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. Oracle Procedure记录

    1.定义 所谓存储过程(Procedure),就是一组用于完成特定数据库功能的SQL语句集,该SQL语句集经过 编译后存储在数据库系统中.在使用时候,用户通过指定已经定义的存储过程名字并给出相应的存储 ...

  2. Java 9的JDK中值得期待的:不仅仅是模块化

    在多次延期后,Java 9将于9月21日以Java开发工具包9的形式出现,这是自2014年3月以来,Java标准版的第一次重大升级.官方列出了JDK 9的大约90个新特性,模块化是最主要的一个.将Ja ...

  3. 15 个有趣的 JS 和 CSS 库

    开发者们,一起来看看有木有你需要的前端库. 1. DisplayJS DisplayJS 是一个帮助你渲染 DOM 的简易框架.使用它,你可以更容易地将 JS 变量遍历到特定的 HTML 元素中,类似 ...

  4. clipboard.js使用方法

    HTML data-clipboard-action=“ copy ”  或者“cut” data-clipboard-target="#domName" data-clipboa ...

  5. Highcharts 时间序列,可缩放的图表;Highcharts X 轴翻转曲线图;Highcharts 带标记曲线图

    Highcharts 时间序列,可缩放的图表 配置 图表 配置可缩放图表. chart.zoomType 指定了用户可以拖放的尺寸,用户可以通过拖动鼠标来放大,可能值是x,y或xy: var char ...

  6. HighCharts 特性;Highcharts 环境配置

    Highcharts Highcharts 是一个用纯JavaScript编写的一个图表库. Highcharts 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表 Highchart ...

  7. 新添加的DOM节点如何实现动画效果

    如何给新添加的DOM节点加动画效果 最近碰到项目中,在DOM节点中,添加新的 html 后 要有动画效果,一直没能很好地理解,尝试了各种方式,终于找出来了 简化版结构 代码如下 使用jq1.9以上版本 ...

  8. CF445

    题解: xjb乱判断一下就可以了 代码: #include<bits/stdc++.h> using namespace std; typedef long long ll; int n, ...

  9. QT出现 Cannot create children for a parent that is in a different thread 的解决方法:

    timer = new Timer(this);改成 timer = new Timer();就可以了. 因为你timer是属于主线程的,尽量不要在非主线程里创建新的对象并指定其对象为主线程内的对象, ...

  10. jmeter测试FTP

    1.下载并运行FTP服务器软件:Quick Easy FTP Server V4.0.0.exe 2.点击右上角的绿色按钮,开启服务器,直到中间的红色按钮亮起 3.在账户管理处可以管理账号信息(用户名 ...