StringBoot使用Easy Excel实现Excel导出(一)主要讲了一下引用,以及基础使用。
这篇文章主要是实现excel模板导出功能,头部数据为图片,下面数据也有图片。一个有自定义头部,实体类导出图片的导出。
模板如下
导出效果如下:
具体代码讲解
实体类
查询数据库数据组成一个实体类,进行excel的导出。
- 重点要注意的是图片要转成byte型
public class info
{
private String entrypeople;
......
private WriteCellData<Void> entrypeopleimgbte;
private WriteCellData<Void> receptionistimgbte;
/**重点是输出图片需要byte类型**/
private byte[] auditpeoplebte;
private byte[] dutyleaderbte;
测试类
定义导入的模板文件路径和生成excel的文件路径,定义ExcelWriter对象,讲需要导出的数据fill进去。
@Test
public void complexFill1() {
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量
String templateFileName = ronweConfig.getProfile() + "/模板.xlsx";
DateUtil dateUtil = new DateUtil();
String fileName = ronweConfig.getProfile() + "/导出文件"+ ".xlsx";
try {
ExcelWriter excelWriter = EasyExcel.write(fileName)
.withTemplate(templateFileName)
.build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。
// forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用
// 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
// 如果数据量大 list不是最后一行 参照下一个
//获取导出数据,进行数据赋值
List<InspEntryexitinfo> datalist=dataHandling();
excelWriter.fill(datalist, writeSheet);
InspEntryexitinfo info=datalist.get(0);
JSONObject jsonObject = new JSONObject();
WriteCellData<Void> auditpeopleWriteCell = TemplateExcelUtils.imageCells(info.getAuditpeoplebte());
jsonObject.put("auditpeople", auditpeopleWriteCell);
WriteCellData<Void> voidWriteCellData = TemplateExcelUtils.imageCells(info.getDutyleaderbte());
jsonObject.put("dutyleader", voidWriteCellData);
excelWriter.fill(jsonObject, writeSheet);
excelWriter.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
获取数据,数据组建准备
这个方法主要是对请求到实体类的图片进行类型转换,转成我们需要的能用的类型。
private List<InspEntryexitinfo> dataHandling() throws IOException {
InspEntryexitinfo inspEntryexitinfo=new InspEntryexitinfo();
//数据库获取数据
List<InspEntryexitinfo> list = inspEntryexitinfoService.selectInspEntryexitinfoList(inspEntryexitinfo);
List<InspEntryexitinfo> infolist = ListUtils.newArrayList();
JSONObject jsonObject = new JSONObject();
for (InspEntryexitinfo info:list) {
//数据处理,在列表中循环的调用TemplateExcelUtils.imageCells方法,进行图片格式处理
String entrypeopleimg=ronweConfig.getProfile() + info.getEntrypeopleimg().substring(8);
WriteCellData<Void> entrypeopleimgWriteCell = TemplateExcelUtils.imageCells(imgHanding(entrypeopleimg));
info.setEntrypeopleimgbte(entrypeopleimgWriteCell);
String receptionistimg=ronweConfig.getProfile() + info.getReceptionistimg().substring(8);
info.setReceptionistimgbte(TemplateExcelUtils.imageCells(imgHanding(receptionistimg)));
String auditpeople=ronweConfig.getProfile() + info.getAuditpeople().substring(8);
info.setAuditpeoplebte(imgHanding(auditpeople));
String dutyleader=ronweConfig.getProfile() + info.getDutyleader().substring(8);
info.setDutyleaderbte(imgHanding(dutyleader));
infolist.add(info);
}
return infolist;
}
图片处理方法
这个方法主要是进行图片样式的一些处理,这里我主要用到的是设置图片在excel表格里的位置,保证在表格里不会完全填充,有所留白。全部填充后,excel的表格边框就看不到了。像如下样式
/**
* Excel所有图片设置
*
* @param bytes
* @return
* @throws IOException
*/
public static WriteCellData<Void> imageCells(byte[] bytes) throws IOException {
WriteCellData<Void> writeCellData = new WriteCellData<>();
// 这里可以设置为 EMPTY 则代表不需要其他数据了
//writeCellData.setType(CellDataTypeEnum.EMPTY);
// 可以放入多个图片
List<ImageData> imageDataList = new ArrayList<>();
writeCellData.setImageDataList(imageDataList);
ImageData imageData = new ImageData();
imageDataList.add(imageData);
// 设置图片
imageData.setImage(bytes);
// 图片类型
//imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG);
// 上 右 下 左 需要留空,这个类似于 css 的 margin;这里实测 不能设置太大 超过单元格原始大小后 打开会提示修复。暂时未找到很好的解法。
imageData.setTop(5);
imageData.setRight(5);
imageData.setBottom(5);
imageData.setLeft(5);
// * 设置图片的位置。Relative表示相对于当前的单元格index。first是左上点,last是对角线的右下点,这样确定一个图片的位置和大小。
// 目前填充模板的图片变量是images,index:row=7,column=0。所有图片都基于此位置来设置相对位置
// 第1张图片相对位置
imageData.setRelativeFirstRowIndex(0);
imageData.setRelativeFirstColumnIndex(0);
imageData.setRelativeLastRowIndex(0);
imageData.setRelativeLastColumnIndex(0);
return writeCellData;
}
文件路径转成byte
这是讲图片的strimg类型的路径转成byte类型。
private byte[] imgHanding(String imageUrlStr) throws IOException {
// 可以填充图片
ByteArrayOutputStream byteArrayOut = null;
imageUrlStr="file:///"+imageUrlStr;
try {
// String imageUrlStr = "file:///D:\\uploadPath\\report\\converter\\img.png";
URL url = new URL(imageUrlStr);
// HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
// if (httpURLConnection.getResponseCode() == 200) {
BufferedImage bufferImg = ImageIO.read(url.openStream());
byteArrayOut = new ByteArrayOutputStream();
// 图片后缀格式
String sfx = imageUrlStr.substring(imageUrlStr.lastIndexOf(".") + 1);
ImageIO.write(bufferImg, sfx, byteArrayOut);
bufferImg.flush();
// }
} catch (IOException e) {
e.printStackTrace();
} finally {
if (byteArrayOut != null) {
byteArrayOut.close();
}
}
return byteArrayOut.toByteArray();
}
结束语
好了,一个带有图片的实体类的导出写好了。