Word模板替换
package com.sisa.auweb.tools.bookmarkprocess; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.impl.piccolo.io.FileFormatException; import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import static feign.Util.toByteArray; /**
* Created by clyan on 2019/7/2 15:15.
*/
public class Word2007 {
private String wordPath = "";
private String writeFilePath = "";
private Object obj = null;
Map<String, Object> map = new HashMap<String, Object>(); /*
path:文件路径
dataSource/objectMap:数据源.
*/
public Word2007(String path, String newFilePath, Object dataSource, Map<String, Object> objectMap) throws IOException { File file = new File(path); if (file.exists() == false || file.isFile() == false) {
throw new FileNotFoundException("文件不存在");
} InputStream is = new FileInputStream(file);
byte[] bytes = new byte[10]; if (is.read(bytes, 0, bytes.length) == -1) {
is.close();
throw new FileFormatException("文件格式错误,本文件只能解析docx文件");
}
String fileCode = bytesToHexString(bytes).toLowerCase(); if (fileCode.length() > 1) {
if (fileCode.equals("504b0304140006000800") == false) {
is.close();
throw new FileFormatException("文件格式错误,本文件只能解析docx文件");
}
}
is.close(); wordPath = path;
writeFilePath = newFilePath;
obj = dataSource; if (dataSource != null) {
pickFields();
} else {
this.map = objectMap;
}
} public void parseTemplate() { try {
InputStream is = new FileInputStream(wordPath);
XWPFDocument doc = new XWPFDocument(OPCPackage.open(is));
List<XWPFParagraph> list = doc.getParagraphs(); for (int i = 0; i < list.size(); i++) {
XWPFParagraph graph = list.get(i);
replaceInXWPFParagraph(graph, map);
}
replaceTables(map, doc);
OutputStream os = new FileOutputStream(writeFilePath);
doc.write(os);
os.flush();
close(os);
close(is); } catch (Exception ex) {
System.out.print(ex.getStackTrace());
}
} private void replaceInXWPFParagraph(XWPFParagraph para, Map<String, Object> params) { List<XWPFRun> runs = null;
Matcher matcher;
String runText = ""; if (matcher(para.getParagraphText()).find()) {
runs = para.getRuns();
if (runs.size() > 0) {
int j = runs.size();
for (int i = 0; i < j; i++) {
XWPFRun run = runs.get(i);
String i1 = run.toString();
runText += i1;
}
}
int replaceCount = runText.trim().split("\\$").length - 1;
matcher = matcher(runText);
if (matcher.find()) {
while ((matcher = matcher(runText)).find()) {
runText = String.valueOf(params.get(matcher.group(1)));
}
//数据源不存在时跳过,以便检查
if (runText.equals("null")) {
runText = "";
}
if (runs.size() > 0) {
boolean handler = false;
for (int i = 0; i < runs.size(); i++) { XWPFRun run = runs.get(i);
String temp = run.toString(); if (handler == false && temp.indexOf("$") >= 0) {
handler = true;
}
if (handler == true) {
if (temp.equals("$") || temp.indexOf("$") == 0) {
if (temp.indexOf("}") >= 0) {
run.setText(runText, 0);
handler = false;
//一行有多个${情况
replaceCount--;
if (replaceCount > 0) {
runText = "";
int j = runs.size();
for (int x = 0; x < j; x++) {
XWPFRun run1 = runs.get(x);
String i1 = run1.toString();
runText += i1;
}
matcher = matcher(runText);
if (matcher.find()) {
while ((matcher = matcher(runText)).find()) {
runText = String.valueOf(params.get(matcher.group(1)));
}
}
}
} else {
run.setText("", 0);
}
continue;
}
if (temp.indexOf("}") < 0) {
run.setText("", 0);
continue;
}
if (temp.indexOf("}") >= 0) {
run.setText(runText, 0);
handler = false;
//一行有多个${情况
replaceCount--;
if (replaceCount > 0) {
runText = "";
int j = runs.size();
for (int x = 0; x < j; x++) {
XWPFRun run1 = runs.get(x);
String i1 = run1.toString();
runText += i1;
} matcher = matcher(runText);
if (matcher.find()) {
while ((matcher = matcher(runText)).find()) {
runText = String.valueOf(params.get(matcher.group(1)));
}
}
}
}
}
}
}
}
}
} private void pickFields() {
Class dataClass = (Class) obj.getClass();
Field[] fs = dataClass.getDeclaredFields();
for (int i = 0; i < fs.length; i++) {
Field f = fs[i];
f.setAccessible(true);
Object val = new Object();
try {
val = f.get(obj);
map.put(f.getName(), val);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
} private byte[] generalFileContent() throws IOException {
InputStream is = new FileInputStream(writeFilePath);
byte[] data = toByteArray(is);
is.close();
return data;
} private void close(InputStream is) {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} private void close(OutputStream os) {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} private String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder();
if (null == src || src.length < 1)
return null;
for (byte b : src) {
int v = b & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2)
stringBuilder.append(0);
stringBuilder.append(hv);
}
return stringBuilder.toString();
} private static Matcher matcher(String str) {
Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
return matcher;
} private void replaceTable(Map<String, Object> params, XWPFTable table) {
int count = table.getNumberOfRows();
for (int i = 0; i < count; i++) {
XWPFTableRow row = table.getRow(i);
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
List<XWPFParagraph> list = cell.getParagraphs();
for (int j = 0; j < list.size(); j++) {
replaceInXWPFParagraph(list.get(j), params);
}
}
}
} private void replaceTables(Map<String, Object> params, XWPFDocument document) {
Iterator<XWPFTable> itTable = document.getTablesIterator();
while (itTable.hasNext()) {
XWPFTable table = itTable.next();
replaceTable(params, table);
}
}
}
Word模板替换的更多相关文章
- C#读取Word模板替换相应的字符串(标签)生成新的Word
在平常工作中,生成word的方式主要是C#读取html的模板文件处理之后保存为.doc文件,这样的好处是方便,快捷,能满足大部分的需求.不过有些特殊的需求并不能满足,如要生成的Word为一个表格,只是 ...
- 利用POI 技术动态替换word模板内容
项目中需要实现一个功能,动态替换给定模板里面的内容,生成word文档提供下载功能. 中间解决了问题有: 1.页眉的文档logo图片解决,刚开始的时候,HWPFDocument 对象无法读取图片对象(已 ...
- POI Word 模板 文字 图片 替换
实验环境:POI3.7+Word2007 Word模板: 替换后效果: 代码: 1.入口文件 public class Test { public static void main(String[] ...
- POI不同版本替换Word模板时的问题
一.问题描述 通过POI,把Word中的占位符替换为实际的值,以生成复杂结构的业务报告. 在POI 3.9上,功能正常.由于某些原因升级到POI 3.10.1后,项目组反馈说Word模板出错,无法生成 ...
- word模板导出的几种方式:第一种:占位符替换模板导出(只适用于word中含有表格形式的)
1.占位符替换模板导出(只适用于word中含有表格形式的): /// <summary> /// 使用替换模板进行到处word文件 /// </summary> public ...
- JAVA Freemarker + Word 模板 生成 Word 文档 (普通的变量替换,数据的循环,表格数据的循环,以及图片的东替换)
1,最近有个需求,动态生成 Word 文当并供前端下载,网上找了一下,发现基本都是用 word 生成 xml 然后用模板替换变量的方式 1.1,这种方式虽然可行,但是生成的 xml 是在是太乱了,整理 ...
- C# 操作word 模板 值 替换
1.引用 aspose.words dll 2.word 使用doc 3.给word 模板中添加要替换位置的 书签 .引用 aspose.words dll .word 使用doc .给word ...
- tp5 使用phpword 替换word模板并利用com组件转换pdf
tp5 使用phpword 替换word模板并利用com组件转换pdf 一.首先composer安装PHPword,就不多说了 二.然后是把模板中要替换的部分用变量代替 三.把原始的模板文件放入项 ...
- poi 针对word模板内容替换
最近多了一个需求,需要对word模板内容进行替换,一开始用的是word03版的,替换起来比较简单,主要是range对像替换非常方便,而且可以保留替换前的字体样式. InputStream is = n ...
随机推荐
- python jdbc连接 oracle 数据库
准备写一个代码生成的小工具自己用,第一步,连接数据库 import jaydebeapi url = 'jdbc:oracle:thin:@192.168.0.13:1521:JGD' user = ...
- 修改mysql的binlog的位置
最近项目上装的mysql服务,分配的磁盘空间太小了,导致binlog两天时间就能打满,这里记录下处理方式 mysql的binlog日志是一个很重要的日志,以事件形式记录了所有的DDL和DML(除了数据 ...
- Mandelbrot集合及其渲染
什么是Mandelbrot集合? Mandelbrot集合是在复数平面上组成分形的点的集合,它正是以数学家Mandelbrot命名. Mandelbrot集合可以用复二次多项式 \[ f_c(z)=z ...
- 树形DP Choosing Capital for Treeland
给你一棵有向树,需要选定一个点为capital,满足翻转边数最小 思路:先求出1为capital 的答案,然后向下更新孩子节点 dp[i]=dp[i-1]+judge(i); #include< ...
- Hihocoder1046K个串(线段树)(待解决)
描述 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次). 兔子们想知道,在这个数字序列所有连续 ...
- 基于tornado python pandas和bootstrap上传组件的mongodb数据添加工具
总体思路:基于bootstrap4的前端页面上传组件,把excel文件上传至服务器,并利用python pandas读取里面的数据形成字典列表 通过pymongo 接口把数据插入或追加到mongodb ...
- DevExpress实现为TextEdit设置水印文字的方法
设置水印与消除水印 public static void SetWatermark(TextEdit textEdit, string watermark) { textEdit.Properties ...
- JavaScript基础——JavaScript入门(笔记)
JavaScript入门(笔记) JavaScript是一种轻量级.解释型的Web开发语言,该语言系统不是很庞杂,简单易学.由于所有现代浏览器都已嵌入JavaScript引擎,JavaScript源代 ...
- sh_02_del关键字
sh_02_del关键字 name_list = ["张三", "李四", "王五"] # (知道)使用 del 关键字(delete)删除 ...
- idea2018.3.6安装与破解教程(亲测可用、破解到2100年)
最近,帮室友进行idea安装,之前自己安装借鉴的博客已404,在网上找了好几个都无效,想着总结一份备用. 此博客是又找了一台电脑,边安装边写的. 目录 (已安装好的,可以直接看idea2018.3.6 ...