此功能中的文本替换实现不难,但是图片替换和自适用费了很大劲,主要是要知道word文档的原理,实际是一个zip 的压缩包,里面包括图片信息和xml文件等等,主要就是看xml中的对应关系,大家可以试着把word改为一个zip文件看看,废话不多说,直接上代码。

主类,测试类:

package com.test;import org.docx4j.Docx4J;
import org.docx4j.TraversalUtil;
import org.docx4j.finders.RangeFinder;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.*;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class Test {public static void main(String[] args) throws Exception {// 设置的标签ArrayList<String> bmList = new ArrayList<>();bmList.add("username");bmList.add("userage");bmList.add("usersex");// 文件源目录String srcPath = "C:\\Users\\0253000023\\Desktop\\1.docx";// 目标文件目录String destPath = "C:\\Users\\0253000023\\Desktop\\5.docx";Map<String, String> map = new HashMap<>();map.put("username","张三");map.put("usersex","男");map.put("userage","27");// 打开一个存在的wordWordprocessingMLPackage wPackage = WordprocessingMLPackage.load(new FileInputStream(srcPath));// 作word处理WordprocessingMLPackage wPackage1 = replaceContentByBookmark(wPackage, map, bmList);wPackage1.save(new File(destPath));Docx4J.toPDF(wPackage1,new FileOutputStream(new File("C:\\Users\\0253000023\\Desktop\\5.pdf")));}public static  WordprocessingMLPackage  replaceContentByBookmark(WordprocessingMLPackage wPackage, Map<String, String> map, ArrayList<String> bmList)  {try {// 提取正文MainDocumentPart main = wPackage.getMainDocumentPart();Document doc = main.getContents();Body body = doc.getBody();// 获取段落List<Object> paragraphs  = body.getContent();// 提取书签并获取书签的游标RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");new TraversalUtil(paragraphs, rt);// 遍历书签for (CTBookmark bm : rt.getStarts()) {// 替换文本内容for (String bmName: bmList) {if (bm.getName().equals(bmName)){Tool.replaceText(bm, map.get(bm.getName()));}}// 替换imageif (bm.getName().equals("userimg")){Tool.addImage(wPackage, bm, "C:\\Users\\0253000023\\Desktop\\4.jpg");}// 替换imageif (bm.getName().equals("userimg2")){Tool.addImage(wPackage, bm, "C:\\Users\\0253000023\\Desktop\\333.jpg");}}} catch (Exception e){// handle exception}return  wPackage;}}

工具类,重点在这里

package com.test;import org.apache.commons.io.IOUtils;
import org.docx4j.Docx4J;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.dml.Graphic;
import org.docx4j.dml.GraphicData;
import org.docx4j.dml.picture.Pic;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFont;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.wml.*;import javax.xml.bind.JAXBElement;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** 模板word内容替换工具类*/
public class Tool {/*** 在标签处插入替换内容** @param bm* @param wPackage* @param object* @throws Exception*/public static void replaceText(CTBookmark bm, Object object) throws Exception {if (object == null) {return;}if (bm.getName() == null){return;}String value = object.toString();try {List<Object> theList = null;ParaRPr rpr = null;if (bm.getParent() instanceof P) {PPr pprTemp = ((P) (bm.getParent())).getPPr();if (pprTemp == null) {rpr = null;} else {rpr = ((P) (bm.getParent())).getPPr().getRPr();}theList = ((ContentAccessor) (bm.getParent())).getContent();} else {return;}int rangeStart = -1;int rangeEnd = -1;int i = 0;for (Object ox : theList) {Object listEntry = XmlUtils.unwrap(ox);if (listEntry.equals(bm)) {if (((CTBookmark) listEntry).getName() != null) {rangeStart = i + 1;}} else if (listEntry instanceof CTMarkupRange) {if (((CTMarkupRange) listEntry).getId().equals(bm.getId())) {rangeEnd = i - 1;break;}}i++;}int x = i - 1;for (int j = x; j >= rangeStart; j--) {theList.remove(j);}ObjectFactory factory = Context.getWmlObjectFactory();org.docx4j.wml.R run = factory.createR();org.docx4j.wml.Text t = factory.createText();t.setValue(value);run.getContent().add(t);theList.add(rangeStart, run);} catch (ClassCastException cce) {}}/*** 替换image* @param wPackage* @param bm* @param file*/public static void addImage(WordprocessingMLPackage wPackage, CTBookmark bm, String file){// 新增imageObjectFactory factory = Context.getWmlObjectFactory();P p = (P) (bm.getParent());R run = factory.createR();byte[] bytes ;Long newCx = 0L;Long newCy = 0L;String newRelId = null;try {bytes = IOUtils.toByteArray(new FileInputStream(file));BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wPackage,bytes);Inline newInline = imagePart.createImageInline(null, null, 0, 1, false,0);// 获取CX 、CYnewCx = newInline.getExtent().getCx();newCy = newInline.getExtent().getCy();// 获取relIdGraphic newg = newInline.getGraphic();GraphicData graphicdata = newg.getGraphicData();Object o = graphicdata.getAny().get(0);Pic pic = (Pic)XmlUtils.unwrap(o);newRelId = pic.getBlipFill().getBlip().getEmbed();} catch (Exception e) {e.printStackTrace();}// 获取模板图片的CX 、CY 、relIdObject parent = (P) bm.getParent();List<Object> rList = getAllElementFromObject(parent, R.class);for (Object robj: rList){if (robj instanceof R){R r = (R) robj;List<Object> drawList = getAllElementFromObject(r, Drawing.class);for (Object dobj: drawList){if (dobj instanceof Drawing){Drawing d = (Drawing) dobj;Inline inline = (Inline)d.getAnchorOrInline().get(0);// 获取CX 、CYLong cx = inline.getExtent().getCx();Long cy = inline.getExtent().getCy();// 获取relIdGraphic g = inline.getGraphic();GraphicData graphicdata = g.getGraphicData();Object o = graphicdata.getAny().get(0);Pic pic = (Pic)XmlUtils.unwrap(o);String relId = pic.getBlipFill().getBlip().getEmbed();// 替换relIdpic.getBlipFill().getBlip().setEmbed(newRelId);// 处理CX、CYMap<String,Long> map = dealCxy(cx, cy, newCx, newCy);// 更改cx、cyinline.getExtent().setCx(map.get("setCx"));inline.getExtent().setCy(map.get("setCy"));}}}}}/*** 处理图片适应大小* @param cx* @param cy* @param newCx* @param newCy*/public static Map<String, Long> dealCxy(Long cx, Long cy, Long newCx, Long newCy){Map<String, Long> map = new HashMap<>();Long setCx;Long setCy;if (newCx > cx){if (newCy <= cy){setCx = cx;setCy = newCy/(newCx/cx);} else {if ((newCx/cx) > (newCy/cy)){setCx = cx;setCy = newCy/(newCx/cx);} else {setCy = cy;setCx = newCx/(newCy/cy);}}} else {   // newCx < cxif (newCy > cy) {setCx = cx;setCy = newCy * (cx/newCx);} else {if ((cx/newCx) > (cy/newCy)) {setCx = cx;setCy = newCy *(cx/newCx);} else {setCy = cy;setCx = newCy * (cy/newCy);}}}map.put("setCx",setCx);map.put("setCy",setCy);return map;}/*** 得到指定类型的元素* @param obj* @param toSearch* @return*/public static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {List<Object> result = new ArrayList<>();if (obj instanceof JAXBElement)obj = ((JAXBElement<?>) obj).getValue();if (obj.getClass().equals(toSearch))result.add(obj);else if (obj instanceof ContentAccessor) {List<?> children = ((ContentAccessor) obj).getContent();for (Object child : children) {result.addAll(getAllElementFromObject(child, toSearch));}}return result;}/*** word 转换 pdf (实际是没有用到的)* @param docxPath* @param pdfPath* @throws Exception*/public static void convertDocxToPDF(String docxPath, String pdfPath) throws Exception {OutputStream os = null;try {WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(new File(docxPath));Mapper fontMapper = new IdentityPlusMapper();fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));fontMapper.put("隶书", PhysicalFonts.get("LiSu"));mlPackage.setFontMapper(fontMapper);os = new java.io.FileOutputStream(pdfPath);FOSettings foSettings = Docx4J.createFOSettings();foSettings.setWmlPackage(mlPackage);Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);}catch(Exception ex){ex.printStackTrace();}finally {IOUtils.closeQuietly(os);}}/*** 下载PDF文件(实际是没有用到的)* @param wordMLPackage* @param os* @throws Exception*/public  void pdfFile(WordprocessingMLPackage wordMLPackage,OutputStream os) throws Exception {String regex = null;Mapper fontMapper = new IdentityPlusMapper();wordMLPackage.setFontMapper(fontMapper);PhysicalFont font = PhysicalFonts.get("Arial Unicode MS");String directory = "D:\\upload\\pdf";String fileName = "OUT_ConvertInXHTMLURL.pdf";File f = new File(directory,fileName);if(f.exists()) {// 文件已经存在,输出文件的相关信息System.out.println(f.getAbsolutePath());System.out.println(f.getName());System.out.println(f.length());} else {//  先创建文件所在的目录f.getParentFile().mkdirs();}File file = new File(directory+"/"+fileName);OutputStream os34 = new java.io.FileOutputStream(file);Docx4J.toPDF(wordMLPackage, os34);os.flush();os.close();wordMLPackage = null;}}

使用docx4j根据书签自动替换word中的文本和图片,图片自适应大小相关推荐

  1. 批量自动替换word中的文字

    from docx import Document import xlrd #定义一个方法用来替换 def change_test(old_test,new_test): #替换所有的段落 all_p ...

  2. java实现for文件删除_Java 添加、删除、替换、格式化Word中的文本的步骤详解(基于Spire.Cloud.SDK for Java)...

    Spire.Cloud.SDK for Java提供了TextRangesApi接口可通过addTextRange()添加文本.deleteTextRange()删除文本.updateTextRang ...

  3. Word控件Spire.Doc 【文本】教程(14) ;如何用图片替换Word中的文字

    在 Spire.Doc 的教程部分,我们介绍了"用 C# 中的表格替换 Word 中的文本"和"用 C# 中的文本替换 Word 中的图像"的简单方法.有时,我 ...

  4. Using POI to replace elements in WORD(.docx/.doc)(使用POI替换word中的特定字符/文字)【改进】...

    上一篇文章可能有点bug,这个是改进 package com.xfzx.test.POI.main;import java.io.File; import java.io.FileInputStrea ...

  5. python读取word文件并替换部分文字_python实现替换word中的关键文字(使用通配符)...

    环境:Python3.6 本文主要是通过win32com操作word,对word中进行常用的操作.本文以替换为例,讲解一下如何使用Python在word中使用"通配符模式"(类似于 ...

  6. POI替换word中的指定文字(包含表格,表格中有回车)

    网上可以找到很多POI替换Word中指定文字的代码,然而基本上都没有对文档中的表格中包含的段落(回车)进行处理.自己写了,代码记录如下: /** * *@templetStream 文档的输入流 *@ ...

  7. python 替换文本 通配符_python实现替换word中的关键文字(使用通配符)

    环境:Python3.6 本文主要是通过win32com操作word,对word中进行常用的操作.本文以替换为例,讲解一下如何使用Python在word中使用"通配符模式"(类似于 ...

  8. html 图片转换成word,在Word中通过把编辑的图片另存为HTML文件实现转换图片

    Word是文字处理软件,它和图片格式转换根本就占不上边啊?如何能转换图片呢?在正常情况下Acdsee确实是图片浏览.格式转换的好工具,但是如果你的机器里没有安装它,却要进行图片转换怎么呢?这样我们的W ...

  9. 文本上划线_如何在Word中对文本进行上划线

    文本上划线 Underlining is a common task in Word, and easily done, but what if you need to overline (also ...

最新文章

  1. LeetCode(1)Two Sum
  2. Red Hat Linux 5.2 14T大文件系统 分区过程
  3. dnf强化卷代码_DNF:夏日套时装礼盒开服竟卖八千万金币,500万捡漏到黄金书
  4. media player怎么不能拖进度图mp4_榜样力量丨科研路上有难题,学长教你怎么解
  5. .NET Core使用NLog通过Kafka实现日志收集
  6. Java并发编程实战~软件事务内存
  7. SQL SERVER 2005 显示行号
  8. 谷歌官方推出 TensorFlow 中文视频:机器学习从零到一(系列之二)
  9. 动态规划与数学方程法解决楼层扔鸡蛋问题
  10. 9款优秀的代码比对工具
  11. 2017会考计算机知识点,高中物理会考知识点考点归纳2017
  12. 自建ipa下载服务器的方法(最简单,使用在线工具)
  13. 程序的优化 文字的减法
  14. easyexcel一个很棒的Excel解析工具
  15. 怎么批量设置EDIUS中的图片持续时间
  16. mac键盘上符号的快捷键_Mac键盘符号实际上是什么意思?
  17. 二叉树前序遍历Java
  18. rvm的安装, 使用rvm, 安装ruby, 以及gem的使用
  19. 炫“库“行动—人大金仓有奖征文——金仓数据库安装教程
  20. 论文阅读笔记《Fine-tuning Deep Neural Networks in Continuous Learning Scenarios》

热门文章

  1. Matlab 绘制箭头函数
  2. 对于运行ASP.NET程序时,提示:无法启动程序“http://localhost:XXXXX/Default.aspx”。的解决办法
  3. 【Axure】Axure RP 9下载、安装、授权、汉化
  4. 系统集成项目管理工程师:第22章职业道德规范学习笔记
  5. 亚马逊asin关键词排名追踪_亚马逊卖家快速提升关键词排名,这几点需要重视...
  6. win10系统下安装informix 12版本安装和简单使用注意
  7. javascript学习指南——先导片
  8. cruise软件模型,混动仿真模型,cruise与simulink联合仿真模型
  9. FFA-Net:文章理解与代码注释
  10. Stata数据处理:各种求和方式一览