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

发布于 2024-08-19 14:20:13 字数 247 浏览 5 评论 0原文

我想使用java、struts2和ajax进行文件下载。

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

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

有可用的例子吗?

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

谢谢。

阿玛尔4金图

I want to give file download using java,struts2 and 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.

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

Is there any example available?

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

Thanks.

amar4kintu

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

软的没边 2024-08-26 14:20:13

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

示例:

在您的 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());

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 result type.

Example:

In your 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.

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

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

// Using Workbook from Apache POI for example...
Workbook wb;
// ...
ByteArrayOutputStream bos = new ByteArrayOutputStream();
wb.write(bos);
InputStream bis = new ByteArrayInputStream(bos.toByteArray());
兮子 2024-08-26 14:20:13

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

Just for your reference, we can do the same using 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));
    }
}
墨洒年华 2024-08-26 14:20:13

作为 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 行特别必须指示该文件是附件并且文件名用引号引起来。

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:

<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 contentDisposition line in particular must indicate that the file is an attachment and that the filename is surrounded by quotes.

夏尔 2024-08-26 14:20:13

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

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

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

@Result(name = "success", type= StreamResult.class,
          params = {"contentType", "application/vnd.ms-excel",
                    "contentDisposition", "attachment; filename=report.xls"},
          value = "reportFileStream"
)
森末i 2024-08-26 14:20:13

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

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

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

参考:
将 Java 输出流转换为输入流

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

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.

Reference:
Convert a Java OutputStream to an InputStream

野生奥特曼 2024-08-26 14:20:13

最后,我能够解决它如下..
我在操作类函数中编写了以下行,并且能够下载名为 report.xls 而不是 ExportReport.action 的文件。我不太清楚..为什么?

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

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

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

谢谢。

阿玛尔4金图

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.xls instead of ExportReport.action. I do not know exactly .. why?

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

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

<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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文