簡體   English   中英

使用Spring MVC下載的Xlsx文件已損壞並且內容類型已更改

[英]Downloaded Xlsx file with spring mvc is corrupted and content-type is changed

調用服務並使用apache-poi生成xlsx並返回視圖的控制器方法。

@RequestMapping(value = "/getSummary", method = RequestMethod.GET)
public String getSummary(Model model, HttpServletRequest request,
                                             HttpServletResponse response,
                                             @ModelAttribute("dateFrom") String dateFrom,
                                             @ModelAttribute("dateTo") String dateTo) throws Exception {

    logger.debug("date=" + dateFrom + "TO date=" + dateTo);
    AuthParam authParam = (AuthParam) request.getSession().getAttribute("authParam");
    if (authParam == null) {
        model.addAttribute("success", false);
        model.addAttribute("error_msg", "Auth Failed.");
        return "shipment/getSummary";
    }
    try {
        List<SummaryResponse> summaryBeanResponse = reportClient.getSummary(authParam, dateFrom, dateTo);
        logger.debug("Result List Size : {}", summaryBeanResponse.size());
        if (summaryBeanResponse.size() > 0) {
            byte[] reportBytes = buildSummaryXlsx(summaryBeanResponse, dateTo);
            logger.debug("Xlsx Sheet Generated!!");
            String fileName = "summary_" + StringUtils.join(dateTo.split("-"), "_") + ".xlsx";
            model.addAttribute("success", true);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("content-disposition", "attachment; filename=" + fileName);
            logger.debug("Content-Type : {}", response.getContentType());
            logger.debug("Header : {}", response.getHeader("Content-Disposition"));
            response.getOutputStream().write(reportBytes);
            logger.debug("Set ALL");
        } else {
            model.addAttribute("success", false);
            model.addAttribute("error_msg", "No data found by search.");
        }
    } catch (Exception ex) {
        model.addAttribute("success", false);
        model.addAttribute("error_msg", "Service error.");
        logger.error("ERROR on report xlsx", ex);
    }
    return "shipment/getSummary";
}

private byte[] buildSummaryXlsx(List<SummaryResponse> summaryResponseList, String date) throws Exception {
    try {
        Workbook workbook = new XSSFWorkbook();
        // create excel xls sheet
        XSSFSheet sheet = (XSSFSheet) workbook.createSheet("summary");
        sheet.setDefaultColumnWidth(14);

        // create style for header cells
        XSSFCellStyle headerStyle = (XSSFCellStyle) workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setFontName("Arial");
        headerStyle.setFont(font);
        headerStyle.setAlignment(HorizontalAlignment.CENTER);
        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        int rowCount = 0;
        int cellCount = 0;

        // Manipulating Data Using Apache-POI

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        workbook.write(byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();
    } catch (Exception ex) {
        logger.debug("Exception On Population Xlsx Sheet, {}", ex);
    }
    return null;
}

這是jsp視圖名稱getSummary.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Get Xlsx report</title>
    <script type="text/javascript">
        $(document).ready(function () {
            var isSuccess = ${success};
            if (isSuccess == false) {
                var msg = "${error_msg}";
                alertify.alert(msg, function() {
                    window.location = "<%= request.getContextPath() %>/shipment/view.html";
                });
            }
        });
    </script>
</head>
<body>
${error_msg}
</body>
</html>

我正在設置內容類型,但是響應頭看起來像

**Response Headers**
HTTP/1.1 200 OK
Cache-Control: no-cache
Cache-Control: no-store
Date: Mon, 31 Jul 2017 12:26:12 GMT
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: text/html;charset=UTF-8
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Disposition: attachment; filename=summary_2017_07_31.xlsx
Set-Cookie: JSSESSIONID=1501503972634; path=/
Content-Language: en

印刷日志:

    2017-07-31 18:26:12,635 DEBUG [admin] (ShipmentController.java:522) - REPORT date=2017-07-1TO date=2017-07-31
    2017-07-31 18:26:12,635 DEBUG [admin] (ReportServiceClient.java:178) - Calling [ReportService.getSummary] service for dateFrom[2017-07-1] and dateTo[2017-07-31]
    2017-07-31 18:26:12,671 DEBUG [admin] (ShipmentController.java:531) - Result List Size : 4
    2017-07-31 18:26:12,824 DEBUG [admin] (ShipmentController.java:534) - Xlsx Sheet Generated!!
    2017-07-31 18:26:12,824 DEBUG [admin] (ShipmentController.java:539) - Content-Type : application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    2017-07-31 18:26:12,824 DEBUG [admin] (ShipmentController.java:540) - Header : attachment; filename=summary_2017_07_31.xlsx
    2017-07-31 18:26:12,824 DEBUG [admin] (ShipmentController.java:542) - Set ALL

我可以下載xlsx文件,但數據已損壞。 實際上,網頁內容/ html頁面視圖是用xlsx文件編寫的。

當沒有數據時,我想顯示彈出窗口;當沒有數據時,我要下載創建的xlsx。

為什么在設置內容類型后更改它。 我該如何正確解決這個問題。

注意:我有一種類似的控制器方法,我創建一個pdf文件並將內容類型設置為response.setContentType("application/pdf") ,它對我來說很好用。

您需要添加單獨的控制器@RequestMapping ,該控制器僅返回XLSX文件字節,並用@ResponseBody注釋。 然后,您可以從JSP的主體內部創建指向此端點的超鏈接,以便用戶單擊該鏈接時,他們可以下載文件。 嘗試在單個RequestMapping嘗試同時返回JSP主體和XLSX內容將不起作用,因為包含JSP的返回類型設置為text/html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM