java实现word批量多模版(浏览器zip压缩导出)
用java实现word导出,如果不实现批量导出,可以只使用 word 替换工具,如果要实现批量导出,这里的解决办法是将所有的导出文件放入服务器临时文件,压缩后导出
1.依赖包
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>3.9</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>3.0.3</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>3.0.3</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>3.0.3</version></dependency>
2. word模板替换工具
package com.**.**.util;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Map;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.util.Assert;
// 这是俩个常量包 BIAS = "/" , MSIE = "MSIE",TRIDENT = "Trident",MOZILLA = "Mozilla"
import com.***.***.core.constants.CoreConstant;
import com.***.***.web.constants.EquipmentComputeConstants;import cn.afterturn.easypoi.word.WordExportUtil;public class ExportUtil {/*** 导出word* <p>* 第一步生成替换后的word文件,只支持docx* </p>* <p>* 第二步下载生成的文件* </p>* <p>* 第三步删除生成的临时文件* </p>* 模版变量中变量格式:{{foo}}* * @param templatePath* word模板地址* @param temDir* 生成临时文件存放地址* @param fileName* 文件名* @param params* 替换的参数* @param request* HttpServletRequest* @param response* HttpServletResponse* @throws IOException*/public static void exportWord(String templatePath, String temDir, String fileName, Map<String, Object> params,HttpServletRequest request, HttpServletResponse response) throws IOException {Assert.notNull(templatePath, "模板路径不能为空");Assert.notNull(temDir, "临时文件路径不能为空");Assert.notNull(fileName, "导出文件名不能为空");Assert.isTrue(fileName.endsWith(".docx"), "word导出请使用docx格式");if (!temDir.endsWith(CoreConstant.BIAS)) {temDir = temDir + File.separator;}File dir = new File(temDir);if (!dir.exists()) {dir.mkdirs();}FileInputStream in = null;
// OutputStream out2 = null;try {XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);String tmpPath = temDir + fileName;// 写在本地FileOutputStream fos = new FileOutputStream(tmpPath);doc.write(fos);/** ------------下载到本地------------ // 设置强制下载不打开* response.setContentType("application/force-download"); // 设置文件名* response.addHeader("Content-Disposition", "attachment;fileName="* + fileName); OutputStream out = response.getOutputStream();* doc.write(out); out.close();*/// -------浏览器下载--------------// 读取要下载的文件,保存到文件输入流in = new FileInputStream(tmpPath);// 获得浏览器代理信息final String userAgent = request.getHeader("USER-AGENT");// 判断浏览器代理并分别设置响应给浏览器的编码格式String finalFileName = null;if (StringUtils.contains(userAgent, EquipmentComputeConstants.MSIE) || StringUtils.contains(userAgent, EquipmentComputeConstants.TRIDENT)) {// IE浏览器finalFileName = URLEncoder.encode(fileName, "UTF8");System.out.println("IE浏览器");} else if (StringUtils.contains(userAgent, EquipmentComputeConstants.MOZILLA)) {// google,火狐浏览器finalFileName = new String(fileName.getBytes(), "ISO8859-1");} else {finalFileName = URLEncoder.encode(fileName, "UTF8");// 其他浏览器}// // 缓存区
// byte buffer[] = new byte[1024];
// int len = 0;
// // 循环将输入流中的内容读取到缓冲区中
// while ((len = in.read(buffer)) > 0) {
// out2.write(buffer, 0, len);
// }// 关闭in.close();
// out2.close();// 清空response
// response.reset();} catch (Exception e) {e.printStackTrace();} // 删除服务器上的临时文件File deleteFile = new File(temDir);deleteFile.delete();}
}
3.zip压缩导出工具
package com.**.**.util;import static org.springframework.util.StreamUtils.BUFFER_SIZE;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;import com.**.**.exception.ResourceException;
import com.**.**.web.constants.Constants;/** * zip打包下载工具* @author ***** <p>2019年4月30日 上午9:53:21</p> * @see* @version 1.0 */
public class ZipExportUtil {/** * 打包* @param path 文件夹路径*/public static void zipExport(String path, HttpServletResponse response){try {response.setContentType("application/DOWLOAD");response.setHeader("Content-Disposition", "attachment; filename="+ DateUtils.dateToString(new Date()) + ".zip");ServletOutputStream out = response.getOutputStream();toZip(path, out, true);DelAllFileUtil.delAllFile("F:\\annualAeport");} catch (Exception e) {throw new ResourceException(Constants.EXCEPTION_CODE_500, e.getMessage());}}/*** 打压缩包导出* * @param srcDir* @param out* @param keepDirStructure* @throws RuntimeException*/public static void toZip(String srcDir, OutputStream out, boolean keepDirStructure) throws RuntimeException {ZipOutputStream zos = null;try {zos = new ZipOutputStream(out);File sourceFile = new File(srcDir);compress(sourceFile, zos, sourceFile.getName(), keepDirStructure);} catch (Exception e) {throw new RuntimeException("zip error from ZipUtils", e);} finally {if (zos != null) {try {zos.close();} catch (IOException e) {throw new ResourceException(Constants.EXCEPTION_CODE_500, e.getMessage());}}}}/*** 执行压缩* * @param sourceFile* @param zos* @param name* @param keepDirStructure* @throws Exception*/private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean keepDirStructure)throws Exception {byte[] buf = new byte[BUFFER_SIZE];if (sourceFile.isFile()) {// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字zos.putNextEntry(new ZipEntry(name));// copy文件到zip输出流中int len;FileInputStream in = new FileInputStream(sourceFile);while ((len = in.read(buf)) != -1) {zos.write(buf, 0, len);}// Complete the entryzos.closeEntry();in.close();} else {File[] listFiles = sourceFile.listFiles();if (listFiles == null || listFiles.length == 0) {// 需要保留原来的文件结构时,需要对空文件夹进行处理if (keepDirStructure) {// 空文件夹的处理zos.putNextEntry(new ZipEntry(name + "/"));// 没有文件,不需要文件的copyzos.closeEntry();}} else {for (File file : listFiles) {// 判断是否需要保留原来的文件结构if (keepDirStructure) {// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了compress(file, zos, name + "/" + file.getName(), keepDirStructure);} else {compress(file, zos, file.getName(), keepDirStructure);}}}}}
}
4.模板样例 文档中的替换样例用{{}}
5.模板在resources下,此处路径本地下载没问题,服务器下载要配置服务器绝对路径 (本地相对路径:/templates 服务器绝对路径:打包后web路径会加入/WEB-INF/classes 这俩层结构)
6. 控制层使用void 不return结果,否则会报错(因需求已实现,且中途改过工具,不确定,问题应该未解决)
@AspectLog(description = "批量导出word")@ApiOperation("批量导出word")@RequestMapping(value = "/datereporting/export", method = RequestMethod.GET)public void export(HttpServletRequest request, HttpServletResponse response, String ids) {try {dateReportingService.batchExport(ids, request, response);} catch (Exception e) {logger.error(Constants.CONTROLLER_GET_ERROR_LOG, e.getMessage());}}
7. 调用替换word工具
// Map<String, Object> everyMap 为 要替换的导出数据 Map<String, Object> data 中的 键 为模板文档中的对应变量
private void exportSocialPerformanceAnalysisReport(Map<String, Object> everyMap, HttpServletRequest request,HttpServletResponse response) throws IOException {String year = everyMap.get("YEAR") == null ? EquipmentComputeConstants.EXPORT_EMPTY: everyMap.get("YEAR").toString();String tableName = everyMap.get("TABLE_NAME") == null ? EquipmentComputeConstants.EXPORT_EMPTY: everyMap.get("TABLE_NAME").toString();String deviceName = everyMap.get("DEVICE_NAME") == null ? EquipmentComputeConstants.EXPORT_EMPTY: everyMap.get("DEVICE_NAME").toString();String equipmentNo = everyMap.get("EQUIPMENT_NO") == null ? EquipmentComputeConstants.EXPORT_EMPTY: everyMap.get("EQUIPMENT_NO").toString();String name = everyMap.get("DEVICE_NAME") == null ? EquipmentComputeConstants.EXPORT_EMPTY: everyMap.get("DEVICE_NAME").toString();String dept = everyMap.get("APPLY_DEPARTMENT") == null ? EquipmentComputeConstants.EXPORT_EMPTY: everyMap.get("APPLY_DEPARTMENT").toString();String evaluate = everyMap.get("EVALUATE") == null ? EquipmentComputeConstants.EXPORT_EMPTY: everyMap.get("EVALUATE").toString();String presentation = everyMap.get("ANALYSIS") == null ? EquipmentComputeConstants.EXPORT_EMPTY: everyMap.get("ANALYSIS").toString();/* 模板文本替换 */Map<String, Object> data = new HashMap<String, Object>(16);data.put("year", year);data.put("name", name);data.put("dept", dept);data.put("usage_situation", evaluate);data.put("presentation", presentation);
// 拼接文件名StringBuilder fileName = new StringBuilder();fileName.append(year);fileName.append(deviceName);fileName.append(tableName);fileName.append("(");fileName.append(equipmentNo);fileName.append(")");fileName.append(".docx");StringBuilder path = new StringBuilder();path.append(templates);path.append("/EquipmentPerformanceAnalysisTemplate4.docx");ExportUtil.exportWord(path.toString(), annualAeportPath, fileName.toString(), data, request, response);}
Map<String, Object> everyMap 为 要替换的导出数据 Map<String, Object> data 中的 键 为模板文档中的对应变量
ExportUtil.exportWord(path.toString(), annualAeportPath, fileName.toString(), data, request, response);
方法参数说明:第一个是路径,第二个是服务器或本地临时文件路径(导出文件位置),第三个是导出文件名(批量执行,文件名一致会覆盖)
8.替换后执行浏览器压缩导出
/* zip打包导出 */ZipExportUtil.zipExport(annualAeportPath, response);/* 删除临时文件 */DelAllFileUtil.delAllFile(annualAeportPath);
9.测试结果
--------------------------------------------------------------------------------------------------
补充文件删除工具类:DelAllFileUtil
package com.***.util;import java.io.File;/*** 删除服务器文件工具*/
public class DelAllFileUtil {/*** 删除文件夹及子文件** @param path 文件夹绝对路径* @return*/public static boolean delAllFile(String path) {boolean flag = false;File file = new File(path);if (!file.exists()) {return flag;}if (!file.isDirectory()) {return flag;}String[] tempList = file.list();File temp = null;for (int i = 0; i < tempList.length; i++) {if (path.endsWith(File.separator)) {temp = new File(path + tempList[i]);} else {temp = new File(path + File.separator + tempList[i]);}if (temp.isFile()) {temp.delete();}if (temp.isDirectory()) {delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件delFolder(path + "/" + tempList[i]);// 再删除空文件夹flag = true;}}return flag;}/*** 删除文件夹** @param folderPath 文件夹绝对路径*/public static void delFolder(String folderPath) {try {delAllFile(folderPath); // 删除完里面所有内容String filePath = folderPath;filePath = filePath.toString();File myFilePath = new File(filePath);myFilePath.delete(); // 删除空文件夹} catch (Exception e) {e.printStackTrace();}}
}
java实现word批量多模版(浏览器zip压缩导出)相关推荐
- java实现word下载及打包成zip下载(单个文件、多个文件)
最近,本人需求将实现word下载以及打包成zip进行下载(单个文件.多个文件)将最近自己学习到的知识点分享给大家 1.实现word模板(三个步骤,最终需要的是upload.ftl) 大家可以参考这篇文 ...
- java 解压缩 工具类_Java实现的zip压缩及解压缩工具类示例
本文实例讲述了Java实现的zip压缩及解压缩工具类.分享给大家供大家参考,具体如下: import java.io.BufferedInputStream; import java.io.Buffe ...
- springboot+hutool批量生成二维码压缩导出
文章目录 1.引入依赖 2.测试编码 3.批量生成 4.解析excel 5.批量图片压缩 6.上传excel直接将输出流转成压缩包 1.引入依赖 <!-- 生成二维码依赖--><de ...
- 更改完善后的导出实现(使用FreeMarker导出Word文档,在浏览器实现的导出下载,和上一篇导出主要是代码的更改,流程无变化)
一.添加maven依赖,导入FreeMarker所需要的jar包 <dependency><groupId>org.freemarker</groupId>< ...
- 实战:JS批量打包下载图片--(zip压缩)
1.下载两个插件 npm i -s jszip file-saver 2.封装函数如下: // 在JS文件中引入这两个插件 import JSZip from 'jszip' import FileS ...
- Java ZIP压缩输入输出流
ZIP是一种较为常见的压缩形式,在Java中要想实现ZIP的压缩需要导入java.util.zip包,可以使用此包中的ZipFile.ZipOutputStream.ZipInputStream.Zi ...
- zip压缩打包文件下载
引用的下文没有考虑中文的问题,是指zip压缩文件中每个文件的中文名称的问题,我们需要一个jar包 ant.jar,该jar包在apache-ant-1.9.7-bin.zip 中 下载资源:htt ...
- 【java】 文件批量下载并压缩为zip压缩包
[java] 文件批量下载并压缩为zip压缩包 java常用的压缩技术 java中常见实现压缩与解压 业务场景 代码实现 注意点 java常用的压缩技术 常见的压缩格式有很多种,例如:zip.rar. ...
- java批量下载文件为zip包
批量下载文件为zip包的工具类 package com.meeno.trainsys.util;import javax.servlet.http.HttpServletRequest; import ...
最新文章
- 服务器查看gpu状态_服务器GPU使用情况查看命令详解
- APL开发日志 -- 2013-03-02
- 【HDU 5184】 Brackets (卡特兰数)
- 【问题】HDFS中块(block)的大小为什么设置为128M?
- html/css学习笔记(一)
- jQuery——入门(二)动画
- leetcode:Longest Common Prefix【Python版】
- Python pip安装报错及解决办法:is not a supported wheel on this platform
- 汉罗塔python_基于Python的汉诺塔算法
- FeiQ(飞秋)更新用户列表的原理
- ELK安装( Elasticsearch、Logstash、Kibana)
- 最全可编辑世界地图中国地图素材
- 社会性动物1: 从众的原因,如何避免
- lisp编程 滑动轴承的auto_「autolisp」Autolisp:利用AuoCAD之Lisp编程案例之智能加工齿轮的演示程序 - seo实验室...
- CodeForces 643 D.Bearish Fanpages(set+multiset)
- Nginx-动静分离与 URLRwrite
- 多测师肖sir_高级讲师_第2个月第17讲讲解接口面试题
- 【Jekyll】使用GitHub Pages + Jekyll搭建自己的技术博客,Jekyll服务器的搭建
- 2021年国内高校教职,求职过程和结果如何?
- 大漠防检测不绑定游戏窗口调用大漠插件
热门文章
- 【go语言学习笔记】if语句以及带赋值语句的if语句
- Erlang rpc.erl 的学习记录
- 《JavaScript 20 年》中文版之创立标准
- 娃娃机微信php源码,jQuery手机微信夹娃娃机游戏代码
- 未来的互联网存储:5 大区块链存储平台深入比较
- 扩展城市信道etu模型matlab仿真,LTE-A系统中物理随机接入信道信号检测的仿真与实现...
- php 控制骰子概率,掷色子猜大小游戏(可控制概率)
- 【嵌入式基础】STM32中断及DMA通信原理编程
- 史上最精简Glide解析(一)
- 国产化下jmeter的适配