【问题标题】:how to return excel in Struts2 result?如何在 Struts2 结果中返回 excel?
【发布时间】:2009-06-16 20:54:59
【问题描述】:

我正在尝试从我的 struts2 操作类返回 Excel 工作表。

我不确定我应该使用什么结果类型?有没有人尝试从 struts2 动作类返回 excel?
我希望向用户显示打开/保存/取消对话框

【问题讨论】:

    标签: java struts2


    【解决方案1】:

    Omnipresent 在 struts.xml 中涵盖了您需要的内容。我也在添加一个带有 Action 的示例:

    InputStream excelStream
    String contentDisposition
    String documentFormat = "xlsx"
    
    String excel() {
    
        ServletContext servletContext = ServletActionContext.getServletContext()
        String filePath = servletContext.getRealPath("/WEB-INF/template/excel/mytemplate.${documentFormat}")
    
        File file = new File(filePath)
        Workbook wb = WorkbookFactory.create(new FileInputStream(file))
    
        Sheet sheet = wb.getSheetAt(0)
    
    <write to excel file>
    
        ByteArrayOutputStream baos = new ByteArrayOutputStream()
        wb.write(baos)
        excelStream = new ByteArrayInputStream(baos.toByteArray())
        contentDisposition = "filename=\"myfilename.${documentFormat}\""
    
        return SUCCESS
    }
    
    String getExcelContentType() {
        return documentFormat == "xlsx" ? "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" : "application/vnd.ms-excel"
    }
    

    我正在使用 poi 模型:org.apache.poi.ss.usermodel。

    您可以根据需要将“xlsx”替换为“xls”。

    struts.xml:

    <action name="myaction" class="com.example.MyAction" method="excel">
            <result type="stream">
                <param name="contentType">${excelContentType}</param>
                <param name="inputName">excelStream</param>
                <param name="contentDisposition">contentDisposition</param>
                <param name="bufferSize">1024</param>
            </result>
        </action>
    

    (添加分号和其他内容以转换为有效的 Java)

    【讨论】:

    • 这有点晚了,但我在同一个问题上需要帮助。首先,在这种情况下,首先在服务器端创建一个文件,然后将其流式传输到客户端。是否可以将 excel 工作表的内容直接流式传输到客户端。其次,您将哪个类用于结果类型“流”。请帮帮我。谢谢!!
    • 'stream' 是 org.apache.struts2.dispatcher.StreamResult,它驻留在 struts2-core 中,并在 struts-default.xml 中定义为结果类型(也在 struts2-core 中)。
    • 关于流媒体,我不知道。可能与 bufferSize 有关,也许较低的值会更直接地流式传输?
    • 好的。拿到了第一部分。谢谢!!
    【解决方案2】:

    您可以使用Stream Result 类型

    示例如下所示:

    <result name="excel" type="stream">
        <param name="contentType">application/vnd.ms-excel</param>
        <param name="inputName">excelStream</param>
        <param name="contentDisposition">attachment; filename="${fileName}"</param>
        <param name="bufferSize">1024</param>
        <param name="contentLength">${contentLength}</param>
     </result>
    

    excelStream 将是您的操作类中的一个方法,contentLength 将是流的长度,fileName 将是一个 getter,它将返回文件的名称。

    【讨论】:

    • 对于 xlsx,使用 contentType application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    • 这是两个答案中更好的一个,因为用户询问“我希望向用户显示打开/保存/取消对话框”。 contentDisposition 中的 attachment; 部分是强制浏览器始终打开对话框所必需的。没有它,如果这样配置,浏览器可能会尝试渲染材质本身。
    【解决方案3】:

    如果需要使用 POI/HSSF 动态生成 Excel 文件并在 Struts 2 中返回,

    JSP

    <s:url action="DownloadExcel.action" var="downloadUrl">
    </s:url>
    <s:a href="%{downloadUrl}">Click to Download</s:a>
    

    动作方法

    @Action(value = "DownloadExcel")
    public void download() throws Exception {
        
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        
        String filename = "report.xlsx"; // or any other filename strategy
        String mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        String characterEncoding = response.getCharacterEncoding();
        if (characterEncoding != null) {
            mimeType += "; charset=" + characterEncoding;
        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + filename);
    
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.getSheetAt(0);
        // Fill out workbook as necessary... (simple example)
        XSSFRow row = sheet.createRow(0);
        XSSFCell cell = row.createCell(0);
        cell.setCellValue("test");
        //...
    
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            workbook.write(out);
            workbook.close();
        } catch (IOException e) {
            log.error("Failed to write into response - fileName=" + filename + ", mimeType=" + mimeType, e);
        }
        finally {
            if (out != null) {
                out.flush();
                out.close();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-02
      • 2015-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多