Java Web实现文件打包下载并解决乱码问题

    xiaoxiao2025-08-04  16

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

    效果如图:

    转载请注明原文地址: https://ju.6miu.com/read-1301386.html
    最新回复(0)