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

时间:2021-07-17 09:45:13

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页面上有一个名为“export”的按钮,点击将执行ajax调用,该调用将执行查询并将使用代码创建.xls文件,我想将该文件下载给用户而不将其存储在硬盘驱动器上。

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

amar4kintu

6 个解决方案

#1


11  

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.

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

然后,您的操作将提供公共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());

#2


2  

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));
    }
}

#3


2  

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

似乎contentDisposition行必须指出该文件是附件,并且文件名用引号括起来。

#4


0  

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"
)

#5


0  

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

#6


0  

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?

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

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.

以下是我的struts.xml文件。我从中删除了 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>

Hope this will help someone.

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

Thanks.

谢谢。

amar4kintu

amar4kintu

#1


11  

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.

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

然后,您的操作将提供公共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());

#2


2  

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));
    }
}

#3


2  

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

似乎contentDisposition行必须指出该文件是附件,并且文件名用引号括起来。

#4


0  

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"
)

#5


0  

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

#6


0  

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?

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

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.

以下是我的struts.xml文件。我从中删除了 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>

Hope this will help someone.

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

Thanks.

谢谢。

amar4kintu

amar4kintu