【Apache POI】Java Web根据模板导出word文件
最近工作中遇到一个需求:根据word模板文档导出word文件。
查阅了一些资料,发现Apache POI可以实现文档读写的功能,于是就研究了一下,总结如下:
Apache-POI在线Javadoc:http://tool.oschina.net/apidocs/apidoc?api=apache-POI
官方网站:http://poi.apache.org/
POI详细介绍:
Apache POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目。目前POI已经有了Ruby版本。结构:
HSSF - 提供读写Microsoft Excel XLS格式档案的功能。
XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。
HWPF - 提供读写Microsoft Word DOC97格式档案的功能。
XWPF - 提供读写Microsoft Word DOC2003格式档案的功能。
HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
HDGF - 提供读Microsoft Visio格式档案的功能。
HPBF - 提供读Microsoft Publisher格式档案的功能。
HSMF - 提供读Microsoft Outlook格式档案的功能。
Java Web根据模板导出word文件
基本实现原理:
1、首先,将模板中需要用到的参数组装为一个Map集合;
2、然后读取模板文档,使用POI API解析文档输入流;
3、将Map集合中的内容写入模板文档。
功能使用了springMVC的相关功能,点击导出按钮,调用前台JS,JS代码根据springMVC的注解功能实现对后台导出方法的调用,controller控制类如下:
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import com.lmb.word.util.XwpfUtil;/*** Java Web根据模板导出word文件(spring MVC controller实现)* @author lmb* @date 2017-3-14**/
public class ExportControl {private static final Logger logger = Logger.getLogger(ExportControl.class);/*** 导出word* @param param* @param request* @param response*/public void exportWord(String param,HttpServletRequest request,HttpServletResponse response){logger.debug("导出word文件开始>>>>>>>>>>>>>");Map<String,Object> params = packageObject();/*params格式如下:{${interfacetype11}=ecsClient, ${time1}=2017/03/14 14:36:15,${code2}=4114030153, ${interfacetype10}=ecsClient, ${percentagecode10}=6.43%, ${percentagecode11}=17.74%, ${text9}=返回欠费不能办理, ${percentagecode8}=67.71%, ${mainpercentage1}=98.57%, ${code1}=2107000024, ${svcname8}=GUSERBRAND, ${text8}=2G用户主产品不在省份上报的列表中, ${start1}=2017-03-13 , ${svcname9}=GUSERBRAND, ${percentagecode2}=18.06%, ${text10}=用户状态不处于有效期, ${percentagecode1}=78.39%, ${text2}=4114030153, ${interfacename1}=cu.tran.fusionflowquery, ${svctext1}=3G流量包查询, ${svctext2}=3G流量包查询, ${svctext8}=用户品牌查询,${svctext9}=用户品牌查询,${svctext10}=用户品牌查询, ${svctext11}=用户品牌查询,${text11}=4114030153, ${interfacetype8}=ecsClient, ${svcname11}=GUSERBRAND, ${end1}=2017-03-13 , ${interfacename10}=cu.tran.fusionflowquery, ${interfacetype9}=ecsClient, ${svcname10}=GUSERBRAND, ${text1}=2G用户主产品不在省份上报的列表中, ${interfacename2}=cu.tran.fusionflowquery, ${interfacename11}=cu.tran.fusionflowquery, ${code8}=2107000024, ${namelist1}= 1、3G流量包查询:24.26% 2、用户品牌查询:37.52%, ${date1}=2017-03-13 , ${code9}=2114000061, ${code11}=4114030153, ${svcname1}=G3GFLUX, ${code10}=2114000066, ${svcname2}=G3GFLUX, ${interfacetype1}=ecsClient, ${percentagecode9}=4.12%, ${interfacetype2}=ecsClient, ${interfacename9}=cu.tran.fusionflowquery, ${indexprovince1}=陕西, ${interfacename8}=cu.tran.fusionflowquery}*/XwpfUtil xwpfUtil = new XwpfUtil();//读入word模板InputStream is = getClass().getClassLoader().getResourceAsStream("wordTemplate.docx");xwpfUtil.exportWord(params,is,request,response,xwpfUtil);logger.debug("导出word文件完成>>>>>>>>>>>>>");}/*** 组装word文档中需要显示数据的集合* @return*/public Map<String, Object> packageObject() {Map<String,Object> params = new HashMap<String,Object>();params.put("${date1}", "");//数据查询时间params.put("${time1}", "");//生成文件时间params.put("${indexprovince1}", "");//省份//报告时间范围params.put("${mainpercentage1}", "");//省份成功率params.put("${start1}", "");//开始时间params.put("${end1}", "");params.put("${namelist1}", "");// ……return params;}
}
控制器中用到的导出方法工具类:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;/*** 根据模板导出word文件工具类* @author lmb* @date 2017-3-14*/
public class XwpfUtil {private static final Logger logger = Logger.getLogger(XwpfUtil.class);/*** 导出word文件* @param params* @param is* @param request* @param response* @param xwpfUtil*/public void exportWord(Map<String, Object> params, InputStream is,HttpServletRequest request, HttpServletResponse response,XwpfUtil xwpfUtil) {XWPFDocument doc = new XWPFDocument();xwpfUtil.replaceInPara(doc,params);xwpfUtil.replaceInTable(doc,params);try {OutputStream os = response.getOutputStream();response.setContentType("application/vnd.ms-excel");response.setHeader("Content-disposition","attachment;filename=exportWord.docx");//文件名中文不显示//把构造好的文档写入输出流doc.write(os);//关闭流xwpfUtil.close(os);xwpfUtil.close(is);os.flush();os.close();} catch (IOException e) {logger.error("文件导出错误");}}/*** 替换word模板文档段落中的变量* @param doc 要替换的文档* @param params 参数*/public void replaceInPara(XWPFDocument doc, Map<String, Object> params) {Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();XWPFParagraph para;while(iterator.hasNext()){para = iterator.next();this.replaceInPara(para,params);}}/*** 替换段落中的变量* @param para 要替换的段落* @param params 替换参数*/public void replaceInPara(XWPFParagraph para, Map<String, Object> params) {List<XWPFRun> runs;if (((Matcher) this.matcher(para.getParagraphText())).find()) {runs = para.getRuns();int start = -1;int end = -1;String str = "";for (int i = 0; i < runs.size(); i++) {XWPFRun run = runs.get(i);String runText = run.toString().trim();if (StringUtils.isNotBlank(runText)&&'$' == runText.charAt(0)&&'{' == runText.charAt(1)) {start = i;}if (StringUtils.isNotBlank(runText)&&(start != -1)) {str += runText;}if (StringUtils.isNotBlank(runText)&&'}' == runText.charAt(runText.length() - 1)) {if (start != -1) {end = i;break;}}}for (int i = start; i <= end; i++) {para.removeRun(i);i--;end--;System.out.println("remove i="+i);}if(StringUtils.isBlank(str)){String temp = para.getParagraphText();str = temp.trim().substring(temp.indexOf("${"),temp.indexOf("}")+1);}for (String key : params.keySet()) {if (str.equals(key)) {para.createRun().setText(String.valueOf(params.get(key)) );break;}}}}/*** 替换word模板文档表格中的变量* @param doc 要替换的文档* @param params 参数*/public void replaceInTable(XWPFDocument doc, Map<String, Object> params) {Iterator<XWPFTable> iterator = doc.getTablesIterator();XWPFTable table;List<XWPFTableRow> rows;List<XWPFTableCell> cells;List<XWPFParagraph> paras;while (iterator.hasNext()) {table = iterator.next();rows = table.getRows();for (XWPFTableRow row : rows) {cells = row.getTableCells();for (XWPFTableCell cell : cells) {paras = cell.getParagraphs();for (XWPFParagraph para : paras) {this.replaceInPara(para, params);}}}}}/*** 正则匹配字符串* @param paragraphText* @return*/public Object matcher(String str) {Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(str);return null;}/*** 关闭输入流* @param is*/public void close(InputStream is) {if (is != null) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}/*** 关闭输出流* @param is*/public void close(OutputStream os) {if (os != null) {try {os.close();} catch (IOException e) {e.printStackTrace();}}}
}
【Apache POI】Java Web根据模板导出word文件相关推荐
- POI根据模板导出word文件,以及word转PDF,PDF转图片再插入PDF中(防止PDF被修改)
POI操作word和PDF POI根据模板导出word文件 word转PDF PDF转图片再插入PDF中(防止PDF被修改) POI根据模板导出word文件 一.制作word模版,${xxxx}是一会 ...
- Springboot--使用POI,根据word模板导出word文件
需求:根据一个word模板,在程序中替换模板中的参数,然后根据这个模板导出word文件. 引入POI对word操作的依赖: <dependency><groupId>org.a ...
- java利用poi模板导出word文件
注意: doc文件的读取,需要导入poi-scratchpad包: docx文件读取,需要导入poi-ooxml包: 一.引入pom <dependency><groupId> ...
- java通过ftl模板导出word最详细教程
百度云链接 链接: https://pan.baidu.com/s/1OEzvsFSqAelstDtu2mo5xw 提取码: fdhq https://pan.baidu.com/s/1OEzvsFS ...
- 利用word的freemarker模板导出word文件
前端请求 var url = window.webApi.business.exportYearWord; jQuery('<form action="' + url + '" ...
- freemarker html 换行,java使用freemarker模板导出word,合并单元格,单元格内换行
之前使用[XWPFDocument][]动态写入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument对于动态生成行效果不是很好,所 ...
- java使用freemarker模板导出word,合并单元格,单元格内换行
之前使用XWPFDocument动态写入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument对于动态生成行效果不是很好,所以使用f ...
- Java web/springboot上传word/doc/docx文档(含图片)与HTML富文本导入/导出互相转换解析!附项目源码
测试效果 先看下效果 文档内容如下: 上传 上传docx文档 查看解析内容 <html><head><style>p{margin-top:0pt;margin-b ...
- sql2java-excel(二):基于apache poi实现数据库表的导出的spring web支持
sql2java是我几年年开始写的一个sql2java是一个轻量级数据库(SQL)访问代码(java)生成器.这几年一直在根据工作需要维护升级,最近的项目中需要对数据库的记录提供导出excel的功能. ...
最新文章
- 模拟二:STEMA 考试选择题模拟练习试卷(中级组) 及答案 + 解题后期更新
- 【Leetcode】大神总结的链表常见面试问题
- javascript高级程序设计 学习笔记 第五章 上
- .NET Core微服务 权限系统+工作流(二)工作流系统
- python db文件_python中查看.db文件中表格的名字及表格中的字段操作
- 【干货】私域电商崛起:2021见实私域流量白皮书高清6月版.pdf(附下载链接)...
- 将Docker image push 到azure
- Java基础语法一 数据类型运算符
- tomcat,httpd 日志格式说明
- 项目需求讨论--可能是用InputFilter来做的最好的金额限制
- TM1640数码管控制器移植STM32HAL库
- 中国不是没有根服务器吗?《流浪地球2》的根服务器怎么在北京?
- Java服务端集成环信im即时通讯
- 2.1.3 毫米波雷达
- 距离感应器下的休眠唤醒机制实现
- charles抓手机端的包(android手机)
- 2022年5月11日-12日 复盘计划
- python 实现根据问题在文章中找到答案
- 不伤眼睛的电脑背景颜色
- ID选择器和类选择器的合理使用