前言
多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♪(・ω・)ノ

