在平时的开发中,经常需要处理Excel的导入导出功能。一般使用poi或EasyExcel进行开发,使用poi处理Excel相对较为复杂,而大部分开发者会选择EasyExcel,因为仅需一行代码就能实现导入和导出的功能。然而,EasyExcel不支持图片的读取操作,因此本文将介绍如何实现图片的读取和写入功能。
EasyExcel官网的常见问题中指出,EasyExcel目前不支持读取图片的功能。
读取图片
poi支持图片的读取。我们可以使用poi编写一个工具类,以支持图片的读取。首先需要添加maven依赖,EasyExcel已经包含poi依赖,因此无需额外添加poi依赖:
<!-- easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>net.sf.jxls</groupId>
<artifactId>jxls-core</artifactId>
<version>1.0.6</version>
</dependency>
图片的读取核心代码如下:
Workbook workbook = WorkbookFactory.create(inputStream);
// 默认读取第一页
XSSFSheet sheet = (XSSFSheet) workbook.getSheetAt(0);
List<POIXMLDocumentPart> documentPartList = sheet.getRelations();
for (POIXMLDocumentPart part : documentPartList) {
if (part instanceof XSSFDrawing) {
XSSFDrawing drawing = (XSSFDrawing) part;
List<XSSFShape> shapes = drawing.getShapes();
for (XSSFShape shape : shapes) {
XSSFPicture picture = (XSSFPicture) shape;
XSSFClientAnchor anchor = picture.getPreferredSize();
CTMarker marker = anchor.getFrom();
int row = marker.getRow();
int col = marker.getCol();
// 从第2行开始
if (row > 0 && row <= size) {
PictureData pictureData = picture.getPictureData();
String extension = pictureData.suggestFileExtension();
byte[] bytes = pictureData.getData();
}
}
}
}
图片读取流程:
- 首先要获取第一页(sheet)数据 workbook.getSheetAt(0)
- 遍历 sheet.getRelations() 提取XSSFDrawing,即图片数据。
- 遍历每行数据,获取字节流。
在将代码复制到IDE中时,可能会提示某些方法不存在,这时需要核对poi的版本。上述引用的EasyExcel版本为3.0.5,其中包含的poi版本是4.1.2。
封装工具类
通过上述代码,我们可以获取到图片的字节流,然后对字节流进行上传或存储处理。但是,每次读取都需要重复编写代码,这样会使代码显得冗余。因此,我们需要将上述代码封装成一个工具类。
例如,如果要上传一个文件,需要将数据赋值给两个字段name和imageStr:
@ExcelProperty("姓名")
private String name;
@ExcelProperty(value = "图片")
private String imageStr;
首先配置一个ExcelImageProperty注解,确定哪一列的图片需要赋值给对应的图片字段:
@Inherited
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelImageProperty {
String[] value() default {""};
/**
* 图片在第几列 1开始
* @return
*/
int index() default -1;
}
imageStr对应第二列,字段上ExcelImageProperty注解的
index = 2
,上述实体修改如下:
@ExcelProperty("姓名")
private String name;
@ExcelProperty(value = "图片")
@ExcelImageProperty(index = 2)
private String imageStr;
在编写好实体和注解后,再编写一个工具类。
@Slf4j
public class ExcelReadImageUtil {
...
}
传入一个列表,通过获取读取输入流获取到图片,并赋值给对应的字段。
- 此模板是一个列表模板,不支持自定义模板。
- 使用poi读取图片,第二行读取数据,遍历每列数据,符合注解字段就赋值。一般获取到输入流后会上传图片,返回一个地址,这里仅仅获取字节流,赋值给对应的字段。
使用EasyExcel读取非图片数据和工具类读取图片数据:
InputStream inputStream = multipartFile.getInputStream();
List<DemoExcelInput> demoExcelInputs = EasyExcelFactory.read(multipartFile.getInputStream()).head(DemoExcelInput.class).sheet().doReadSync();
ExcelReadImageUtil.readImage(inputStream,demoExcelInputs);
注意:
inputStream不能重复使用,否则会报错
inputStream close
错误。
写图片
EasyExcel支持多种格式的写图片,包括:
- URL
- InputStream
- byte[]
- File
- 自定义转换器
添加写的实体:
@Data
public class DemoExcelInput {
...
}
读取图片:
...
导出文件截图:
但是上述imageStr对应的String类型EasyExcel并不支持,但却能导出图片,这就需要使用到自定义转换器。
创建ExcelUrlImageConverter转换器:
...
将读取到的图片流转换为WriteCellData对象,从而实现图片的写入。
未经允许不得转载:大白鲨游戏网 » EasyExcel导入导出功能中的图片读取和写入