天天看点

struts2实现文件导出type="stream"

之前项目中使用struts2实现文件导出,但是跟踪代码并没有理解这是怎么做到的。后来网上看了几个大神的文章才略有所悟,在此分享出来,望各位指点。

配置:

<package name="test" namespace="/test" extends="struts-default">
        <action name="*" method="{1}" class="com.testAction">
            <result name="download" type="stream">
                <param name="contentType">application/octet-stream,text/csv;charset=UTF-8</param>
                <param name="inputName">apendListInputStream</param>
                <param name="contentDisposition">attachment;filename=${downFileName}</param>
                <param name="bufferSize">10485760</param>
            </result>
        </action>
</package>
           

配置解释:

type="stream"           

    把一般内容输出到流

contentType              

    指定文件格式(内容类型,和互联网MIME标准中的规定类型一致,例如text/plain代表纯文本,text/xml表示XML,image/gif代表GIF图片,image/jpeg代表JPG图片)

contentDisposition 

    其中attachment 将会告诉浏览器下载该文件,filename 指定下载文件保有存时的文件名

bufferSize                  

    下载缓冲区的大小

downFileName

    要求action中必须有downFileName的一个属性,且提供了set get方法,在程序第一次发起对action的请求时给downFileName赋值,如(/test/exportFile.action)。

<param name="inputName">apendListInputStream</param>

    参数inputName指定输入流的名称。和前面的文件名一样,Action里提供一个getApendListInputStream()的方法返回值是inputStream。

代码:

public class TestAction extends BaseAction{
        private String downFileName;
        public String getDownFileName() {
        return downFileName;
        }
        public void setDownFileName(String downFileName) {
            this.downFileName = downFileName;
        }
        public String exportFile() throws Exception{
            //业务逻辑校验,比如导出数量大小限制等
            //文件名命名
            String name = "导出结果" + DateFormatUtils.format(new Date())+ ".csv";
            downFileName = new String(name.getBytes("gbk"), "ISO8859-1");
            return "download";
        }
    
        public InputStream getApendListInputStream() {
            InputStream inputStream = null;
            try {
                //从数据库或其他地方获取要导出数据list
                //list生成文件,这个地方如何生成文件,可以参考其他资料,我们只做strust2的逻辑,不纠结文件生成。
                CSVWriter writer=null;
                String[] titles = {"标题1","标题2","标题3","标题4"...};
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                for (Test ia : list) {
                    writer = new CSVWriter(new BufferedWriter(new OutputStreamWriter(baos, "GBK")));
                    writer.writeNext(titles);
                    writer.writeNext(ia);
                }
                inputStream=new ByteArrayInputStream(baos.toByteArray());
            }catch (Exception e) {
                log.error("StationMsgAction.getApendListInputStream is error", e);
            }
            return inputStream;
        }
    }
           

发送请求:/test/exportFile.action,即可导出文件。

有没有发现很神奇的事情,文件名和文件内容都是依据action中的方法生成的,文件名和文件内容调用哪个方法来生成,都是通过配置中的变量跟actiong中的方法做默认匹配的。虽然精简了代码,但是确实容易让人迷惑。

继续阅读