Java使用word模板导出word
1.创建一个空的springboot工程,引入jar包
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version>
</dependency>
maven工程只需引入2个jar,系统会自动添加其他相关jar包
2.工具类一
package com.example.demo.util;import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;import java.io.IOException;
import java.io.InputStream;public class CustomXWPFDocument extends XWPFDocument {public CustomXWPFDocument(InputStream in) throws IOException {super(in);}public CustomXWPFDocument(OPCPackage pkg) throws IOException {super(pkg);}public void createPicture(String blipId,int id, int width, int height, XWPFParagraph paragraph){final int EMU = 9525;width *= EMU;height *= EMU;//给段落插入图片CTInline inline = paragraph.createRun().getCTR().addNewDrawing().addNewInline();String picXml = "" +"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +" <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +" <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +" <pic:nvPicPr>" +" <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" +" <pic:cNvPicPr/>" +" </pic:nvPicPr>" +" <pic:blipFill>" +" <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +" <a:stretch>" +" <a:fillRect/>" +" </a:stretch>" +" </pic:blipFill>" +" <pic:spPr>" +" <a:xfrm>" +" <a:off x=\"0\" y=\"0\"/>" +" <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +" </a:xfrm>" +" <a:prstGeom prst=\"rect\">" +" <a:avLst/>" +" </a:prstGeom>" +" </pic:spPr>" +" </pic:pic>" +" </a:graphicData>" +"</a:graphic>";XmlToken xmlToken = null;try{xmlToken = XmlToken.Factory.parse(picXml);}catch(XmlException xe){xe.printStackTrace();}inline.set(xmlToken);inline.setDistT(0);inline.setDistB(0);inline.setDistL(0);inline.setDistR(0);CTPositiveSize2D extent = inline.addNewExtent();extent.setCx(width);extent.setCy(height);CTNonVisualDrawingProps docPr = inline.addNewDocPr();docPr.setId(id);docPr.setName("Picture " + id);docPr.setDescr("Generated");}
}
3.工具类二
package com.example.demo.util;import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.*;import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class WordUtil {/*** 替换段落里面的变量 ** @param doc 要替换的文档 * @param params 参数 * @throws FileNotFoundException* @throws InvalidFormatException*/public void replaceInPara(CustomXWPFDocument doc, Map<String, Object> params) throws InvalidFormatException, FileNotFoundException {Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();XWPFParagraph para;while (iterator.hasNext()) {para = iterator.next();this.replaceInPara(para, params,doc);}}/*** 替换段落里面的变量 ** @param para 要替换的段落 * @param params 参数 * @throws FileNotFoundException* @throws InvalidFormatException*/public void replaceInPara(XWPFParagraph para, Map<String, Object> params, CustomXWPFDocument doc) throws InvalidFormatException, FileNotFoundException {List<XWPFRun> runs;Matcher matcher;if (this.matcher(para.getParagraphText()).find()) {runs = para.getRuns();int start = -1;int end = -1;String str = "";String text= "";for (int i = 0; i < runs.size(); i++) {text += runs.get(i).toString();}for (int i = 0; i < runs.size(); i++) {XWPFRun run = runs.get(i);System.out.println("------>>>>>>>>>" + text);if (text.contains("$")) {start = text.indexOf("$");}if ((start != -1)) {str += text.substring(text.indexOf("$"), text.length()).trim();String paraList=runs.toString();System.out.println("未删除前"+paraList);Object[] runArr = runs.toArray();int size=runs.size();int $Index=0;for (int j = 0; j < runArr.length; j++) {if (runArr[j].toString().contains("$")) {$Index=j;break;}}int startIn=$Index;while (startIn<runs.size()) {para.removeRun(startIn);System.out.println("删除中"+para.getRuns());}System.out.println("删除后"+para.getRuns());}if ('}' == text.charAt(text.length() - 1)) {if (start != -1) {end = text.length() - 1;break;}}}System.out.println("start--->"+start);System.out.println("end--->"+end);System.out.println("str---->>>" + str);for (String key : params.keySet()) {if (str.equals(key)) {if(str.indexOf("@")==-1){String value= params.get(key).toString();para.createRun().setText(value);break;}else{String value= params.get(key).toString();int length = para.getRuns().size();if (length > 0) {for (int i = (length - 1); i >= 0; i--) {para.removeRun(i);}}String blipId = doc.addPictureData(new FileInputStream(new File(value)), CustomXWPFDocument.PICTURE_TYPE_PNG);doc.createPicture(blipId,doc.getNextPicNameNumber(CustomXWPFDocument.PICTURE_TYPE_PNG), 550, 250,para);break;}}}}}/*** 替换表格里面的变量 ** @param doc 要替换的文档 * @param params 参数 * @throws FileNotFoundException* @throws InvalidFormatException*/public void replaceInTable(CustomXWPFDocument doc, Map<String, Object> params) throws InvalidFormatException, FileNotFoundException {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,doc);}}}}}/*** 正则匹配字符串 ** @param str* @return*/private Matcher matcher(String str) {Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(str);return matcher;}/*** 关闭输入流 ** @param is*/public void close(InputStream is) {if (is != null) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}/*** 关闭输出流 ** @param os*/public void close(OutputStream os) {if (os != null) {try {os.close();} catch (IOException e) {e.printStackTrace();}}}
}
4.测试代码
package com.example.demo.controller;import ch.qos.logback.core.util.FileUtil;
import com.example.demo.util.CustomXWPFDocument;
import com.example.demo.util.WordUtil;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;@RestController
public class ExportWordController {@RequestMapping(value = "/export")public void export(HttpServletRequest request,HttpServletResponse response) throws Exception {Map<String, Object> params = new HashMap<>();params.put("${Name}", "Fisher3652");params.put("${Sex}", "男");params.put("${Desc}", "18岁\tJAVA开发\r熟悉JVM基本原理");params.put("${@Pic}", "C:\\Users\\111\\Pictures\\123.jpg");//spring项目使用此方法获取文件路径
// String fileNameInResource = request.getSession().getServletContext().getRealPath("Demo.docx");InputStream is;CustomXWPFDocument doc;//spring项目使用此方法获取创建文件
// is = new FileInputStream(new File(fileNameInResource));//springboot项目使用次方法is = FileUtil.class.getClassLoader().getResourceAsStream("static/Demo.docx");doc = new CustomXWPFDocument(is);WordUtil xwpfTUtil = new WordUtil();xwpfTUtil.replaceInPara(doc, params);xwpfTUtil.replaceInTable(doc, params);//此处不指定下载目录,默认到用户本地的下载文件下OutputStream os = response.getOutputStream();response.setContentType("application/vnd.ms-excel");SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");String fileName = sdf.format(new Date());response.setCharacterEncoding(StandardCharsets.UTF_8.name());response.setContentType("application/x-zip-compressed");response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName,"UTF-8") + ".doc");doc.write(os);xwpfTUtil.close(os);xwpfTUtil.close(is);os.flush();os.close();System.out.println("word成功生成");}
}
5.模板文件放在static目录下
6.导出结果
Java使用word模板导出word相关推荐
- 【Apache POI】Java Web根据模板导出word文件
最近工作中遇到一个需求:根据word模板文档导出word文件. 查阅了一些资料,发现Apache POI可以实现文档读写的功能,于是就研究了一下,总结如下: Apache-POI在线Javadoc:h ...
- poi-tl,根据word模板导出word(表格行循环,表格无表头的情况)
最近项目里要做一个根据客户提供的word模板导出word的功能,方法有很多,比如easyPoi(对word的支持并不是很好),freeMark(太麻烦不想研究),以及poi-tl, 最后研究了半天发现 ...
- Springboot--使用POI,根据word模板导出word文件
需求:根据一个word模板,在程序中替换模板中的参数,然后根据这个模板导出word文件. 引入POI对word操作的依赖: <dependency><groupId>org.a ...
- freemarker html 换行,java使用freemarker模板导出word,合并单元格,单元格内换行
之前使用[XWPFDocument][]动态写入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument对于动态生成行效果不是很好,所 ...
- java使用freemarker模板导出word,合并单元格,单元格内换行
之前使用XWPFDocument动态写入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument对于动态生成行效果不是很好,所以使用f ...
- java通过ftl模板导出word最详细教程
百度云链接 链接: https://pan.baidu.com/s/1OEzvsFSqAelstDtu2mo5xw 提取码: fdhq https://pan.baidu.com/s/1OEzvsFS ...
- java 导出word,java根据提供word模板导出word文档
本文主要讲解,利用poi-tl在word中动态生成表格行,进行文字.图片填充.一共提供了两种方式,1.基于本地文件 2.基于网络文件 本文讲解思路,1.先看示例,2. 示例对应的代码展示 3. 基本概 ...
- 基于Easypoi+jfree,使用SpringBoot架构,Java编程实现word模板导出Word报表
目录 1.项目目录结构 2.pom.xml添加的依赖 3.编写jfreeutil工具类 4.编写wordutil工具类 5.编写word模板 7.运行效果 8.复杂布局实现 8.1如何实现图片并排 S ...
- java利用poi模板导出word文件
注意: doc文件的读取,需要导入poi-scratchpad包: docx文件读取,需要导入poi-ooxml包: 一.引入pom <dependency><groupId> ...
- java根据提供word模板导出word文档
涉及主要jar包为 freemarker-2.3.10.jar,servlet-api-2.4.jar. (1)首先修改 word模板如下形式,把需要查询写入word的值用${}形式封装 (2)把 w ...
最新文章
- el表达式 java_java基础学习:JavaWeb之EL表达式
- 学生计算机屏幕坏了怎么办,如果计算机显示器的屏幕坏了怎么办?
- 快速操作Linux终端命令行的快捷键…
- python PyQt5 QLabel()(可以用来显示文字、图片或作为放置一些控件提示信息的容器)
- SpringBoot通过yml和xml文件配置日志输出
- byte[] 转化为 string 转化为汉字和字母
- JavaSE JDK搭建
- 【JeecgBoot】关于 jeecg-boot 的项目理解、使用心得和改进建议
- php小偷程序生成,php开发:php小偷程序实例代码
- viper4android 6.0脉冲,【详解】v4a音效脉冲样本
- 二次开发时,css中 @font-face 的处理方法
- 反复横跳的瞄准线!从向量计算说起!基于射线检测的实现!Cocos Creator!
- gitlab 不能启动 runsv not running
- Point Estimation
- Type A卡和Type B卡的主要区别
- [工具]更新音乐下载软件工具音乐下载网站,MP3音乐无损音乐下载器
- hot~《国家网络安全应急预案》你知道么。
- 计算机科学家尼沃思曾经提出了,2010年江苏省专转本计算机真题含答案
- mysql zimbra_zimbra备份与恢复
- P5937 [CEOI1999]Parity Game-扩展域并查集与离散化处理