Java Web实现文件打包下载详见代码:
作为工具类我封装在FileUtil里,解决压缩乱码要下载
apache-ant-zip.jar包
JDK中自带的ZipOutputStream在压缩文件时,如果文件名中有中文,则压缩后的
zip文件打开时发现中文文件名变成乱码.
解决的方法是使用apache-ant-zip.jar包(见附件)中的ZipOutputStream和ZipEntry.
即,导入类:
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
并且注意,压缩之前调用 ZipOutputStream的out.setEncoding(System.getProperty("sun.jnu.encoding")); 方法,
系统参数sun.jnu.encoding表示获取当前系统中的文件名的编码方式.这里将ZipOutputStream的文件名编码方式
设置成系统的文件名编码方式.
解压时,直接使用JDK原来的ZipInputStream即可.
但是有个 需要注意 的地方是,在读取ZIP文件之前,需要设置:
System.setProperty("sun.zip.encoding", System.getProperty("sun.jnu.encoding"));
将系统的ZIP编码格式设置为系统文件名编码方式,否则解压时报异常.
(网上,还有修改ZipInputStream源码的方式貌似太麻烦了,参考:http://zwllxs.iteye.com/blog/871260)
/** * 文件打包下载 * * @param tempFilePath 待创建临时压缩文件 * @param files 待压缩文件集合 * @param request 请求 * @param response 响应 * @return response * @throws Exception 异常 */ public static HttpServletResponse downLoadZipFiles(String tempFilePath, List<File> files, HttpServletRequest request, HttpServletResponse response) throws Exception { try { /**这个集合就是你想要打包的所有文件, * 这里假设已经准备好了所要打包的文件*/ //List<File> files = new ArrayList<File>(); /**创建一个临时压缩文件, * 我们会把文件流全部注入到这个文件中 * 这里的文件你可以自定义是.rar还是.zip*/ File file = new File(tempFilePath); if (!file.exists()) { file.createNewFile(); } response.reset(); //response.getWriter() //创建文件输出流 FileOutputStream fous = new FileOutputStream(file); /**打包的方法我们会用到ZipOutputStream这样一个输出流, * 所以这里我们把输出流转换一下*/ ZipOutputStream zipOut = new ZipOutputStream(fous); zipOut.setEncoding(System.getProperty("sun.jnu.encoding"));//设置文件名编码方式 /**这个方法接受的就是一个所要打包文件的集合, * 还有一个ZipOutputStream*/ zipFile(files, zipOut); zipOut.close(); fous.close(); return downloadZip(file, response, request); } catch (Exception e) { e.printStackTrace(); } /**直到文件的打包已经成功了, * 文件的打包过程被我封装在FileUtil.zipFile这个静态方法中, * 稍后会呈现出来,接下来的就是往客户端写数据了*/ return response; } /** * 把接受的全部文件打成压缩包 * * @param files * @param outputStream org.apache.tools.zip.ZipOutputStream */ public static void zipFile(List files, ZipOutputStream outputStream) { int size = files.size(); for (int i = 0; i < size; i++) { File file = (File) files.get(i); zipFile(file, outputStream); } } public static HttpServletResponse downloadZip(File file, HttpServletResponse response, HttpServletRequest request) { try { // 以流的形式下载文件。 InputStream fis = new BufferedInputStream(new FileInputStream(file.getPath())); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/x-msdownload"); //如果输出的是中文名的文件,解决乱码 response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(file.getName().getBytes("gbk"), "iso-8859-1") + "\""); toClient.write(buffer); toClient.flush(); toClient.close(); } catch (IOException ex) { ex.printStackTrace(); } finally { try { File f = new File(file.getPath()); f.delete(); } catch (Exception e) { e.printStackTrace(); } } return response; } /** * 根据输入的文件与输出流对文件进行打包 * * @param inputFile File * @param ouputStream org.apache.tools.zip.ZipOutputStream */ public static void zipFile(File inputFile, ZipOutputStream ouputStream) { try { if (inputFile.exists()) { /**如果是目录的话这里是不采取操作的, * 至于目录的打包正在研究中*/ if (inputFile.isFile()) { FileInputStream IN = new FileInputStream(inputFile); BufferedInputStream bins = new BufferedInputStream(IN, 512); //org.apache.tools.zip.ZipEntry ZipEntry entry = new ZipEntry(inputFile.getName()); // ZipEntry entry = new ZipEntry(new String(inputFile.getName().getBytes(), "utf-8")); ouputStream.putNextEntry(entry); // 向压缩文件中输出数据 int nNumber; byte[] buffer = new byte[512]; while ((nNumber = bins.read(buffer)) != -1) { ouputStream.write(buffer, 0, nNumber); } // 关闭创建的流对象 bins.close(); IN.close(); } else { try { File[] files = inputFile.listFiles(); for (int i = 0; i < files.length; i++) { zipFile(files[i], ouputStream); } } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } }
Controller层调用:
@ActionAnnotation(name = "生成函調報告1,2文档并下载", group = "查询") public ModelAndView createWord1(HttpServletRequest request, HttpServletResponse response) throws Exception { Management management = managementService.query(request.getParameter("mm_id")); Map<String, Object> model = new HashMap<String, Object>(); model.put("management", management); String view = SystemParameter.get("soldier"); Template template = freeMarkerConfigurer.getConfiguration().getTemplate(SystemParameter.get("tempDirSoldier") + "/soldier.ftl", "utf-8"); String temp = FreeMarkerTemplateUtils.processTemplateIntoString(template, model); File file = new File(getServletContext().getRealPath(view)); FileUtils.writeStringToFile(file, temp, "utf-8"); String view1 = SystemParameter.get("unSoldierly"); Template template1 = freeMarkerConfigurer.getConfiguration().getTemplate(SystemParameter.get("tempDirSoldier") + "/unSoldierly.ftl", "utf-8"); String temp1 = FreeMarkerTemplateUtils.processTemplateIntoString(template1, model); File file1 = new File(getServletContext().getRealPath(view1)); FileUtils.writeStringToFile(file1, temp1, "utf-8"); List<File> fileList = new ArrayList<File>(); fileList.add(file); fileList.add(file1); FileUtil.downLoadZipFiles(getServletContext().getRealPath(SystemParameter.get("tempDirZipReport")), fileList, request, response); return responseText(response, "1"); }
效果如图: