1、引入包文件
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
</dependency>
當然,如果有引入導入或導出組件,也是可以的。這個不限於Hzero,凡是SpringBoot都是可行的。
2、存放模板
這裏要注意一下,我們存放模板可以放在項目的根目錄外面,這樣可以避免很多訪問文件的問題,但是不方便部署,還可以放在項目的resoures
目錄下
我在這個目錄下創建一個目錄temp
,然後將模板存放在這個目錄下。
3、創建Controller
我這裏使用Post請求,原來使用get請求,前臺無法轉換格式文件,總是文件受損,換成post就正常了。
@ApiOperation(value = "自定義導出")
@Permission(level = ResourceLevel.ORGANIZATION)
@PostMapping("/excel/export")
public ResponseEntity excelExport(@ApiParam(value = "租戶ID", required = true) @PathVariable Long organizationId,
HttpServletResponse response,
@RequestBody SoShipmentDetectionHead soShipmentDetectionHead) {
soShipmentDetectionHead.setTenantId(organizationId);
try {
soShipmentDetectionHeadService.excelExport(response, soShipmentDetectionHead);
} catch (IOException e) {
log.error("導出失敗", e);
throw new CommonException("導出失敗,請聯繫管理員");
}
return Results.success();
}
4、創建Service
這裏不介紹業務邏輯,只說明技術問題
private void writeExcel(String path, HttpServletResponse response, String ctnNo) throws IOException {
Resource resource = new ClassPathResource(path);
if (resource.isReadable()) {
OutputStream responseOutput = null;
XSSFWorkbook workBook = null;
try (InputStream inputStream = resource.getInputStream()) {
workBook = new XSSFWorkbook(inputStream);
Sheet sheetAt = workBook.getSheetAt(0);
/** 業務邏輯 start **/
SoShipmentDetectionLine line = new SoShipmentDetectionLine();
line.setCartonNo(ctnNo);
List<SoShipmentDetectionLine> lineList = soShipmentDetectionLineRepository.select(line);
SoShipmentDetectionHead head = new SoShipmentDetectionHead();
head.setModType("類型");
head.setCustomer("客戶名稱");
head.setDate(new Date());
head.setCtnNo(ctnNo);
createHead(lineList, ctnNo, head);
writeSheet(sheetAt, head, lineList);
/** 業務邏輯 end **/
// 設置瀏覽器解析文件的mime類型,如果js中已設置,這裏可以不設置
response.setContentType("application/vnd.ms-excel;charset=gbk");
// 設置此項,在IE瀏覽器中下載Excel文件時可彈窗展示文件下載
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(ctnNo + ".xlsx", "UTF-8"));
// 允許瀏覽器訪問header中的FileName
response.setHeader("Access-Control-Expose-Headers", "FileName");
// 設置FileName,轉碼防止中文亂碼
response.setHeader("FileName", URLEncoder.encode(ctnNo + ".xlsx", "UTF-8"));
response.flushBuffer();
workBook.write(response.getOutputStream());
} catch (Exception e) {
log.error("error", e);
} finally {
if (null != responseOutput) {
responseOutput.close();
}
if (null != workBook) {
workBook.close();
}
}
} else {
throw new CommonException("文件不存在!");
}
}
這裏要知道項目發佈時是jar
包形式,一般的讀取文件是無法讀取jar包裏的文件的,這時候要用ClassPathResource
讀取文件,文件路徑"temp" + File.separator + "testReport.xlsx"
,這樣就能讀取resoures
目錄下的文件了,還有一點要記住,我們讀取的文件是.xlsx
,所以要用XSSFWorkbook
創建文件對象,如果是.xls
要用HSSFWorkbook
創建對象。這非常重要,否則文件會損壞。