【问题标题】:File download using Java, Struts 2 and AJAX使用 Java、Struts 2 和 AJAX 下载文件
【发布时间】:2011-01-08 12:18:27
【问题描述】:

我想使用 java、struts2 和 ajax 提供文件下载。

在我的 html 页面上有一个名为“export”的按钮,点击哪个 ajax 调用将执行查询并使用代码创建 .xls 文件,我想将该文件提供给用户下载而不存储它在硬盘上。

有人知道如何在java中使用struts2和ajax吗?

有例子吗?

如果您需要我提供更多详细信息,请告诉我...

谢谢。

amar4kintu

【问题讨论】:

    标签: java ajax jsp download struts2


    【解决方案1】:

    在这种情况下,您不必使用 AJAX。只需让您的按钮将表单提交给您的 Struts 操作,并让该操作使用 stream result 类型。

    例子:

    在您的 Struts XML 中:

    <result name="download" type="stream">
        <param name="contentDisposition">attachment;filename=report.xls</param>
        <param name="contentType">application/vnd.ms-excel</param>
        <param name="inputName">inputStream</param>
        <param name="bufferSize">1024</param>
    </result>
    

    然后您的操作将提供一个public InputStream getInputStream() 来传递数据。

    我认为您用来生成 Excel 文件的任何库 (POI?) 都可以将输出写入任意的OutputStream

    一种将其转换为InputStream 的快捷方式:

    // Using Workbook from Apache POI for example...
    Workbook wb;
    // ...
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    wb.write(bos);
    InputStream bis = new ByteArrayInputStream(bos.toByteArray());
    

    【讨论】:

    • 您好,我在我的 struts.xml 中添加了以下内容 application/vnd.ms-excel fileStream attachment;filename=report.xls 1024 现在我按照您的说明进行操作,但它提供的文件下载操作名称为 ExportReport.action 而不是 report.xls 所以应该是什么原因?
    • 那么,您使用的是 MSIE?将文件名作为 URL 路径信息传递,或者使用更好的网络浏览器。
    • 我使用的是 firefox,它应该给我下载文件为 report.xls,但它给了我 ExportReport.action 下载。如果我将其重命名为report.xls。它显示了我正在导出的完美 .xls 文件。谁能告诉我我错过了什么?
    【解决方案2】:

    仅供参考,我们可以使用 Annotation 来做同样的事情:

    public class MyAction {
        private InputStream fileInputStream;
        private String logoName;
    
        @Action(value="/downloadLogo", 
            results={
                @Result(name="success", type="stream", 
                params = {
                        "contentType", "application/image/gif",
                        "inputName", "fileInputStream",
                        "contentDisposition", "filename=\"${logoName}\"",
                        "bufferSize", "1024"
                })
            }           
        )    
        public String downloadLogo() throws Exception {
            logoName = "test.jpg";
                fileInputStream = new FileInputStream(new File("DirePath", logoName));
        }
    }
    

    【讨论】:

      【解决方案3】:

      作为 amar4kintu 关于保存为 ExportReport.action 而不是 report.xls 文件的问题的后续行动,如果您的 struts.xml 文件中未遵循以下格式,则会在 IE 中发生这种情况:

      <result name="download" type="stream">
              <param name="contentDisposition">attachment;filename="${flashcardSetBean.title}.xlsx"</param>
              <param name="contentType">application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</param>
              <param name="inputName">inputStream</param>
              <param name="bufferSize">1024</param>
      </result>
      

      似乎contentDisposition 行特别必须表明该文件是一个附件并且文件名用引号括起来。

      【讨论】:

        【解决方案4】:

        我会在 Action 类上使用这种注释:

        @Result(name = "success", type= StreamResult.class,
                  params = {"contentType", "application/vnd.ms-excel",
                            "contentDisposition", "attachment; filename=report.xls"},
                  value = "reportFileStream"
        )
        

        【讨论】:

          【解决方案5】:

          下面解释了一种将输出流传输到输入流的更好方法 as opposed to the response by ZoogieZork above

          InputStream is = new PipedInputStream();
          PipedOutputStream out = new PipedOutputStream((PipedInputStream) is);
          wb.write(out);
          

          这种方法的优点是整个缓冲区不存储在内存中,而是使用一个小的内部循环缓冲区进行管道传输。这在内存和 CPU 开销方面都更好。

          参考: Convert a Java OutputStream to an InputStream

          【讨论】:

            【解决方案6】:

            atlast,我能够解决它如下.. 我在我的动作类函数中写了以下行,我能够下载名称为 report.xls 而不是 ExportReport.action 的文件。我不知道确切..为什么?

            response.setHeader("Content-Disposition","attachment;filename=rpt.xls"); 
            

            以下内容在我的struts.xml 文件中。我从中删除了&lt;contentDispositin&gt; 参数,因为它不能从struts.xml 文件中工作,我将它放在我的操作Java 文件中,如上所述。

            <result name="success"  type="stream" >
                <param name="inputName">fileStream</param>
                <param name="contentType">application/vnd.ms-excel</param>
                <param name="bufferSize">1024</param>
            </result>
            

            希望这会对某人有所帮助。

            谢谢。

            amar4kintu

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-12-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-07-03
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多