您的位置:首页 > 编程语言 > Java开发

Web项目中使用java Struts2实现Zip、xml文件的动态创建和下载(Zip文件中动态存在多个xml文件)

2012-11-05 14:12 489 查看
web项目中有时候会遇到动态生成zip并下载的需求,但是在生成zip文件的时候我们又不希望产生冗余的临时文件。下面将

介绍我的处理方式。有不妥的地方还希望大家批评指教。

此次需求描述如下:

1.根据数据动态生成XML文件

2.将动态生成的XML文件(一个或多个)整合打包成一个Zip文件

3.客户通过浏览器点击后完成Zip文件的下载

下面开始开发相应功能

1.根据数据动态生成XML文件

这里使用dom4j-1.6.1.jar来实现XML的读取和创建:

public class XmlHandleDom4jHelper{

/**
* Creating a new XML document
*
* @author hli
*/
public static Document generateDocument() {
Document document = DocumentHelper.createDocument();
document.addComment("创建XML");
Element root = document.addElement("root");
Element author1 = root.addElement("author").addAttribute("name", "李红").addAttribute("age", "25").addText("李红");

Element author2 = root.addElement("info").addAttribute("QQ", "317962765").addText("317962765");

return document;
}

/**
* Writing a document to a file
*
* @param document
* @throws IOException
*/
public static void write(ByteArrayOutputStream byteArrayOutputStream,Document document) throws IOException {
OutputFormat format = OutputFormat.createPrettyPrint();
format.setTrimText(true);
format.setNewLineAfterDeclaration(false);
XMLWriter writer = new XMLWriter(byteArrayOutputStream, format);
writer.write(document);
writer.flush();
writer.close();
}
}


2.动态生成Zip文件

/**
* 生成ZIP文件(不生成临时文件)
*
* @param out
* @author hli
* @return byte[] ZIP文件byte数组
*/
public byte[] generateCommonTransZipStreamNoTempFile() {

byte[] zipData = null;
try {

List<ByteArrayOutputStream> xmlFileListByteOutputStream = new ArrayList<ByteArrayOutputStream>();

ByteArrayOutputStream xmlFileByteArrayOutputStream = null;

for ( int num = 1 ; num < 3 ; num++ ) {

xmlFileByteArrayOutputStream = new ByteArrayOutputStream();

Document document = XmlHandleDom4jHelper.generateDocument();

XmlHandleDom4jHelper.write(xmlFileByteArrayOutputStream,document);

xmlFileListByteOutputStream.add(xmlFileByteArrayOutputStream);

}

ByteArrayOutputStream outputStreamByte = new ByteArrayOutputStream();
// ----压缩文件:
// FileOutputStream f = new FileOutputStream("F:\\report\\abc.zip");

// 使用指定校验和创建输出流
CheckedOutputStream csum = new CheckedOutputStream(outputStreamByte, new CRC32());

ZipOutputStream zos = new ZipOutputStream(csum);
zos.setEncoding("GBK");

for ( int i = 0 ; i < xmlFileListByteOutputStream.size() ; i++ ) {

ByteArrayOutputStream byteStream = xmlFileListByteOutputStream.get(i);

byte[] bytes = byteStream.toByteArray();

ByteArrayInputStream byInputStream = new ByteArrayInputStream(bytes);

// 开始写入新的ZIP文件条目并将流定位到条目数据的开始处
ZipEntry zipEntry = new ZipEntry("Test_xml_file_" + i);
zos.putNextEntry(zipEntry);
byte[] buffer = new byte[1024];
int readCount = byInputStream.read(buffer);

while (readCount != -1) {
zos.write(buffer, 0, readCount);
readCount = byInputStream.read(buffer);
}
// 注,在使用缓冲流写压缩文件时,一个条件完后一定要刷新一把,不 然可能有的内容就会存入到后面条目中去了
zos.flush();

// 文件读完后关闭
byInputStream.close();

}
zos.closeEntry();// 此处 一定要close,否则下载的ZIP错误

zos.close();

zipData = outputStreamByte.toByteArray();

} catch (Exception e) {
e.printStackTrace();
}
return zipData;
}


3.客户通过浏览器点击后完成Zip文件的下载

此处使用Struts2的文件下载功能

备注:参考我另一篇文章:点击打开链接

A>在action中编码:

public InputStream getDownZipStream() {

byte[] zipData = reportService.generateCommonTransZipStreamNoTempFile();

//此处为下载的文件名称
//若为中文,则需要进行编码
downFileName = "downZip.zip";

return new ByteArrayInputStream(zipData);
}


B>Struts2配置文件中:

<action name="down_zip" class="com.hli.action.report.ReportAction">
<result name="success" type="stream">
<param name="contentType">application/zip</param>
<param name="inputName">downZipStream</param>
<param name="contentDisposition">attachment;filename="${downFileName}"</param>
<param name="bufferSize">4096</param>
</result>


完成上述编程后,所需需求实现且无临时文件生成。

备注:上传java方法实现需要优化,暂时先记下,待日后完善
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: