You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Apache POI 3.7读取分组行Excel生成WBS编码遇缩进检测问题

问题原因

你当前的代码错误地将Excel行分组(大纲级别)和单元格文本缩进混为一谈。截图中的Excel是用**行分组功能(大纲视图)**实现的层级折叠,而非设置单元格样式的文本缩进。CellStyle.getIndention()仅能获取单元格内文本的缩进量(比如在单元格格式中设置的缩进),完全无法读取行分组的层级信息,所以始终返回0。

解决方案

要获取行分组的层级,需使用Apache POI中Row对象的getOutlineLevel()方法,该方法直接返回当前行的大纲级别(行分组的层级,从0开始,0表示无分组)。

同时需要调整WBS编码的生成逻辑:用一个列表维护每个层级的当前序号,根据行的级别变化动态更新序号列表,最终拼接出1.1.1格式的编码。

修改后的完整代码
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ExcelReaderforHierarchy {

    public static boolean importExcel() throws Exception {
        boolean ret = false;
        try {
            String a_fileName = "E:\\groupedRow.xls";
            FileInputStream w_In = new FileInputStream(a_fileName);
            HSSFWorkbook workbook = new HSSFWorkbook(w_In);
            Sheet sheet = workbook.getSheetAt(0);

            generateWBSCodes(sheet);

            ret = true;
            workbook.close();
            w_In.close();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return ret;
    }

    private static void generateWBSCodes(Sheet sheet) {
        // 存储各级别当前的序号,索引对应级别-1(如index=0对应级别1的序号)
        List<Integer> levelCounters = new ArrayList<>();
        int previousLevel = 0;

        for (Row row : sheet) {
            int currentLevel = row.getOutlineLevel();
            // 根据当前级别与上一行级别的关系更新计数器列表
            if (currentLevel > previousLevel) {
                // 进入更深层级,为新增的每个层级初始化序号为1
                for (int i = previousLevel; i < currentLevel; i++) {
                    levelCounters.add(1);
                }
            } else if (currentLevel < previousLevel) {
                // 返回上层级,移除不需要的层级计数器
                for (int i = previousLevel; i > currentLevel; i--) {
                    levelCounters.remove(levelCounters.size() - 1);
                }
                // 回到同级后,当前层级序号加1
                if (currentLevel > 0) {
                    int counterIndex = currentLevel - 1;
                    levelCounters.set(counterIndex, levelCounters.get(counterIndex) + 1);
                }
            } else if (currentLevel == previousLevel && currentLevel > 0) {
                // 同层级的下一行,序号加1
                int counterIndex = currentLevel - 1;
                levelCounters.set(counterIndex, levelCounters.get(counterIndex) + 1);
            }

            // 生成并打印WBS编码
            StringBuilder wbsCode = new StringBuilder();
            for (int i = 0; i < currentLevel; i++) {
                if (i > 0) {
                    wbsCode.append(".");
                }
                wbsCode.append(levelCounters.get(i));
            }
            String wbsOutput = currentLevel > 0 ? wbsCode.toString() : "(无层级)";
            System.out.println("Row: " + row.getRowNum() + ", WBS Code: " + wbsOutput);

            previousLevel = currentLevel;
        }
    }

    public static void main(String[] args) throws Exception {
        importExcel();
    }
}
关键说明
  1. row.getOutlineLevel():直接获取行的分组层级,0表示无分组,1表示一级分组,2表示二级分组,以此类推。
  2. 层级计数器列表:动态维护每个层级的当前序号,解决嵌套分组的序号递增问题,比如从二级回到一级时,一级序号会自动加1。
  3. 资源关闭:补充了workbook.close()和w_In.close(),避免资源泄漏。

内容的提问来源于stack exchange,提问作者ømi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:25:03