在項目開發過程中,經常遇到需要將數據導出到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(); } } }
結果

