Hzero實現xlsx模板文件導出功能

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 創建對象。這非常重要,否則文件會損壞。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章