public class WordTest2 {
public static void main(String[] args) { /** 此Map存放动态替换的内容,key-Word中定义的变量,value-要替换的内容 **/
Map map = Maps.newHashMap();
map.put("CL_XT_zlContractNo", "55555556444444888544");
map.put("LOAN_memberName", "小赵");
map.put("LOAN_certNo", "1234568524545");
map.put("LOAN_address", "重庆市沙坪坝积极");
map.put("LOAN_mobileNo", "110110110");
map.put("LOAN_memberName", "张三");
map.put("LOAN_certNo", "510254545488445");
map.put("LOAN_address", "四川省锦州达到");
map.put("LOAN_mobileNo", "023-5854555");
map.put("GUARANTEE_guaPersonName", "李四"); /** 此Map存放动态 批量生产Word中表格的内容 **/
List<String[]> tableDataList = new ArrayList<String[]>();
tableDataList.add(new String[] { "应还款日", "应还本金", "应付利息", "应还(付)总额" });
tableDataList.add(new String[] { "2018-01-01", "23", "0.2", "111" });
tableDataList.add(new String[] { "2018-01-02", "233", "0.2", "123" });
tableDataList.add(new String[] { "2018-01-03", "2333", "0.2", "321" });
tableDataList.add(new String[] { "2018-01-04", "2333", "0.2", "321" });
tableDataList.add(new String[] { "2018-01-05", "2333", "0.2", "321" });
tableDataList.add(new String[] { "2018-01-06", "2333", "0.2", "321" });
tableDataList.add(new String[] { "2018-01-07", "2333", "0.2", "321" }); String localTemplateTmpPath = "E:\\new\\TestWord.docx";
String newContractLocalPath = "E:\\new\\TestWord2.docx"; WordUtil.changWord(localTemplateTmpPath, newContractLocalPath, map, tableDataList); }
}

核心代码:

