POI获取Excel sheet页中最外一个非空单元格的地址

最近遇到一个需求要求将excel的内容作为图片导出,经过一系列研究之后决定使用apache poi和 Graphics2D 进行导出图片。实现方案是:扫描每一行的单元格的内容然后画出对应的矩形并照着单元格的样式画图。但是由于并不是每个单元格都需要,所以要获取最小非空单元格和最大非空单元格中间的范围地址,具体如下:

导出单元格如下:

 内容是使用单元格的边框画出线条,和方框组成一个树形图。其他单元格内容为空背景是白色如果使用 “Sheet.getLastRowNum()”,和“row.getLastCellNum()” 方法 返回的最大是J列和16行,很显然超出了目标单元格的范围这种方法不适用。

循环遍历单元格找出需用的部分代码如下:(注:遇到合并单元格需要特殊处理)

    /**
     * 获取最大非空单元格的范围
     *
     * @param sheet 目标sheet页面
     * @return 范围地址
     */
    public static CellRangeAddress getMaxNotBlankRangeAddress(XSSFSheet sheet) {
        DataFormatter dataFormatter = new DataFormatter();
        int maxRow = -1;
        int maxCol = -1;
        int minRow = -1;
        int minCol = -1;
        //获取合并所有单元格
        List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();

        for (int i = 0; i < sheet.getLastRowNum(); i++) {
            XSSFRow row = sheet.getRow(i);
            for (int j = 0; j < row.getLastCellNum(); j++) {
                XSSFCell cell = row.getCell(j);
                String x = dataFormatter.formatCellValue(cell);
                if (Strings.isNotBlank(x)){
                    CellRangeAddress address = getMergedCellRangeAddress(mergedRegions, i, j);
                    // 判断是否是合并单元格
                    if (address == null){
                        if (minCol==-1 || minRow == -1){
                            minCol = j;
                            minRow = i;
                        }else {
                            minCol = Math.min(minCol,j);
                            minRow = Math.min(minRow,i);
                        }
                        maxCol = Math.max(maxCol,j);
                        maxRow = Math.max(maxRow,i);
                    }else {
                        if (minCol==-1 || minRow == -1){
                            minCol = address.getFirstColumn();
                            minRow = address.getFirstRow();
                        }else {
                            minCol = Math.min(minCol,address.getFirstColumn());
                            minRow = Math.min(minRow,address.getFirstRow());
                        }
                        maxCol = Math.max(maxCol,address.getLastColumn());
                        maxRow = Math.max(maxRow,address.getLastRow());
                    }
                }
            }
        }

        return new CellRangeAddress(minRow, maxRow, minCol, maxCol);
    }
    // 获取合并单元格地址
    static private CellRangeAddress getMergedCellRangeAddress(List<CellRangeAddress> mergedRegions,int x,int y){
        for (CellRangeAddress cellAddresses : mergedRegions) {
            if (cellAddresses.isInRange(x, y)) {
                return cellAddresses;
            }
        }
        return null;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值