用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压缩导出)相关推荐

  1. java实现word下载及打包成zip下载(单个文件、多个文件)

    最近,本人需求将实现word下载以及打包成zip进行下载(单个文件.多个文件)将最近自己学习到的知识点分享给大家 1.实现word模板(三个步骤,最终需要的是upload.ftl) 大家可以参考这篇文 ...

  2. java 解压缩 工具类_Java实现的zip压缩及解压缩工具类示例

    本文实例讲述了Java实现的zip压缩及解压缩工具类.分享给大家供大家参考,具体如下: import java.io.BufferedInputStream; import java.io.Buffe ...

  3. springboot+hutool批量生成二维码压缩导出

    文章目录 1.引入依赖 2.测试编码 3.批量生成 4.解析excel 5.批量图片压缩 6.上传excel直接将输出流转成压缩包 1.引入依赖 <!-- 生成二维码依赖--><de ...

  4. 更改完善后的导出实现(使用FreeMarker导出Word文档,在浏览器实现的导出下载,和上一篇导出主要是代码的更改,流程无变化)

    一.添加maven依赖,导入FreeMarker所需要的jar包 <dependency><groupId>org.freemarker</groupId>< ...

  5. 实战:JS批量打包下载图片--(zip压缩)

    1.下载两个插件 npm i -s jszip file-saver 2.封装函数如下: // 在JS文件中引入这两个插件 import JSZip from 'jszip' import FileS ...

  6. Java ZIP压缩输入输出流

    ZIP是一种较为常见的压缩形式,在Java中要想实现ZIP的压缩需要导入java.util.zip包,可以使用此包中的ZipFile.ZipOutputStream.ZipInputStream.Zi ...

  7. zip压缩打包文件下载

    引用的下文没有考虑中文的问题,是指zip压缩文件中每个文件的中文名称的问题,我们需要一个jar包  ant.jar,该jar包在apache-ant-1.9.7-bin.zip 中  下载资源:htt ...

  8. 【java】 文件批量下载并压缩为zip压缩包

    [java] 文件批量下载并压缩为zip压缩包 java常用的压缩技术 java中常见实现压缩与解压 业务场景 代码实现 注意点 java常用的压缩技术 常见的压缩格式有很多种,例如:zip.rar. ...

  9. java批量下载文件为zip包

    批量下载文件为zip包的工具类 package com.meeno.trainsys.util;import javax.servlet.http.HttpServletRequest; import ...

最新文章

  1. 服务器查看gpu状态_服务器GPU使用情况查看命令详解
  2. APL开发日志 -- 2013-03-02
  3. 【HDU 5184】 Brackets (卡特兰数)
  4. 【问题】HDFS中块(block)的大小为什么设置为128M?
  5. html/css学习笔记(一)
  6. jQuery——入门(二)动画
  7. leetcode:Longest Common Prefix【Python版】
  8. Python pip安装报错及解决办法:is not a supported wheel on this platform
  9. 汉罗塔python_基于Python的汉诺塔算法
  10. FeiQ(飞秋)更新用户列表的原理
  11. ELK安装( Elasticsearch、Logstash、Kibana)
  12. 最全可编辑世界地图中国地图素材
  13. 社会性动物1: 从众的原因,如何避免
  14. lisp编程 滑动轴承的auto_「autolisp」Autolisp:利用AuoCAD之Lisp编程案例之智能加工齿轮的演示程序 - seo实验室...
  15. CodeForces 643 D.Bearish Fanpages(set+multiset)
  16. Nginx-动静分离与 URLRwrite
  17. 多测师肖sir_高级讲师_第2个月第17讲讲解接口面试题
  18. 【Jekyll】使用GitHub Pages + Jekyll搭建自己的技术博客,Jekyll服务器的搭建
  19. 2021年国内高校教职,求职过程和结果如何?
  20. 大漠防检测不绑定游戏窗口调用大漠插件

热门文章

  1. 【go语言学习笔记】if语句以及带赋值语句的if语句
  2. Erlang rpc.erl 的学习记录
  3. 《JavaScript 20 年》中文版之创立标准
  4. 娃娃机微信php源码,jQuery手机微信夹娃娃机游戏代码
  5. 未来的互联网存储:5 大区块链存储平台深入比较
  6. 扩展城市信道etu模型matlab仿真,LTE-A系统中物理随机接入信道信号检测的仿真与实现...
  7. php 控制骰子概率,掷色子猜大小游戏(可控制概率)
  8. 【嵌入式基础】STM32中断及DMA通信原理编程
  9. 史上最精简Glide解析(一)
  10. 国产化下jmeter的适配