public class WordUtil {
/**
* 根据模板生成新word文档
* 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
*
* @param inputUrl 模板存放地址
* @param outputUrl 新文档存放地址
* @param textMap 需要替换的信息集合
* @param tableList 需要插入的表格信息集合
* @return 成功返回true, 失败返回false
*/
public static boolean changWord(String inputUrl, String outputUrl, Map<String, String> textMap, List<String[]> tableList) { // 模板转换默认成功
boolean changeFlag = true;
try {
// 获取docx解析对象
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
// 解析替换文本段落对象
WordUtil.changeText(document, textMap);
// 解析替换表格对象
WordUtil.changeTable2(document, textMap, tableList); // 生成新的word
File file = new File(outputUrl);
FileOutputStream stream = new FileOutputStream(file);
document.write(stream);
stream.close();
} catch (Exception e) {
e.printStackTrace();
changeFlag = false;
}
return changeFlag;
} /**
* 替换段落文本
*
* @param document docx解析对象
* @param textMap 需要替换的信息集合
*/
public static void changeText(XWPFDocument document, Map<String, String> textMap) {
// 获取段落集合
List<XWPFParagraph> paragraphs = document.getParagraphs();
Set<String> keySet = textMap.keySet();
changeParagraph(textMap, paragraphs, keySet);
// 获取表格对象集合
List<XWPFTable> tables = document.getTables();
for (XWPFTable table : tables) {
List<XWPFParagraph> paras;
int rcount = table.getNumberOfRows();
for (int j = 0; j < rcount; j++) {
XWPFTableRow row = table.getRow(j);
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
paras = cell.getParagraphs();
changeParagraph(textMap, paras, keySet);
}
}
}
} private static void changeParagraph(Map<String, String> textMap, List<XWPFParagraph> paragraphs, Set<String> keySet) {
reBuildParagraph2(textMap, paragraphs, keySet);
} private static void reBuildParagraph2(Map<String, String> textMap, List<XWPFParagraph> paragraphs, Set<String> keySet) {
for (XWPFParagraph paragraph : paragraphs) { /**
* 此处For循环的思路:
* 将原来的XWPFParagraph中的多个XWPFRun转化成一个XWPFRun,如此做的好处是不会改变原Word的格式
* 如果直接通过XWPFParagraph获取文本内容,再进行赋值,会改变原有的Word的格式
*/
String paragraphText = paragraph.getText();
for (String key : keySet) {
String regex = "\\$\\{" + key + "\\}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(paragraphText);
while (matcher.find()) {
List<XWPFRun> runs = paragraph.getRuns();
StringBuffer sb = new StringBuffer("");
for (XWPFRun run : runs) {
int testPosition = run.getTextPosition();
String text = run.getText(testPosition);
if (StringUtils.isNotBlank(text)) {
sb.append(text);
}
}
String newText = sb.toString();
int runLength = runs.size();
for (int i = runLength - 1; i >= 0; i--) {
if (i == 0) {
runs.get(i).setText(newText, 0);
} else {
paragraph.removeRun(i);
if (runLength > 1) {
runLength = runLength - 1;
}
}
}
}
} /**
* 此处的思路:
* 转换后的XWPFParagraph只会存在一个XWPFRun,并保留了原Word的格式
* 将XWPFRun按照正则进行截取成多个XWPFRun;(具体实现是,将原有的XWPFRun拆分成多个,删除原有的XWPFRun,再将拆分后的XWPFRun创建到原XWPFParagraph)
* 如此做的目的是:对Word中定义的变量(例如:${abc})进行格式操作,比如添加下划线
*/
List<XWPFRun> runs = paragraph.getRuns();
List<String> list = Lists.newArrayList();
if (runs.size() > 0) {
XWPFRun run = runs.get(0);
int testPosition = run.getTextPosition();
String text = run.getText(testPosition);
String regex2 = "\\$\\{\\w*\\}";
String[] strs = text.split(regex2);
String totalStr = "";
if (strs.length == 1) {
if (text.contains("${")) {
list.add(strs[0]);
String regexStr = text.substring(strs[0].length());
list.add(regexStr);
paragraph.removeRun(0);
}
} else {
if (strs.length > 1) {
for (int i = 0; i < strs.length; i++) {
String splitStr = strs[i];
totalStr = totalStr + splitStr;
String regexStr = "";
list.add(strs[i]);
if (i + 1 < strs.length) {
regexStr = text.substring(totalStr.length(), text.indexOf(strs[i + 1], totalStr.length()));
}
list.add(regexStr);
totalStr = totalStr + regexStr;
}
paragraph.removeRun(0);
}
} for (int i = 0; i < list.size(); i++) {
XWPFRun newRun = paragraph.createRun();
newRun.setText(list.get(i));
}
/**
* 此处的思路:
* 获取转换后的XWPFParagraph上的多个XWPFRun
* 将XWPFRun按照正则进行文本内容替换(动态替换)
*/
List<XWPFRun> newRuns = paragraph.getRuns();
for (XWPFRun newRun : newRuns) {
int position = newRun.getTextPosition();
String newText = newRun.getText(position);
for (String key : keySet) {
String regex = "\\$\\{" + key + "\\}";
Pattern pattern = Pattern.compile(regex);
if (null != pattern && StringUtil.isNotBlank(newText)) {
Matcher matcher = pattern.matcher(newText);
while (matcher.find()) {
String replaceText = newText.replaceAll(regex, textMap.get(key));
replaceText = " " + replaceText + " ";
newRun.setText(replaceText, 0);
newRun.setUnderline(UnderlinePatterns.SINGLE);
}
}
}
}
} }
} /**
* 替换表格对象方法
*
* @param document docx解析对象
* @param textMap 需要替换的信息集合
* @param tableList 需要插入的表格信息集合
*/
public static void changeTable2(XWPFDocument document, Map<String, String> textMap, List<String[]> tableList) {
// 获取表格对象集合
List<XWPFTable> tables = document.getTables();
for (int i = 0; i < tables.size(); i++) {
// 只处理行数大于等于2的表格,且不循环表头
XWPFTable table = tables.get(i); // 表头
String[] tableHeads = tableList.get(0);
String tableHead = "";
for (int a = 0; a < tableHeads.length; a++) {
tableHead = tableHead + tableHeads[a];
}
String templateTableHead = table.getText().replaceAll("\t", "").replaceAll("\n", "");
System.out.println(templateTableHead.contains(tableHead));
if (templateTableHead.contains(tableHead)) {
// 创建20行7列
int rows = tableList.size();
int cols = tableList.get(0).length; for (int l = 1; l < rows; l++) {
XWPFTableRow targetRow = table.insertNewTableRow(l + 1);
targetRow.getCtRow().setTrPr(table.getRow(l).getCtRow().getTrPr());
List<XWPFTableCell> cellList = table.getRow(l).getTableCells();
XWPFTableCell targetCell = null;
for (XWPFTableCell sourceCell : cellList) {
targetCell = targetRow.addNewTableCell();
targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
targetCell.getParagraphs().get(0).getCTP().setPPr(sourceCell.getParagraphs().get(0).getCTP().getPPr());
}
XWPFTableRow row = table.getRow(l);
for (int j = 0; j < cols; j++) {
// 设置单元格内容
row.getCell(j).setText(tableList.get(l)[j]);
}
}
}
}
} }

