使用Java,Struts 2和AJAX进行文件下载

时间:2010-01-23 07:26:52

标签: java ajax jsp download struts2

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

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

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

有没有可用的例子?

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

感谢。

amar4kintu

6 个答案:

答案 0 :(得分:11)

在这种情况下,您不必使用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());

答案 1 :(得分:2)

作为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行必须表明该文件是附件,并且文件名用引号括起来。

答案 2 :(得分:2)

仅供您参考,我们可以使用注释执行相同的操作:

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 :(得分:0)

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

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

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

下面解释了管道输出到输入流的更好方法 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