zoukankan      html  css  js  c++  java
  • (解决)easypoi图片导出只占用一个单元格

    前提

    本解决方案来源于网络,因解决自己需求,因此自行记录起来,如有侵权请联系我。

    依赖环境

    easypoi——依赖版本3.1.0

    问题原因

    easypoi源代码中创建图片的方法中,没有对图片合并单元格后计算单元格合并,仅仅是计算图片所在的一个单元格位置,因此只填充一个单元格。

    /**
     * 图片类型的Cell
     */
    public void createImageCell(Cell cell, double height,
                                String imagePath, byte[] data) throws Exception {
        if (height > cell.getRow().getHeight()) {
            cell.getRow().setHeight((short) height);
        }
        ClientAnchor anchor;
        if (type.equals(ExcelType.HSSF)) {
            anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1),
                    cell.getRow().getRowNum() + 1);
        } else {
            anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1),
                    cell.getRow().getRowNum() + 1);
        }
        if (StringUtils.isNotEmpty(imagePath)) {
            data = ImageCache.getImage(imagePath);
        }
        if (data != null) {
            PoiExcelGraphDataUtil.getDrawingPatriarch(cell.getSheet()).createPicture(anchor,
                    cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));
        }
    }
    

    解决方案

    对上述代码进行重写

    /**
         * 图片类型的Cell
         */
    public void createImageCell(Cell cell, double height,
                                    String imagePath, byte[] data) throws Exception {
        if (height > cell.getRow().getHeight()) {
            cell.getRow().setHeight((short) height);
        }
        
        //重写部分开始
        //获取当前单元格所在的sheet
        Sheet sheet = cell.getRow().getSheet();
        //获取当前sheet页中的所有合并单元格信息
        List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
        //获取当前单元格的开始列号
        int firstColumn = (short)cell.getColumnIndex();
        //获取当前单元格的开始行号
        int firstRow = cell.getRow().getRowNum();
        //获取当前单元格的结束列号
        int lastColumn = (short)(cell.getColumnIndex());
        //获取当前单元格的结束行号
        int lastRow = cell.getRow().getRowNum();
        for(CellRangeAddress mergedRegion : mergedRegions){
            //判断当前单元格是否包含合并行或和并列 当前单元格的所有行号和列号都包含在合并域内 则认为当前单元格存在合并行或和并列
            if(cell.getColumnIndex()>=mergedRegion.getFirstColumn()
                    && cell.getColumnIndex()<=mergedRegion.getLastColumn()
                    && cell.getRow().getRowNum()>=mergedRegion.getFirstRow()
                    && cell.getRow().getRowNum()<=mergedRegion.getLastRow()){
                //获取合并域的开始行号
                firstRow = mergedRegion.getFirstRow();
                //获取合并域的结束行号
                lastRow = mergedRegion.getLastRow();
                //获取合并域的开始列号
                firstColumn = mergedRegion.getFirstColumn();
                //获取合并域的结束列号
                lastColumn = mergedRegion.getLastColumn();
                break;
            }
        }
        //重写部分结束
    
        ClientAnchor anchor;
    
        if(this.type.equals(ExcelType.HSSF)) {
        	//重写前
        	//anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
        	//重写后
            anchor = new HSSFClientAnchor(0, 0, 0, 0, (short)firstColumn, firstRow, (short)(lastColumn+1), lastRow+1);
        } else {
        	//重写前
        	//anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
        	//重写后
            anchor = new XSSFClientAnchor(0, 0, 0, 0, (short)firstColumn, firstRow, (short)(lastColumn+1), lastRow+1);
        }
    
        if(StringUtils.isNotEmpty(imagePath)) {
            data = ImageCache.getImage(imagePath);
        }
    
        if(data != null) {
            PoiExcelGraphDataUtil.getDrawingPatriarch(cell.getSheet()).createPicture((ClientAnchor)anchor, cell.getSheet().getWorkbook().addPicture(data, this.getImageType(data)));
        }
    }
    

    重写jar中的方法

    1. 找到要重写的方法所在的包,如上述方法所在的包为
        package cn.afterturn.easypoi.excel.export.base;
    
    1. 在src目录下,创建新建一个同包名同类名的类
    2. 将源代码完整的复制到新创建的类
    3. 在新创建的类中,修改对应的要重写的方法中的代码(注意不要删除原有的方法以及参数,但是可以新增一些方法)

    原理

    编译输出的时候会优先使用我们src下面的类,而不是优先使用Jar包里面的类,这样就达到了覆盖jar包方法的目的。

  • 相关阅读:
    pandas DataFrame 数据处理常用操作
    host文件配置 了解
    安装Spring+搭建Spring开发环境
    java 环境配置 maven 环境配置
    Hive SQL 常见问题(转载)
    小结
    SQL 将两个结构相同的表合并到成一个表
    用户画像--初步了解
    hive 提取用户第一次浏览/购买 某商品的 时间
    ES2017 keys,values,entries使用
  • 原文地址:https://www.cnblogs.com/z1rar1/p/14269037.html
Copyright © 2011-2022 走看看