最近多了一个需求,需要对word模板内容进行替换,一开始用的是word03版的,替换起来比较简单,主要是range对像替换非常方便,而且可以保留替换前的字体样式。

  InputStream is = new FileInputStream(srcFath);
OutputStream os = new FileOutputStream(tempFile);
XWPFDocument doc = new XWPFDocument(is);
Range range = doc.getRange();
range.replaceText("${name}","aaa");
doc.write(os);
is.close();
os.flush();
os.close();

最后看到word里包含了图片,需要同时保存一张png图片,对于jpg的图片是可以的,但是png的显示不出来,改为操作2007的文档,07版的没有了Range,使用XWPFParagraph和XWPFRun来操作。XWPFParagraph表示段落,有的word里有表格内容,需要使用XWPFTable来处理,与段落区分开来处理。

 private  void replaceText(XWPFDocument doc, Map<String, Object> params) {
Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
XWPFParagraph para;
while (iterator.hasNext()) {
para = iterator.next();
this.replaceInPara(para, params);
}
}
private void replaceText(XWPFParagraph para, Map<String, Object> params) {
List<XWPFRun> runs;
Matcher matcher;
if (matcher(para.getParagraphText()).find()) {
runs = para.getRuns();
for (int i=0; i<runs.size(); i++) {
XWPFRun run = runs.get(i);
String runText = run.toString();
matcher = matcher(runText);
if (matcher.find()) {
while ((matcher = matcher(runText)).find()) {
runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
}
para.removeRun(i);
//重新插入run里内容格式可能与原来模板的格式不一致
para.insertNewRun(i).setText(runText);
}
}
}
}
    

  private Matcher matcher(String str) {
    Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(str);
    return matcher;
  }

 

再次处理替换内容的格式问题,通过一个临时文件先保存替换模板变量后的文件,在与之前模板文档一起通过正则匹配出变量位置,由于替换变量时先删除再插入,所以位置是一致的。

private  void setStyle(XWPFDocument doc,XWPFDocument tempdoc, Map<String, Object> params) {
Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
Iterator<XWPFParagraph> iterator2 = tempdoc.getParagraphsIterator();
XWPFParagraph para ;
XWPFParagraph para2;
while (iterator.hasNext()) {
para = iterator.next();
para2 = iterator2.next();
this.styleInPara(para,para2, params);
}
}
private void setStyle(XWPFParagraph para, XWPFParagraph para2,Map<String, Object> params) {
List<XWPFRun> runs;
List<XWPFRun> runs2;
Matcher matcher;
if (matcher(para.getParagraphText()).find()) {
runs = para.getRuns();
runs2 = para2.getRuns();
for (int i=0; i<runs.size(); i++) {
XWPFRun run = runs.get(i);
XWPFRun run2 = runs2.get(i);
String runText = run.toString();
matcher = matcher(runText);
if (matcher.find()) {
//按模板文件格式设置格式
run2.getCTR().setRPr(run.getCTR().getRPr());
}
}
}
}

按照原模板格式设置好替换后格式后显示正常。

ps:XWPFRun表示有相同属性的一段文本,所以模板里变量内容需要从左到右的顺序写,${userName},如果先写${},再添加内容,会拆分成几部分,不能正常使用

poi 针对word模板内容替换的更多相关文章

  1. 使用java Apache poi 根据word模板生成word报表

    项目开发过程中,客户提出一堆导出报表的需求,需要导出word格式,页眉还需要加上客户公司的logo,试了几种方案,最后选择了用 Apache poi 加上自定义标签的方式实现. 目前功能还比较简单,一 ...

  2. 利用POI 技术动态替换word模板内容

    项目中需要实现一个功能,动态替换给定模板里面的内容,生成word文档提供下载功能. 中间解决了问题有: 1.页眉的文档logo图片解决,刚开始的时候,HWPFDocument 对象无法读取图片对象(已 ...

  3. poi导出word模板项目实例(一个文件)

    在页面上填写值,然后导出到word模板中,并把页面上的值带到模板中,也就是导出word文档,提前有word 的模板形式, 1.jsp 页面   <table class="formTa ...

  4. POI往word模板中写入数据

    转: POI往word模板中写入数据 2018年03月24日 16:00:22 乄阿斗同學 阅读数:2977  版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn ...

  5. C# 操作word 模板 值 替换

    1.引用 aspose.words   dll 2.word 使用doc 3.给word 模板中添加要替换位置的 书签 .引用 aspose.words dll .word 使用doc .给word ...

  6. poi读写word模板 / java生成word文档

    有一word文档表格 形如: 姓名 ${name} 电话 ${tel} 从数据库读取记录替换上述变量 import java.io.FileOutputStream; import java.util ...

  7. ConterReplaceBehavior.class.php模板内容替换,如__PUBLIC__

    ConterReplaceBehavior.class.php查找 __PUBLIC__ protected function templateContentReplace($content) { / ...

  8. .NET使用NPOI读取Word模板并替换关键字并下载

    NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 ...

  9. poi读取word的内容

    pache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能. 1.读取word 2003及word 2007需要的 ...

随机推荐

  1. ES6特性之:参数默认值

    作为一个开发者,跟进行业步伐是非常需要的,不能躺在现有的知识和经验温床上做美梦.JavaScript的ES2015标准(即我们说的ES6)在2016年已经被广泛应用了,还没开始使用的朋友,赶紧来磨一下 ...

  2. Docker容器利用weave实现跨主机互联

    Docker容器利用weave实现跨主机互联 环境: 实现目的:实现主机A中容器1与主机B中容器1的网络互联 主机A步骤: ①下载复制weave二进制执行文件(需要internet)[root@192 ...

  3. RF(自定义关键字)

    1.在 D:\work_software\python\Lib\site-packages 文件夹下, 新建 python package 包 ,例如我的是 TestLibrary 建好后的完整路径: ...

  4. Regex 正则表达式入门

    0,什么是正则表达式 正则表达式(Regular Expression简写为Regex),又称为规则表达式,它是一种强大的文本匹配模式,其用于在字符串中查找匹配符合特定规则的子串. 正则表达式是独立于 ...

  5. 【原创】Linux Mutex机制分析

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  6. 集训模拟赛-1-T2

    好了不要在铺垫了直接整吧就 题目拿来!!!!!!! 倒水 (water) (256MB,1s) [问题描述] 你有一个水桶(记为 0),两个杯子(记为 1,2).水桶中的水量无限,容量也无限.1 号杯 ...

  7. 如何选择IO调度器

    概述 由于对multi-quque的IO调度算法不太熟悉,为了避免误人子弟,本文暂时只会介绍如何选择single-queue的IO调度算法.等将来对multi-queue有充分认识后再补充. 如果不清 ...

  8. Day_08【面向对象】扩展案例2_测试旧手机新手机类,并给新手机实现玩游戏功能

    分析以下需求,并用代码实现 1.定义手机类 行为: 打电话,发短信 2.定义接口IPlay 行为: 玩游戏 3.定义旧手机类继承手机类 行为: 继承父类的行为 4.定义新手机继承手机类实现IPlay接 ...

  9. sql server 百万级数据库优化方案

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  10. C#MVC通过AJAX调用API方法进行上传下载

    //这是写的一个类,具体是上传图片的上传和下载 public class FileResult    {        public int Code { get; set; }        pub ...