前言 多sheet导出也是我们日常工作经常会碰到的一个需求场景,它既可以是复杂内容的sheet排列展示,也可以是几个小部分的内容并列展示。 细心的朋友似乎已经通过上一篇博文发现了
多sheet导出也是我们日常工作经常会碰到的一个需求场景,它既可以是复杂内容的sheet排列展示,也可以是几个小部分的内容并列展示。
细心的朋友似乎已经通过上一篇博文发现了EasyExcel写数据的套路:打开sheet -> 执行写入。不要惊讶,确实就这两步!
- 打开sheet
先来看看我们昨天是怎么打开一个可写入的sheet,也就是返回一个com.alibaba.excel.write.builder.ExcelWriterSheetBuilder对象
很明显可以看到,API里面支持对sheetNo进行设置,所以我们可以利用起来。
2、执行写入
写入的时候我们可以看到有write方法和fill方法
- write方法适合表格式逐行的写入
- fill方法适合对于模板样式的数据填充
下面我们也要用同样的套路来实现我们今天的主题---多sheet导出
多sheet导出-表格式逐行写入(难度星级:☆☆☆☆)需求:我们需要导出一个excel,除了学生基本信息,新增一个sheet为班级信息,具体如下
首先我们需要先定义数据对象,用来传递数据列表信息
@Data
public class Grate implements Serializable {
@ExcelProperty("班级")
private String grate;
@ExcelProperty("班主任老师")
private String teacher;
@ExcelProperty("任课老师")
private String instructor;
@ExcelProperty("学科")
private String subject;
}
假定数据已经定义好了,学生信息studentList、班级信息grateList,导出代码:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream).build();
WriteSheet studentSheet =
EasyExcel.writerSheet(0, "学生信息").head(Student.class).build();
WriteSheet grateSheet =
EasyExcel.writerSheet(1, "班级信息").head(Grate.class).build();
excelWriter.write(studentList, studentSheet)
.write(grateList.get(), grateSheet);
excelWriter.finish();
ps:页面导出直接下载代码
private void downloadExcel(HttpServletResponse response, InputStream inputStream, String fileName)
throws IOException {
if (StringUtils.isBlank(fileName)) {
fileName = this.getFileDefaultName();
}
if (!StringUtils.endsWith(fileName, XLSX)) {
fileName += XLSX;
}
response.setCharacterEncoding("utf-8");
response.setContentType("application/vnd.ms-excel");
int buffer = 1024 * 10;
byte[] data = new byte[buffer];
int read;
while ((read = inputStream.read(data)) != -1) {
response.getOutputStream().write(data, 0, read);
}
String fileNameEncode = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileNameEncode);
response.getOutputStream().flush();
response.getOutputStream().close();
}
- HttpServletResponse:前端请求响应流,懂的人都懂
- ByteArrayInputStream:new ByteArrayInputStream(outputStream.toByteArray()),定义IO输入到页面的数据流
- fileName:文件名
至此,需求解决!相信可以满足产品一段时间了
隔天,我们那要命的产品又来跟我说,我想在"学生信息"页面看到昨天模板那个页面,不然就别下班了,卑微的我默默又开始干起来了
多sheet导出-模板写入(难度星级:☆☆☆☆)有了上一篇博客的经验,我们直接上代码
// 定义写入输出流(方便后续上传,主要用于异步导出)
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
File file = new File("/template/模板.xlsx");
FileInputStream fileInputStream = new FileInputStream(file);
// 以模板的方式打开写入门面类
ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream).withTemplate(new ByteArrayInputStream(copyStream(fileInputStream).toByteArray())).build();
// 自定义数据
StudentInfo.Student student = new StudentInfo.Student("高一","张三","男","17","88");
StudentInfo studentInfo = new StudentInfo("第三中学", "李丽", Lists.list(student));
Grate grate = new Grate("高一","李丽","张合","语文");
// 自定义sheet
WriteSheet studentInfoSheet = EasyExcel.writerSheet(0, "学生信息").build();
WriteSheet grateSheet = EasyExcel.writerSheet(1, "班级信息").head(Grate.class).build();
// 填充数据(fill填充模板数据|write填充表格数据)
excelWriter.fill(studentInfo, studentInfoSheet).fill(studentInfo.getStudentList(),studentInfoSheet).write(Lists.newArrayList(grate),grateSheet);
excelWriter.finish();
模板.xlsx
- 学生信息
- 班级信息(空白即可)
- 学生信息
- 班级信息
- 多sheet导出只需要在生成sheet的同时设置号下标即可
2、存在使用模板的话,一定要设置工作区(com.alibaba.excel.write.metadata.WriteWorkbook)的templateInputStream属性,哪怕只有一个sheet使用模板
3、模板填充用ExcelWriter#fill(),表格填充使用ExcelWriter#write。注意模板中同时使用列表和非列表的,需要填充两次
大家可以关注公众号“技术小邱”来进行交流,Thanks♪(・ω・)ノ