Word动态替换文本的更多相关文章

  1. C# 在word中查找及替换文本

    C# 在word中查找及替换文本 在处理word文档时,很多人都会用到查找和替换功能.尤其是在处理庞大的word文档的时候,Microsoft word的查找替换功能就变得尤为重要,它不仅能让我们轻易 ...

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

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

  3. C# 替换Word文本—— 用文档、图片、表格替换文本

    编辑文档时,对一些需要修改的字符或段落可以通过查找替换的方式,快速地更改.在C# 在word中查找及替换文本一文中,主要介绍了在Word中以文本替换文本的方法,在本篇文章中,将介绍如何用一篇Word文 ...

  4. Java Word中的文本、图片替换功能

    Word中的替换功能以查找指定文本然后替换为新的文本,可单个替换或全部替换.以下将要介绍的内容,除常见的以文本替换文本外,还将介绍使用不同对象进行替换的方法,具体可包括: 1. 指定字符串内容替换文本 ...

  5. Java 添加、删除、替换、格式化Word中的文本(基于Spire.Cloud.SDK for Java)

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

  6. Java 程序动态替换 docx 模板中定制值的实现例子

    项目系统中打印功能,导出 word 文档功能是挺常用的,本文介绍自定文档模板,程序实现模板内容中值替代的功能. 模板文件 template.docx ​ 执行 main public static v ...

  7. Word 查找替换高级玩法系列之 -- 把论文中的缩写词快速变成目录下边的注释表

    1. 前言 问题:Word写论文如何把文中的缩写快速转换成注释表? 原来样子: 想要的样子: 2. 步骤 使用查找替换高级用法,替换缩写顺序 选中所有文字 打开查找替换对话框,输入以下表达式: 替换后 ...

  8. 【实践】js 如何实现动态添加文本节点

    对于我这个js 小白来说 今天鼓起勇气做起了邮箱认证这个特效 但是这次不是想说如何实现这这个特效而是想记录一下特效当中的某个部分 那就是向元素节点动态添加文本节点 百度了一下动态添加文本节点的方式 是 ...

  9. SSRS动态设置文本框属性

    SSRS可以通过表达式动态设置文本框所有的属性,比如字体,字号,是否加粗,如下图所示: 汉字和数字英文字母占用的空间不一样,一个汉字占用两个数字和英文字母的空间,VB里有LENB取得字节数,这SSRS ...

随机推荐

  1. 搭建selenium + Python环境的总结:

    安装Python+Selenium 写博客是一个不错的选择,首先,是担心自己忘掉,其次,可以供大家做一个参考: 其实,这是自己第一次搭建Python环境(之前用了一周的Idle),还是比较容易的吧: ...

  2. 1-15-2-RAID1 企业级RAID磁盘阵列的搭建(RAID1、RAID5、RAID10)

    大纲: 1.创建RAID1 2.创建RAID5 3.创建RAID10 =============================== 1.创建RAID1 RAID1原理:需要两块或以上磁盘,可添加热备 ...

  3. Python之坐标轴刻度细化、坐标轴设置、标题图例添加

    学习python中matplotlib绘图设置坐标轴刻度.文本 http://www.jb51.net/article/134638.htm Python绘图 https://www.cnblogs. ...

  4. 关于mybatis mapper.xml中的if判断

    场景: 页面上有搜索框进行调节查询,不同搜索框中的内容可以为空. 过程: 点击搜索,前端把参数传给后台,这是后台要把为空的参数过滤掉. 做法: 通常我们在dao层即mapper.xml中进行过滤判断操 ...

  5. Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache

    1.事件描述:CentOS7下使用tree命令,发现该命令没有被安装,在安装的过程中发现yum报错 1 2 3 4 5 [root@openstack-01 ~]# tree -d bash: tre ...

  6. table 转实体

    public class Table2Entity<T> where T : class,new() { public static List<T> GetEntitys(Da ...

  7. python 黑客书籍 ——扫描+暴力破解

    https://legacy.gitbook.com/book/germey/net-security/details 网络安全 介绍 构建一个端口扫描器 利用Pexpect模拟SSH连接 利用Pxs ...

  8. 转:Hive SQL的编译过程

    Hive是基于Hadoop的一个数据仓库系统,在各大公司都有广泛的应用.美团数据仓库也是基于Hive搭建,每天执行近万次的Hive ETL计算流程,负责每天数百GB的数据存储和分析.Hive的稳定性和 ...

  9. python:小乌龟turtle

    turtle的意思是乌龟,也是python中自带的图形函数,使用turtle的方法也很形象,就好像在画布上有一个小乌龟(在画布上是一个箭头),然后你可以让它动来动去,它经过的地方就被留下了记号. 例如 ...

  10. 013——数组(十三) array_push array_rand array_reverse

    <?php /* 数组 array_push array_rand array_reverse */ //array_push()在数组的末端,增加一个或多个元素,入栈 /*$array = a ...