使用easypoi导出带图片的Excel,
引入依赖
依赖中着重要剔除可能会造成冲突的依赖,不剔除的话可能会报错
Exception in thread "main" java.lang.NoSuchFieldError: Class
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook does
not have member field 'org.apache.xmlbeans.impl.schema.DocumentFactory Factory'
这个错误本质上是由于以下原因
- XMLBeans 3.0+ 修改了内部工厂机制
- POI 5.0+ 使用了新的类型系统
- EasyPOI 可能携带了旧版本依赖
所以要保证项目依赖项里不要有冲突的依赖
以下是所使用到的所有依赖
xml
<properties>
<java.version>24</java.version>
<poi.version>5.2.3</poi.version>
<easypoi.version>4.4.0</easypoi.version>
<xmlbeans.version>5.1.1</xmlbeans.version>
</properties>
<dependencies>
<!-- EasyPOI -->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>${easypoi.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Apache POI -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- XMLBeans -->
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>${xmlbeans.version}</version>
</dependency>
<!-- 其他必要依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.23.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
实体类
实体类中着重注意的是图片字段一定要带有type=2配置属性
java
package com.xmliu.easypoidemo;
import cn.afterturn.easypoi.excel.annotation.Excel;
public class Employee {
@Excel(name = "姓名", orderNum = "0", width = 15)
private String name;
@Excel(name = "部门", orderNum = "1", width = 20)
private String department;
// 关键图片配置, savePath = "src/main/resources/images/"
@Excel(name = "照片", orderNum = "2", type = 2, width = 20, height = 20)
private String photoPath;
// 必须有无参构造
public Employee() {}
public Employee(String name, String department, String photoPath) {
this.name = name;
this.department = department;
this.photoPath = photoPath;
}
// getter和setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getPhotoPath() {
return photoPath;
}
public void setPhotoPath(String photoPath) {
this.photoPath = photoPath;
}
}
导出Excel
该导出方法提供了两种图片加载方式,一个是本地磁盘图片,一个是项目内部图片,当然也可以是在线图片url
java
package com.xmliu.easypoidemo;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import org.apache.poi.ss.usermodel.Workbook;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class EasyPoiDemo {
public static void main(String[] args) {
// 模拟数据
List<Employee> employees = new ArrayList<>();
// employees.add(new Employee("张三", "技术部", "src/main/resources/images/huoche.jpg"));
// employees.add(new Employee("李四", "市场部", "src/main/resources/images/echarts.png"));
// employees.add(new Employee("王五", "人事部", "src/main/resources/images/wangwu.jpeg"));
employees.add(new Employee("张三", "技术部", "/Users/zhangwei/Downloads/huoche.jpg"));
employees.add(new Employee("李四", "市场部", "/Users/zhangwei/Downloads/echarts.png"));
employees.add(new Employee("王五", "人事部", "/Users/zhangwei/Downloads/wangwu.jpeg"));
// 导出Excel
exportWithImages(employees, "员工信息表" + System.currentTimeMillis()+".xlsx");
}
public static void exportWithImages(List<Employee> data, String fileName) {
// 1. 配置导出参数
ExportParams params = new ExportParams("员工信息表", "员工数据", ExcelType.XSSF);
// 2. 生成工作簿
Workbook workbook = ExcelExportUtil.exportExcel(params, Employee.class, data);
// 3. 写入文件
try (FileOutputStream out = new FileOutputStream(fileName)) {
workbook.write(out);
System.out.println("Excel导出成功,文件保存在: " + new File(fileName).getAbsolutePath());
} catch (IOException e) {
System.err.println("Excel导出失败: " + e.getMessage());
e.printStackTrace();
}
}
}
导出结果

从上图中可以看出导出的Excel并没有图片,这个问题确实很奇怪
但是我们通过压缩软件打开该Excel发现
三张图片确实已经存在,只是没显示到Excel单元格中,该问题还需进一步研究原因与解决方法,如若哪位朋友知道,还望不吝赐教,在下不胜感激。
以下是控制台日志
xml
已连接到地址为 ''127.0.0.1:55220',传输: '套接字'' 的目标虚拟机
Excel导出成功,文件保存在: /Users/zhangwei/IdeaProjects/easypoi-demo/员工信息表1745986971020.xlsx
已与地址为 ''127.0.0.1:55220',传输: '套接字'' 的目标虚拟机断开连接
进程已结束,退出代码为 0