POI操作Excel合并单元格

文章讲述了在使用POI库处理Excel时,如何识别和处理合并单元格的问题,包括获取合并单元格的首行首列坐标来获取实际值,以及`sheet.getMergedRegions()`方法的检索顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近因为工作原因,要分析一个Excel文档的数据,结果发现获取到的数据里有很多时候是空的,经过实际分析发现是合并单元格导致的不能获取到值,于是对于POI处理合并单元格的一些获取方法进行了测试。

获取Excel单元的测试方法如下:

    /**
     * 获取合并单元格
     *
     * @param fileName  文件名称
     * @param sheetName 工作簿名称
     */
    public static void getHeBingDanYuanGe(String fileName, String sheetName) {
        //判断文件名格式是否为excel
        if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) {
            System.out.println("文件类型异常,不为excel文档");
            return;
        }

        File file = new File(fileName);
        //判断文件是否存在
        if (!file.exists()) {
            System.out.println("文件不存在,请检查文件路径");
            return;
        }

        Workbook wb = null;
        InputStream is = null;

        try {
            is = new FileInputStream(file);
            if (fileName.endsWith(".xls")) {
                wb = new HSSFWorkbook(is);
            } else {
                wb = new XSSFWorkbook(is);
            }
            Sheet sheet = wb.getSheet(sheetName);
            int lastRowNum = sheet.getLastRowNum();//最后一行的行坐标
            for (int i = 0; i <= lastRowNum; i++) {
                Row row = sheet.getRow(i);
                int firstCellNum = row.getFirstCellNum();//行开始的列坐标
                int lastCellNum = row.getLastCellNum();//行结束的列坐标+1
            }
            /**
             * 获取合并单元格,根据测试验证发现查找顺序:单行多列合并,单列多行合并,多行多列合并,从上往下,从左往右
             * 合并单元格的值只能通过合并单元格的首行首列组成的坐标获取到,其他的行坐标列坐标都无法获取到具体的取值
             */
            List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
            System.out.println(mergedRegions.size());
            for(CellRangeAddress mergeRegion : mergedRegions){
                int firstRow = mergeRegion.getFirstRow();//获取合并单元格的起始行坐标
                int lastRow = mergeRegion.getLastRow();//获取合并单元的结束行坐标
                int firstColumn = mergeRegion.getFirstColumn();//获取合并单元格的起始列坐标
                int lastColumn = mergeRegion.getLastColumn();//获取合并单元格的结束列坐标
                System.out.println(firstRow + " " + lastRow + " " + firstColumn + " " + lastColumn);
                for(int i=firstRow; i<=lastRow; i++){
                    Row row = sheet.getRow(i);
                    for(int j=firstColumn; j<=lastColumn; j++){
                        Cell cell = row.getCell(j);
                        System.out.println(getCellValueByCell(cell));
                    }
                }
                int numberOfCells = mergeRegion.getNumberOfCells();//获取合并单元格的原单元格个数
                System.out.println("numberOfCells:"+numberOfCells);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("读取文件内容异常");
        } finally {
            try {
                wb.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Excel文档截图如下:

运行结果如下:

7
2 2 2 3
3

numberOfCells:2
2 2 5 7
7


numberOfCells:3
4 4 3 4
5

numberOfCells:2
5 5 3 5
6


numberOfCells:3
3 4 2 2
4

numberOfCells:2
0 2 0 1
1

numberOfCells:6
0 1 2 3
2

numberOfCells:4

 根据测试结果,可以很明显的看出,对于合并单元格的基础单元格,除了位于该合并单元格首行首列的基础单元格能够获取到实际的取值外,其他的基础单元格均无法正常获取到值。如果需要获取值的话,需要先定位到该合并单元格的首行首列坐标,然后根据首行首列坐标获取到单元格的取值。

与此同时,可以看出,调用sheet.getMergedRegions()方法获取工作簿里的合并单元格集合时,是从左往右、从上往下进行检索的。检索过程中,优先检索当行多列合并的单元格,然后是多行单列合并的单元格,最后才是多行多列合并的单元格。这里也是需要在实际过程中注意的点,毕竟不少人的常识认为是根据合并后的单元格从左往右、从上往下检索就行,不会去考虑合并单元格的行数、列数对应的关系。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值