(解决)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 -------------- ------------- ...
随机推荐
- MySQL日期和时间函数汇总
本文基于MySQL8.0 本文介绍MySQL关于日期和时间操作的函数. 日期和时间函数 函数 描述 ADDDATE() 给日期值添加时间值 ADDTIME() 添加time CONVERT_TZ() ...
- MySQL技术内幕InnoDB存储引擎(五)——索引及其相关算法
索引概述 索引太多可能会降低运行性能,太少就会影响查询性能. 最开始就要在需要的地方添加索引. 常见的索引: B+树索引 全文索引 哈希索引 B+树索引 B+树 所有的叶子节点存放完整的数据,非叶子节 ...
- sqli-labs less11-12(post型union注入)
less-11 post型union注入 过程: 输入admin admin 判断username password的闭合方式 对username查字段个数 ' union select 1,2# ' ...
- Day1 input&print
1.print函数 格式: 打印字符串:print('xxx','yyy') 可以接受多个字符串,多个字符串之间使用逗号分隔. 间隔字符串的逗号会被打印成空格输出. 打印整数或计算结果:print(' ...
- Excel-HLOOKUP函数匹配查找②
问题场景 绩效奖金评定发放,针对表中的考核员工,先按考核总分评级,再根据根据分级评定绩效奖金. 场景一 在考核员工表中,根据员工的考核总分将其分为四个等级(可根据业务场景和实际情况分析):A级分数区间 ...
- Unity 游戏的暂停,继续,重开,退出
1.暂停游戏. Time.timeScale = 0; 2.继续游戏. Time.timeScale = 1; Time.timeScale = 0可以暂停游戏,Time.timeSc ...
- 洛谷题解 P1051 【谁拿了最多奖学金】
其实很水 链接: P1051 [谁拿了最多奖学金] 注意: 看好信息,不要看漏或看错因为信息很密集 AC代码: 1 #include<bits/stdc++.h>//头文件 2 using ...
- Linux简单复习
cd 命令:切换目录 ls命令:用于浏览目录下的文件或者文件夹 rm 命令:用于删除文件或者目录,用法 rm –rf test.txt (-r表示递归,-f表示强制) cp 命令:用于拷贝文件,用法, ...
- Python制作折线图
利用python的第三方包Pygal制作简单的折线图. 申明:本文仅供学习交流使用.源码大部分来自<python编程从入门到实践>:如有侵权,请联系我删除. 1 #!usr/bin/env ...
- Redis基础篇(二)高性能IO模型
我们经常听到说Redis是单线程的,也会有疑问:为什么单线程的Redis能那么快? 这里要明白一点:Redis是单线程,主要是指Redis的网络IO和键值对读写是由一个线程来完成的,这也是Redis对 ...