(解决)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中的方法
- 找到要重写的方法所在的包,如上述方法所在的包为
package cn.afterturn.easypoi.excel.export.base;
- 在src目录下,创建新建一个同包名同类名的类
- 将源代码完整的复制到新创建的类
- 在新创建的类中,修改对应的要重写的方法中的代码(注意不要删除原有的方法以及参数,但是可以新增一些方法)
原理
编译输出的时候会优先使用我们src下面的类,而不是优先使用Jar包里面的类,这样就达到了覆盖jar包方法的目的。
(解决)easypoi图片导出只占用一个单元格的更多相关文章
- Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作
Visual Studio 2017中使用正则修改部分内容 最近在项目中想实现一个小工具,需要根据类的属性<summary>的内容加上相应的[Description]特性,需要实现的效 ...
- java POI excel 导出复合样式(一个单元格两个字体)
前言:java poi 导出 excel 时,需要设置一个单元格有多个字体样式,有点类似于富文本. 想要达到的效果(一个单元格里): 我使用的 poi 版本是 <dependency> & ...
- 前端Excel表格导入导出,包括合并单元格,表格自定义样式等
表格数据导入 读取导入Excel表格数据这里采用的是 xlsx 插件 npm i xlsx 读取excel需要通过 XLSX.read(data, {type: type}) 方法来实现,返回一个叫W ...
- excel表格中打开可以显示整个表格但是打印却只能打印一个单元格
excel表格中打开可以显示整个表格但是打印却只能打印一个单元格 如下图显示 解决办法 2007 版菜单栏上 ----->页面布局----->打印区域----->取消打印.即可正常. ...
- Developer Express控件gridcontrol中gridView的某一个单元格是否可以自由输入
场景:在Developer Express控件gridcontrol中的gridView中,当医生开的临时医嘱的医嘱类型为"中草药","计价总量"单元格不可以自 ...
- 如何用Apache POI操作Excel文件-----如何对一个单元格加注解?
有的时候,我们需要通过操作Apache POI,在生成Cell数据的同时,能对其生成的Cell,加上注解(comments),类似于下面的. 那么对于这种情况,我们的代码应该如何写呢? 借花献佛,我就 ...
- Java 获取表格中某一个单元格的值
需求 搜索页面返回表格样搜索结果, 获取搜索结果中某个单元格的具体值. 以下图为例, 下表是搜索返回的结果, 第一行是各个列的名字, 其它是具体的返回值. 方法1: 根据用户输入的表头名来确定是第几列 ...
- cxgrid回车移到下一个单元格
cxgrid回车移到下一个单元格 cxgrid回车移到下一个单元格 作用:表格式录入全键盘操作. 设置cxgrid1Dbtableview1.optionsBehavior.goToNextCel ...
- mysql GROUP_CONCAT 函数 将相同的键的多个单元格合并到一个单元格
mysql GROUP_CONCAT 函数 将相同的键的多个单元格合并到一个单元格 MemberID MemberName FruitName -------------- ------------- ...
随机推荐
- mybatis批量修改数据
xxxMapper.xml: <update id="updateSensorWarnings" parameterType="java.util.List&quo ...
- 半夜删你代码队 Day5冲刺
一.每日站立式会议 1.站立式会议 成员 昨日完成工作 今日计划工作 遇到的困难 陈惠霖 跟进作业 完成注册界面 相关界面设计内容知识不充足 侯晓龙 开始双人合作 开始与数据库结合 无 周楚池 初步完 ...
- this.$options.data()实战之重置data
刚刚看到这个方法学习了一下,然后想到正在开发的项目有一个需要重置data的操作,正好拿来使用一下,节省了好多代码,美滋滋...
- MySQL日期和时间函数汇总
本文基于MySQL8.0 本文介绍MySQL关于日期和时间操作的函数. 日期和时间函数 函数 描述 ADDDATE() 给日期值添加时间值 ADDTIME() 添加time CONVERT_TZ() ...
- 笔记-[ZJOI2014]力
[ZJOI2014]力 \[\begin{split} E_j=&\sum_{i=1}^{j-1}\frac{q_i}{(i-j)^2}-\sum_{i=j+1}^{n}\frac{q_i}{ ...
- SpringBoot + SpringSecurity + Mybatis-Plus + JWT实现分布式系统认证和授权
1. 简介 Spring Security是一个功能强大且易于扩展的安全框架,主要用于为Java程序提供用户认证(Authentication)和用户授权(Authorization)功能. ...
- adb devices查看不到Android模拟器的设备
1.先开启模拟器,后执行adb devices命令: List of devices attached 2.找到SDK的安装目录下platform-tools文件夹下adb.exe文件,将其复制到桌面 ...
- 基于nacos注册中心的ribbon定制规则
前面说到基于nacos的注册发现有可以扩展实现我们自己的负载均衡算法(Nacos数据模型),来实现同集群调用,是基于spring.cloud.nacos.discovery.cluster-name参 ...
- 开发阶段,将SpringBoot应用快速部署到K8S
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- C++线程详细说明
一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX ...