使用 Java、Struts 2 和 AJAX 下载文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2122490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:47:28  来源:igfitidea点击:

File download using Java, Struts 2 and AJAX

javaajaxjspdownloadstruts2

提问by amar4kintu

I want to give file download using java,struts2 and ajax.

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

On my html page there is a button called "export" clicking on which ajax call will be made which will execute a query and will create .xls file using code and I want to give that file for download to user without storing it on hard drive.

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

Does any one know how to do that using struts2 and ajax in java?

有谁知道如何在java中使用struts2和ajax来做到这一点?

Is there any example available?

有没有可用的例子?

Let me know if you need more details from me...

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

Thanks.

谢谢。

amar4kintu

阿玛金图

采纳答案by ZoogieZork

You don't have to use AJAX in this case. Just have your button submit the form to your Struts action, and have the action use the stream resulttype.

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

Example:

例子:

In your Struts XML:

在您的 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>

Your action will then provide a public InputStream getInputStream()to pass along the data.

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

I presume that whatever library you're using to generate the Excel files (POI?) can write the output to an arbitrary OutputStream.

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

A quick-and-dirty way to convert that to an InputStream:

将其转换为 的一种快速而肮脏的方法InputStream

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

回答by amar4kintu

atlast, I was able to solve it as following.. I wrote following line in my action class function and I was able to download file with name report.xlsinstead of ExportReport.action. I do not know exactly .. why?

最后,我能够解决它如下..我在我的动作类函数中写了以下行,我能够下载名称report.xls而不是ExportReport.action. 我不知道到底.. 为什么?

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

Following is in my struts.xmlfile. I removed <contentDispositin>param from it because it was not working from struts.xmlfile and I put it in my action Java file as above.

以下是我的struts.xml文件。我从中删除了<contentDispositin>参数,因为它不能从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>

Hope this will help someone.

希望这会帮助某人。

Thanks.

谢谢。

amar4kintu

阿玛金图

回答by Aleksey Otrubennikov

I'd use this kind of annotation on the Action class:

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

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

回答by web guy

As a follow-up to amar4kintu's question regarding files saved as ExportReport.action instead of report.xls, this happens in IE if the following format is not followed in your struts.xml file:

作为 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>

It seems like the contentDispositionline in particular must indicate that the file is an attachment and that the filename is surrounded by quotes.

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

回答by Krishan Babbar

Just for your reference, we can do the same using Annotation:

仅供参考,我们可以使用 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));
    }
}

回答by Gaurav Kumar

A better approach to pipe outstream to an inputstream is explained below as opposed to the response by ZoogieZork above

与上面 ZoogieZork 的响应相反,下面解释了将输出流传输到输入流的更好方法

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

The advantage of this method is that the entire buffer is not stored in memory but is rather piped using a small internal circular buffer. This is better both in terms of memory as well as CPU overhead.

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

Reference: Convert a Java OutputStream to an InputStream

参考: 将 Java OutputStream 转换为 InputStream