web项目中有时候会遇到动态生成zip并下载的需求,但是在生成zip文件的时候我们又不希望产生冗余的临时文件。下面将
1.根据数据动态生成XML文件
2.将动态生成的XML文件(一个或多个)整合打包成一个Zip文件
3.客户通过浏览器点击后完成Zip文件的下载
2.动态生成Zip文件
3.客户通过浏览器点击后完成Zip文件的下载
此处使用Struts2的文件下载功能
备注:参考我另一篇文章: 点击打开链接
B>Struts2配置文件中:
介绍我的处理方式。有不妥的地方还希望大家批评指教。
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方法实现需要优化,暂时先记下,待日后完善