这里Word模板填充功能。
有两种方式实现模板填充功能,一种是借助于Aspose工具包中的Aspose.Word工具实现,另一种是借助于Deepoove工具的poi-tl提供的模板引擎实现。
一、Deepoove方式实现
API参考:http://deepoove.com/poi-tl/
借助Deepoove工具包,可以实现自动化、便捷的模板填充操作,替换规则固定,不能根据需要自定义填充规则,有时使用起来会不太方便。
1. Deepoove引入
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.6.0-beta1</version>
</dependency>
<!-- 可能用到的Apache poi 依赖 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
2. 填充工具代码
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import java.io.*;
import java.util.Map;
/**
* Word模板填充工具
*
* @author maomaochong
* @date 2021/11/26 14:21
**/
public class WordRenderUtil {
/**
* 填充模板,并导出到输出流
*
* 填充规则:
* word中模板:{{templateField}}
* dataMap中:key为templateField(不带括号),value为任意待填充数据
*
* @param templatePath 模板路径
* @param dataMap 待填充数据集
* @param outStream 导出输出流
* @throws IOException
*/
public static void renderTemplateAndExportToStream(String templatePath, Map dataMap, OutputStream outStream) throws IOException {
XWPFTemplate xwpfTemplate = null;
InputStream inputStream = null;
try {
// 配置
Configure config = Configure.newBuilder().build();
// 读取模板到输入流
inputStream = new FileInputStream(templatePath);
// 编译模板,填充数据
xwpfTemplate = XWPFTemplate
.compile(inputStream, config)
.render(dataMap);
// 写入到输出流
xwpfTemplate.write(outStream);
} catch (IOException e) {
throw new RuntimeException("模板填充失败");
}finally {
if(xwpfTemplate != null){
xwpfTemplate.close();
}
// 关流
if (inputStream != null) {
inputStream.close();
}
}
}
/**
* 填充模板,并导出到指定文件
*
* 填充规则:
* word中模板:{{templateField}}
* dataMap中:key为templateField(不带括号),value为任意待填充数据
*
* @param templatePath 模板路径
* @param dataMap 待填充数据集
* @param destDirPath 导出目录
* @param destFileName 导出文件名
* @throws IOException
*/
public static void renderTemplateAndExportToPath(String templatePath, Map dataMap, String destDirPath, String destFileName) throws IOException {
XWPFTemplate xwpfTemplate = null;
InputStream inputStream = null;
try{
// 配置
Configure config = Configure.newBuilder().build();
// 读取模板到输入流
inputStream = new FileInputStream(templatePath);
// 编译模板,填充数据
xwpfTemplate = XWPFTemplate
.compile(inputStream, config)
.render(dataMap);
// 目标目录是否存在
File file = new File(destDirPath);
if (!file.exists()) {
file.mkdirs();
}
// 写入到文件
xwpfTemplate.writeToFile(destDirPath + File.separator + destFileName);
}catch (IOException e){
throw new RuntimeException("生成文件失败!");
}finally {
if(xwpfTemplate != null){
xwpfTemplate.close();
}
// 关流
if (inputStream != null) {
inputStream.close();
}
}
}
}
3. 测试用例
import java.io.*;
import java.util.HashMap;
/**
* @author maomaochong
* @date 2021/11/26 14:59
**/
public class Test02 {
public static void main(String[] args) {
try {
// test01();
test02();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void test01() throws Exception {
HashMap<String, String> map = new HashMap<>();
map.put("Code", "2021800001");
map.put("Creator", "小明公司");
map.put("Year", "2021");
map.put("Month", "11");
map.put("Day", "23");
map.put("ApplyNum", "2021800001");
map.put("PatentApplyNum", "2021800001");
map.put("PatentName", "小明小明");
map.put("Sltz", "\u2611");
map.put("Bltz", "\u2610");
WordRenderUtil.renderTemplateAndExportToPath(System.getProperty("user.dir") + File.separator + "template2.docx", map, System.getProperty("user.dir") + File.separator + "wordTemplate\\out", "dest.docx");
}
private static void test02() throws Exception {
HashMap<String, String> map = new HashMap<>();
map.put("Code", "2021800001");
map.put("Creator", "小明公司");
map.put("Year", "2021");
map.put("Month", "11");
map.put("Day", "23");
map.put("ApplyNum", "2021800001");
map.put("PatentApplyNum", "2021800001");
map.put("PatentName", "小明小明");
map.put("Sltz", "\u2611");
map.put("Bltz", "\u2610");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
WordRenderUtil.renderTemplateAndExportToStream(System.getProperty("user.dir") + File.separator + "template2.docx", map, byteArrayOutputStream);
}
}
4. 填充过程中可能会用到的一些特殊符号编码
参考:https://blog.csdn.net/cy_baicai/article/details/82897724
二、Aspose.Word方式实现
参考文档:https://apireference.aspose.com/words/java/com.aspose.words/package-summary
使用Aspose.Word工具来填充Word模板,同时可以使用其携带的工具实现从Word向Pdf的格式转换,比较方便,还可以根据需要自定义模板样式。
1. Aspose.Word引入
由于Aspose.Word是收费库,所以为了学习,从网上找到了绿色方法,仅供学习使用,我们要支持正版。
- 获取对应jar包
由于语雀不支持压缩包格式上传,将后缀改为了docx
,下载后将后缀改回rar
即可。
asposewordforjava15.docx
在jar包所在目录,使用如下命令将其安装到本地仓库
mvn install:install-file -Dfile=aspose-words-15.8.0-jdk16.jar -DgroupId=com.aspose -DartifactId=aspose-words -Dversion=15.8.0 -Dpackaging=jar
在pom文件里引入此依赖
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>15.8.0</version>
</dependency>
<!-- 可能会用到的Apache poi依赖 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
2. 授权文件
附件:license.xml
3. 工具类代码
import com.aspose.words.*;
//import org.apache.commons.lang.StringUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Aspose工具类
*/
public class AsposeWordsUtils {
// private static final Logger log = LoggerFactory.getLogger(AsposeWordsUtils.class);
/**
* 判断是否有授权文件 如果没有则会认为是试用版,转换的文件会有水印
*
* @return
*/
public static boolean getLicense() throws Exception {
boolean result = false;
// 指定授权文件路径
InputStream is = AsposeWordsUtils.class.getClassLoader().getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
return result;
}
/**
* doc2pdf工具
*
* @param sourcerFile 源文件
* @param targetFile 目标文件
*/
public static void doc2pdf(String sourcerFile, String targetFile) throws Exception {
if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
return;
}
long old = System.currentTimeMillis();
File file = new File(targetFile); // 新建一个空白pdf文档
FileOutputStream os = new FileOutputStream(file);
Document doc = new Document(sourcerFile); // sourcerFile是将要被转化的word文档
doc.save(os, SaveFormat.PDF); // 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
os.close();
long now = System.currentTimeMillis();
// log.info("共耗时:" + ((now - old) / 1000.0) + "秒"); //转化用时
}
/**
* 获取Word模板文档填充工具
*
*
* 填充规则:
* 模板(自定义):{{templateField}}
* 数据集:key为templateField(不带括号),value为需要填充的任意数据
*
* @param inFilePath 文档路径
* @param outFilePath 输出文档路径
* @param data 待替换的域的键值
* @param signCode 签章图片base64编码
* @return 处理结果
* @throws Exception
*/
public static Map<String, String> readwriteWord(String inFilePath, String outFilePath, Map<Object, Object> data, String signCode) throws Exception {
// 验证License 若不验证则转化出的word文档会有水印产生
if (!getLicense()) {
return null;
}
Map<String, String> map = new HashMap<>();
Document doc = null;
// 定义文档接口
doc = new Document(inFilePath);
for (Map.Entry<Object, Object> entry : data.entrySet()) {
String key = entry.getKey().toString();
Object value = entry.getValue();
if (value != null) {
Pattern p = Pattern.compile("\n");
Matcher m = p.matcher(value.toString());
int i = 0;
String replaceValue = "";
Boolean flag = false;
while (m.find()) {
// 换行处理
replaceValue = value.toString().replace(m.group(), "" + ControlChar.LINE_BREAK + "");
flag = true;
}
if (flag) {
// 要求替换的内容是完全匹配时的替换
// 可更换模板样式
doc.getRange().replace("{{" + key + "}}", replaceValue, true, false);
} else {
// 要求替换的内容是完全匹配时的替换
doc.getRange().replace("{{" + key + "}}", value.toString(), true, false);
}
}
}
if(signCode != null && !signCode.isEmpty()){
DocumentBuilder builder = new DocumentBuilder(doc);
builder.moveToMergeField("signature");
BASE64Decoder decoder = new BASE64Decoder();
byte[] imgByteArr = decoder.decodeBuffer(signCode);
for (int i = 0; i < imgByteArr.length; ++i) {
if (imgByteArr[i] < 0) {// 调整异常数据
imgByteArr[i] += 256;
}
}
builder.insertImage(imgByteArr, RelativeHorizontalPosition.RIGHT_MARGIN, -160, RelativeVerticalPosition.OUTSIDE_MARGIN, -140, 160, 160, WrapType.NONE);
}
// 生成四位随机数
Random ne = new Random();
int num = ne.nextInt(9999 - 1000 + 1) + 1000;
String random = String.valueOf(num);
String fileName = "" + System.currentTimeMillis() + random;
//替换后的Word
String docPath = outFilePath + fileName + inFilePath.substring(inFilePath.lastIndexOf("."));
//生成的PDF位置
String pdfPath = outFilePath + fileName + ".pdf";
doc.save(docPath);
File file = new File(docPath);
if (file.exists()) {
// 直接转换为word
doc2pdf(docPath, pdfPath);
map.put("pdfPath", pdfPath);
map.put("docPath", docPath);
}
return map;
}
}
4. 测试用例
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author maomaochong
* @date 2021/11/26 14:59
**/
public class Test02 {
public static void main(String[] args) {
try {
test03();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void test03() throws Exception {
Map map = new HashMap<>();
map.put("Code", "2021800001");
map.put("Creator", "小明公司");
map.put("Year", "2021");
map.put("Month", "11");
map.put("Day", "23");
map.put("ApplyNum", "2021800001");
map.put("PatentApplyNum", "2021800001");
map.put("PatentName", "小明小明");
map.put("Sltz", "\u2611");
map.put("Bltz", "\u2610");
AsposeWordsUtils.readwriteWord(System.getProperty("user.dir") + File.separator + "template2.docx", System.getProperty("user.dir") + File.separator + "wordTemplate\\out\\dest2.docx", map, null);
}
}
三、Aspose.Word动态生成Word中表格数据
直接展示多类型数据行动态生成,即两个不同类型的数据集合,在表格中动态生成的场景,单行的相对就简单一些,可以参考此种实现方式,更易处理。
1. 工具类代码
调用其中的dynamicDealTableData()
方法。
//import com.alibaba.fastjson.JSONObject;
import com.aspose.words.*;
//import org.apache.commons.lang.StringUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
import com.joezj.test.DataOne;
import com.joezj.test.DataTwo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import sun.misc.BASE64Decoder;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Aspose工具类
*/
public class AsposeWordsUtils {
// private static final Logger log = LoggerFactory.getLogger(AsposeWordsUtils.class);
/**
* 判断是否有授权文件 如果没有则会认为是试用版,转换的文件会有水印
*
* @return
*/
public static boolean getLicense() throws Exception {
boolean result = false;
// 指定授权文件路径
InputStream is = AsposeWordsUtils.class.getClassLoader().getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
return result;
}
/**
* doc2pdf工具
*
* @param sourcerFile 源文件
* @param targetFile 目标文件
*/
public static void doc2pdf(String sourcerFile, String targetFile) throws Exception {
if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
return;
}
long old = System.currentTimeMillis();
File file = new File(targetFile); // 新建一个空白pdf文档
FileOutputStream os = new FileOutputStream(file);
Document doc = new Document(sourcerFile); // sourcerFile是将要被转化的word文档
doc.save(os, SaveFormat.PDF); // 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
os.close();
long now = System.currentTimeMillis();
// log.info("共耗时:" + ((now - old) / 1000.0) + "秒"); //转化用时
}
/**
* 获取Word模板文档填充工具
*
* 填充规则:
* 模板(自定义):{{templateField}}
* 数据集:key为templateField(不带括号),value为需要填充的任意数据
*
* @param inFilePath 文档路径
* @param outFilePath 输出文档路径
* @param data 待替换的域的键值
* @param signCode 签章图片base64编码
* @return 处理结果
* @throws Exception
*/
public static Map<String, String> readwriteWord(String inFilePath, String outFilePath, Map<Object, Object> data, String signCode) throws Exception {
// 验证License 若不验证则转化出的word文档会有水印产生
if (!getLicense()) {
return null;
}
Map<String, String> map = new HashMap<>();
Document doc = null;
// 定义文档接口
doc = new Document(inFilePath);
for (Map.Entry<Object, Object> entry : data.entrySet()) {
String key = entry.getKey().toString();
Object value = entry.getValue();
if (value != null) {
Pattern p = Pattern.compile("\n");
Matcher m = p.matcher(value.toString());
int i = 0;
String replaceValue = "";
Boolean flag = false;
while (m.find()) {
// 换行处理
replaceValue = value.toString().replace(m.group(), "" + ControlChar.LINE_BREAK + "");
flag = true;
}
if (flag) {
// 要求替换的内容是完全匹配时的替换
// 可更换模板样式
doc.getRange().replace("{{" + key + "}}", replaceValue, true, false);
} else {
// 要求替换的内容是完全匹配时的替换
doc.getRange().replace("{{" + key + "}}", value.toString(), true, false);
}
}
}
if(signCode != null && !signCode.isEmpty()){
DocumentBuilder builder = new DocumentBuilder(doc);
builder.moveToMergeField("signature");
BASE64Decoder decoder = new BASE64Decoder();
byte[] imgByteArr = decoder.decodeBuffer(signCode);
for (int i = 0; i < imgByteArr.length; ++i) {
if (imgByteArr[i] < 0) {// 调整异常数据
imgByteArr[i] += 256;
}
}
builder.insertImage(imgByteArr, RelativeHorizontalPosition.RIGHT_MARGIN, -160, RelativeVerticalPosition.OUTSIDE_MARGIN, -140, 160, 160, WrapType.NONE);
}
// 生成四位随机数
Random ne = new Random();
int num = ne.nextInt(9999 - 1000 + 1) + 1000;
String random = String.valueOf(num);
String fileName = "" + System.currentTimeMillis() + random;
//替换后的Word
String docPath = outFilePath + fileName + inFilePath.substring(inFilePath.lastIndexOf("."));
//生成的PDF位置
String pdfPath = outFilePath + fileName + ".pdf";
doc.save(docPath);
File file = new File(docPath);
if (file.exists()) {
// 直接转换为word
doc2pdf(docPath, pdfPath);
map.put("pdfPath", pdfPath);
map.put("docPath", docPath);
}
return map;
}
/**
* Word中动态生成表格数据
* @param inFilePath 源文件
* @param outFilePath 目标文件
* @param listOne 数据集1
* @param listTwo 数据集2
* @throws Exception
*/
public static void dynamicDealTableData(String inFilePath, String outFilePath, List<DataOne> listOne, List<DataTwo> listTwo) throws Exception {
// 验证License
if (!getLicense()) {
return;
}
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
// 读取源文件
Document doc = new Document(inFilePath);
// 获取word中的第一个表格,index指定表格位置
Table table = (Table) doc.getChild(NodeType.TABLE, 0, true);
/**
* 下边的处理方式可能比较繁琐,总之逻辑就是:
* 如果数据集1有数据的话,就要根据 数据集1 的 模板行号 加上 其数据量来计算出
* 数据集2 的 模板行号 再处理
*/
// 数据集1 模板数据首行
int DataOneLineNum = 7;
// 处理 数据集1
if (CollectionUtils.isEmpty(listOne)) { // 数据集1 无数据
// 获取模板行
Range dataOneRange = table.getRows().get(DataOneLineNum).getRange();
dataOneRange.replace("Index", String.valueOf(1), true, true);
dataOneRange.replace("ApplyNoItem", "", true, true);
dataOneRange.replace("ApplyNameItem", "", true, true);
dataOneRange.replace("ApplyDateItem", "", true, true);
// 数据集2 模板数据首行(无 数据集1数据)
int listTwoLineNum_NonListOne = DataOneLineNum + 2;
// 无 数据集2数据
if (CollectionUtils.isEmpty(listTwo)) {
// 获取模板行
Range listTwoRange = table.getRows().get(listTwoLineNum_NonListOne).getRange();
listTwoRange.replace("IndexMotel", String.valueOf(1), true, true);
listTwoRange.replace("ApplyNo", "", true, true);
listTwoRange.replace("ApplyDate", "", true, true);
listTwoRange.replace("ApplyName", "", true, true);
listTwoRange.replace("UploaderType", "", true, true);
listTwoRange.replace("Remarks", "", true, true);
} else {
int temp = listTwoLineNum_NonListOne;
for (int index = 0; index < listTwo.size(); index++) {
// 复制模板行
Node node = table.getRows().get(listTwoLineNum_NonListOne).deepClone(true);
// 插入到第八行后
table.getRows().insert(temp + 1, node);
Range applyValidAmountRange = table.getRows().get(temp + 1).getRange();
// 加行
temp++;
// 序号
applyValidAmountRange.replace("IndexMotel", String.valueOf(index + 1), true, true);
// 申请号
if (StringUtils.isNotBlank(listTwo.get(index).getApplyNo())) {
applyValidAmountRange.replace("ApplyNo", listTwo.get(index).getApplyNo(), true, true);
}else{
applyValidAmountRange.replace("ApplyNo", "", true, true);
}
// 申请日期
if (Objects.nonNull(listTwo.get(index).getApplyDate())) {
applyValidAmountRange.replace("ApplyDate", df.format(listTwo.get(index).getApplyDate()), true, true);
}else{
applyValidAmountRange.replace("ApplyDate", "", true, true);
}
// 名称
if (StringUtils.isNotBlank(listTwo.get(index).getApplyName())) {
applyValidAmountRange.replace("ApplyName", listTwo.get(index).getApplyName(), true, true);
}else{
applyValidAmountRange.replace("ApplyName", "", true, true);
}
// 类型
if (StringUtils.isNotBlank(listTwo.get(index).getType())) {
applyValidAmountRange.replace("UploaderType", listTwo.get(index).getType(), true, true);
}else{
applyValidAmountRange.replace("UploaderType", "", true, true);
}
// 备注
if (StringUtils.isNotBlank(listTwo.get(index).getApplyRemark())) {
applyValidAmountRange.replace("Remarks", listTwo.get(index).getApplyRemark(), true, true);
}else{
applyValidAmountRange.replace("Remarks", "", true, true);
}
}
// 删除模板行数据
table.getRows().get(listTwoLineNum_NonListOne).remove();
}
} else {
// 处理 数据集1
int temp = DataOneLineNum;
for (int index = 0; index < listOne.size(); index++) {
// 复制第八行
Node node = table.getRows().get(DataOneLineNum).deepClone(true);
// 插入到第八行后
table.getRows().insert(temp + 1, node);
Range range = table.getRows().get(temp + 1).getRange();
// 加行
temp++;
// 序号
range.replace("Index", String.valueOf(index + 1), true, true);
// 申请号
if (StringUtils.isNotBlank(listOne.get(index).getApplyNo())) {
range.replace("ApplyNoItem", listOne.get(index).getApplyNo(), true, true);
}else{
range.replace("ApplyNoItem", "", true, true);
}
// 名称
if (StringUtils.isNotBlank(listOne.get(index).getApplyName())) {
range.replace("ApplyNameItem", listOne.get(index).getApplyName(), true, true);
}else {
range.replace("ApplyNameItem", "", true, true);
}
// 申请日期
if (StringUtils.isNotBlank(df.format(listOne.get(index).getApplyDate()))) {
range.replace("ApplyDateItem", df.format(listOne.get(index).getApplyDate()), true, true);
} else {
range.replace("ApplyDateItem", "", true, true);
}
}
// 数据集2 数据首行(存在 数据集1)
int dataTwoLineNum = DataOneLineNum + listTwo.size() + 2;
// 处理 截至上一年度在审未决和有效授权专利拥有量
if (CollectionUtils.isEmpty(listTwo)) {
// 获取模板行
Range dataTwoRange = table.getRows().get(dataTwoLineNum).getRange();
dataTwoRange.replace("IndexMotel", String.valueOf(1), true, true);
dataTwoRange.replace("ApplyNo", "", true, true);
dataTwoRange.replace("ApplyDate", "", true, true);
dataTwoRange.replace("ApplyName", "", true, true);
dataTwoRange.replace("UploaderType", "", true, true);
dataTwoRange.replace("Remarks", "", true, true);
} else {
int temp2 = dataTwoLineNum;
for (int index = 0; index < listTwo.size(); index++) {
// 复制模板行
Node node = table.getRows().get(dataTwoLineNum).deepClone(true);
// 插入到第八行后
table.getRows().insert(temp2 + 1, node);
Range applyValidAmountRange = table.getRows().get(temp2 + 1).getRange();
// 加行
temp2++;
// 序号
applyValidAmountRange.replace("IndexMotel", String.valueOf(index + 1), true, true);
// 申请号
if (StringUtils.isNotBlank(listTwo.get(index).getApplyNo())) {
applyValidAmountRange.replace("ApplyNo", listTwo.get(index).getApplyNo(), true, true);
}else{
applyValidAmountRange.replace("ApplyNo", "", true, true);
}
// 申请日期
if (Objects.nonNull(listTwo.get(index).getApplyDate())) {
applyValidAmountRange.replace("ApplyDate", df.format(listTwo.get(index).getApplyDate()), true, true);
}else{
applyValidAmountRange.replace("ApplyDate", "", true, true);
}
// 名称
if (StringUtils.isNotBlank(listTwo.get(index).getApplyName())) {
applyValidAmountRange.replace("ApplyName", listTwo.get(index).getApplyName(), true, true);
}else{
applyValidAmountRange.replace("ApplyName", "", true, true);
}
// 类型
if (StringUtils.isNotBlank(listTwo.get(index).getType())) {
applyValidAmountRange.replace("UploaderType", listTwo.get(index).getType(), true, true);
}else{
applyValidAmountRange.replace("UploaderType", "", true, true);
}
// 备注
if (StringUtils.isNotBlank(listTwo.get(index).getApplyRemark())) {
applyValidAmountRange.replace("Remarks", listTwo.get(index).getApplyRemark(), true, true);
}else{
applyValidAmountRange.replace("Remarks", "", true, true);
}
}
// 删除模板行数据
table.getRows().get(DataOneLineNum + listTwo.size() + 2).remove();
}
// 删除 数据集1 模板行
table.getRows().get(DataOneLineNum).remove();
}
// 保存到本地
doc.save(outFilePath);
}
}
2. 测试用例
import java.io.File;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
* @author maomaochong
* @date 2021/11/29 10:49
**/
public class Test03 {
public static void main(String[] args) throws Exception {
test01();
}
private static void test01() throws Exception {
List<DataOne> listOne = new ArrayList<>();
List<DataTwo> listTwo = new ArrayList<>();
listOne.add(new DataOne("123", "1123", LocalDateTime.now(), "ceshi", "123123"));
listOne.add(new DataOne("333", "2231", LocalDateTime.now(), "ceshi2", "123113"));
listTwo.add(new DataTwo("1122", "2233", "123133", LocalDateTime.now(), "测试1", "类型1", "备注"));
listTwo.add(new DataTwo("3322", "1221", "123133", LocalDateTime.now(), "测试2", "类型2", "备注2"));
AsposeWordsUtils.dynamicDealTableData(System.getProperty("user.dir") + File.separator + "template1.docx", System.getProperty("user.dir") + File.separator + "wordTemplate\\out\\dest3.docx", listOne, listTwo);
}
}
生成效果: