背景
业务中,客户需要导出各种数据统计报表,如果客户要求,我希望导出的报表中能插入这些数据的统计图表该如何操作,如图:

传统POI
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
package com.test.other.demo.report
import org.apache.poi.hssf.usermodel.HSSFWorkbook
import org.apache.poi.ss.usermodel.*
import org.apache.poi.util.IOUtils
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.junit.platform.commons.util.StringUtils
import java.io.*
/**
* POI 往excel插入图片
*/
public class POIExport {
private Workbook workbook
public static void main(String[] args) throws Exception {
Workbook workbook = getWorkBook("/Users/hui.yang/Desktop/excel演示/poi/演示1.xlsx")
Sheet sheet = workbook.getSheet("sheet1")
InputStream inputStream = new FileInputStream("/Users/hui.yang/Desktop/excel演示/poi/演示图表1.png")
byte[] bytes = IOUtils.toByteArray(inputStream)
// 这里根据实际需求选择图片类型
int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG)
CreationHelper helper = workbook.getCreationHelper()
ClientAnchor anchor = helper.createClientAnchor()
Drawing drawing = sheet.createDrawingPatriarch()
anchor.setRow1(10)
anchor.setCol1(0)
// 插入图片
Picture pict = drawing.createPicture(anchor, pictureIdx)
// 调整图片占单元格百分比的大小,1.0就是100%
pict.resize(8, 5)
//临时缓冲区
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream()
//创建临时文件
try {
workbook.write(byteArrayOut)
} catch (IOException e) {
e.printStackTrace()
} finally {
workbook.close()
}
byte[] bookByteAry = byteArrayOut.toByteArray()
File file = new File("/Users/hui.yang/Desktop/excel演示/poi/演示插入结果.xlsx")
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs()
}
if (!file.exists()) {
file.createNewFile()
}
FileOutputStream fos = new FileOutputStream(file)
fos.write(bookByteAry, 0, bookByteAry.length)
fos.flush()
fos.close()
}
/**
* 获取workBoot 兼容xlsx xls
*/
public static Workbook getWorkBook(String filePath) throws Exception {
Workbook workbook = null
if (StringUtils.isBlank(filePath)) {
// throw new RuntimeException("路径错误!")
} else if (filePath.toLowerCase().endsWith("xls")) {
workbook = new HSSFWorkbook(new FileInputStream(filePath))
} else if (filePath.toLowerCase().endsWith("xlsx")) {
workbook = new XSSFWorkbook(new FileInputStream(filePath))
} else {
// throw new RuntimeException("路径错误!")
}
return workbook
}
}

e-iceblue(推荐)
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.xls.free</artifactId>
<version>5.1.0</version>
</dependency>
package com.test.other.demo.report;
import com.spire.xls.*;
public class EiceBlueExport {
public static void main(String[] args) {
Workbook workbook = new Workbook();
workbook.loadFromFile("/Users/hui.yang/Desktop/excel演示/e-iceblue/演示1.xlsx");
Worksheet sheet = workbook.getWorksheets().get(0);
ExcelPicture pic = sheet.getPictures().add(10, 1, "/Users/hui.yang/Desktop/excel演示/e-iceblue/演示图表1.png");
pic.setWidth(600);
pic.setHeight(120);
workbook.saveToFile("/Users/hui.yang/Desktop/excel演示/e-iceblue/演示插入结果.xlsx", ExcelVersion.Version2013);
transFileToPdf("/Users/hui.yang/Desktop/excel演示/e-iceblue/庞源在线-安全-安全周报-20230303130801.xlsx");
}
public static void transFileToPdf(String fillPath) {
Workbook wb = new Workbook();
wb.loadFromFile(fillPath);
wb.getWorksheets().get(0);
ConverterSetting converterSetting = new ConverterSetting();
converterSetting.setSheetFitToPage(true);
wb.setConverterSetting(converterSetting);
wb.saveToFile("/Users/hui.yang/Desktop/excel演示/e-iceblue/庞源在线-安全-安全周报-20230303130801.pdf", FileFormat.PDF);
}
}

方案对比
1 poi对xlxs xls不同版本有不同的语法,需要单独写个方法去获取WorkBook,而e-iceblue直接封装好方法,傻瓜式操作
2 poi需设置图片类型,文件流操作,而e-iceblue直接封装好方法,傻瓜式操作
3 e-iceblue有丰富的文档转换工具,如转为PDF,如以上代码,我这边转换的pdf,看了下再也不用在***网站转pdf了,
骚的一批,当然也封装了其他文档转换,这里不赘述
