在项目开发过程中,经常遇到需要将数据导出到Excel文件中的需求,如果是简单的数据展示,例如:只需一行表头,然后在下面循环输出数据这样的需求,还是比较容易实现的。
但是,在很多情况下,表格的头部并不是简单的一行表头就可以的,这时候就需要通过自己手动编码的方法去实现布局。虽然可以通过一定的封装降低复杂度,依然无法避免在业务代码中出现大量样板式代码。
对于这种情况,我们可以手动创建对应excel文件并完成表头布局,然后放在项目的目录下,在导出时,先读取文件内容到内存中,然后写入数据并输出到响应流。
以下面的这个excel为例(图片源自知乎,侵删):
我们在本地先创建这个excel
将excel文件存到项目的目录下,我这里存到static目录下
接着,我们就可以以此为基础,进行数据填充并导出了。
测试环境:
SpringBoot版本:2.2.2.RELEASE
POI相关maven依赖:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>xstream</groupId> <artifactId>xstream</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency>
Controller:
package com.kket.demo.controller; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; /** * 导出Controller * @create 2019-12-14 22:41 **/ @RequestMapping("export") @Controller public class ExportController { @GetMapping("exportExcel") public void exportExcel(HttpServletRequest request, HttpServletResponse response){ try { //加载文件资源 InputStream templateInputStream = getClass().getResourceAsStream("/static/test.xlsx"); //通过输入流创建XSSFWorkbook对象 XSSFWorkbook templateWorkBook = new XSSFWorkbook(templateInputStream); //获取第一个sheet XSSFSheet sheet = templateWorkBook.getSheetAt(0); //填充数据,这里填充一些简单的数据 //从第四行开始填充 int startLine = 4; //填充5行 int dataLength = 5; XSSFRow dataRow = null; for (int i = startLine; i < startLine + dataLength; i++) { dataRow = sheet.createRow(i); for (int l = 0; l < 7; l++) { dataRow.createCell(l).setCellValue(l); } } String fileName = "target"; response.setContentType("application/vnd.ms-excel"); //根据浏览器类型处理文件名称 String agent = request.getHeader("USER-AGENT").toLowerCase(); //若是火狐 if (agent.indexOf("firefox") > -1){ fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1"); } else { //其他浏览器 fileName = java.net.URLEncoder.encode(fileName, "UTF-8"); } response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx"); templateWorkBook.write(response.getOutputStream()); response.getOutputStream().flush(); } catch (Exception e) { e.printStackTrace(); } } }
结果