word模板报告数据插入及格式转换
1. 向模板内写入数据
1.1 单文本插入
//通过查询得到数据用参数或者对象接收后,与模板内参数对应完成文本插入
String code = usersService.findByCode().getCode();
TestUsers byCode = usersService.findByCode();
Map<String, Object> data = new HashMap<>();
data.put("${barcode}", code);
data.put("${barcode}", byCode.getCode());
效果
1.2 图片插入
1.2.1 根据文件路径插入
Map<String, Object> picData = new HashMap<>();
String inspection = "张三";
String audit = "C:\\Users\\chongchong\\Desktop\\repositories\\img\\shenhe.jpg";
String source = inspection + File.separator;
String targer = audit + File.separator;
//判断字符串是否是文件路径,调用不同的文本插入方法,且与模板内设计参数对应
if(source.matches("^[A-z]:\\\\(.+?\\\\)*$") && targer.matches("^[A-z]:\\\\(.+?\\\\)*$")){
picData.put("${inspection}", source);
picData.put("${audit}", targer);
} else if (source.matches("^[A-z]:\\\\(.+?\\\\)*$")){
picData.put("${inspection}",source);
data.put("${audit}",targer.substring(0,targer.length() - 1));
} else if (targer.matches("^[A-z]:\\\\(.+?\\\\)*$")){
data.put("${inspection}",source.substring(0,source.length() - 1));
picData.put("${audit}",targer);
} else {
data.put("${inspection}",source);
data.put("${audit}",targer);
}
效果
1.2.2 根据网络链接插入
/**
* @Author: chongchong
* @Description: 通过获取网络链接图片存储到本地,然后选择插入数据
* @DateTime: 2023/10/13 9:47
* @Params: imageUrl:网络链接 localImagePath:本地存储地址
* @Return void
*/
public static void UrlImg(String imageUrl,String localImagePath) throws IOException {
URL url = new URL(imageUrl);
InputStream in = url.openStream();
FileOutputStream out = new FileOutputStream(localImagePath);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
in.close();
out.close();
}
效果
1.3 批量文本插入
//通过选中的itemId查询对应的数据
List<TestItemsDetail> byItemId = itemsDetailService.getByItemId(Long.valueOf(29));
//遍历获取的对象数据,然后向表格内插入数据,此处知23条数据,剔除单独数据插入,具体使用时可以先判断再插入
for (int i = 0; i < byItemId.size() / 2; i++) {
arrearsList.add(Arrays.asList(byItemId.get(i).getName(),byItemId.get(i).getRefRangeStart(),
byItemId.get(byItemId.size() - i - 1).getName(),byItemId.get(byItemId.size() - i -1).getRefRangeStart()));
}
arrearsList.add(Arrays.asList(byItemId.get(byItemId.size()/2).getName(),byItemId.get(byItemId.size()/2).getRefRangeStart()));
效果
1.4 写入新的模板
/**
调用创建新报告方法,往其中插入对应的文本、图片等数据,
modelWord:模板word所在路径;
replaceWord:插入数据生成路径;
data:单文本;
picData:图片;
1:默认为1,代表的是批量插入文本所在的第几个表格(从0开始),此处批量插入数据的表格是第二个表格;
arrearsList:批量插入文本;
**/
ReplaceWord.operateWord(modelWord,replaceWord,data, picData,1,arrearsList);
2.根据文件路径转换格式
2.1 转换格式
调用AsposeUtil方法wordToPdf方法进行格式转换
getLicense方法是将格式转换的水印不生成
/**
wordPath:需要转换格式的文件路径("C:\\Users\\chongchong\\Desktop\\repositories\\word\\23分型报告单模板1.docx")
pdfPath:转换格式后的路径("C:\\Users\\chongchong\\Desktop\\repositories\\23分型报告单.pdf")
**/
AsposeUtil.wordToPdf(wordPath,pdfPath);
效果
3.代码
向模板内写入数据方法
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import java.io.*;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* @Author: chongchong
* @DateTime: 2023/10/11 17:10
* @Description: word模板数据填充
*/
public class ReplaceWordService {
/**
* @Author: chongchong
* @Description: 替换段落文本
* @DateTime: 2023/10/11 17:11
* @Params: document docx解析对象 textMap 需要替换的信息集合
* @Return void
*/
public static void changeText(XWPFDocument document, Map<String, Object> textMap) {
// 获取段落集合
Iterator<XWPFParagraph> iterator = document.getParagraphsIterator();
XWPFParagraph paragraph = null;
while (iterator.hasNext()) {
paragraph = iterator.next();
// 判断此段落是否需要替换
if (checkText(paragraph.getText())) {
replaceValue(paragraph, textMap);
}
}
}
/**
* @Author: chongchong
* @Description: 检查文本中是否包含指定的字符(此处为“$”)
* @DateTime: 2023/10/11 17:12
* @Params: text
* @Return boolean
*/
public static boolean checkText(String text) {
boolean check = false;
if (text.contains("$")) {
check = true;
}
return check;
}
/**
* @Author: chongchong
* @Description: 替换图片
* @DateTime: 2023/10/11 17:12
* @Params: document picData
* @throws: Exception
* @Return
*/
public static void changePic(XWPFDocument document, Map<String, Object> picData) throws Exception {
// 获取段落集合
Iterator<XWPFParagraph> iterator = document.getParagraphsIterator();
XWPFParagraph paragraph;
while (iterator.hasNext()) {
paragraph = iterator.next();
// 判断此段落是否需要替换
String text = paragraph.getText();
if (checkText(text)) {
replacePicValue(paragraph, picData);
}
}
}
/**
* @Author: chongchong
* @Description: 替换表格内的文字
* @DateTime: 2023/10/11 17:14
* @Params: document data
* @Return void
*/
public static void changeTableText(XWPFDocument document, Map<String, Object> data) {
// 获取文件的表格
Iterator<XWPFTable> tableList = document.getTablesIterator();
XWPFTable table;
List<XWPFTableRow> rows;
List<XWPFTableCell> cells;
// 循环所有需要进行替换的文本,进行替换
while (tableList.hasNext()) {
table = tableList.next();
if (checkText(table.getText())) {
rows = table.getRows();
// 遍历表格,并替换模板
for (XWPFTableRow row : rows) {
cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
// 判断单元格是否需要替换
if (checkText(cell.getText())) {
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
replaceValue(paragraph, data);
}
}
}
}
}
}
}
/**
* @Author: chongchong
* @Description: 替换表格内图片
* @DateTime: 2023/10/11 17:14
* @Params: document picData
* @Return void
*/
public static void changeTablePic(XWPFDocument document, Map<String, Object> picData) throws Exception {
// 获取文件的表格
Iterator<XWPFTable> tableList = document.getTablesIterator();
XWPFTable table;
List<XWPFTableRow> rows;
List<XWPFTableCell> cells;
// 循环所有需要进行替换的文本,进行替换
while (tableList.hasNext()) {
table = tableList.next();
if (checkText(table.getText())) {
rows = table.getRows();
// 遍历表格,并替换模板
for (XWPFTableRow row : rows) {
cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
// 判断单元格是否需要替换
if (checkText(cell.getText())) {
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
replacePicValue(paragraph, picData);
}
}
}
}
}
}
}
/**
* @Author: chongchong
* @Description: 替换内容
* @DateTime: 2023/10/11 17:15
* @Params: paragraph textMap
* @Return void
*/
public static void replaceValue(XWPFParagraph paragraph, Map<String, Object> textMap) {
XWPFRun run, nextRun;
String runsText;
List<XWPFRun> runs = paragraph.getRuns();
for (int i = 0; i < runs.size(); i++) {
run = runs.get(i);
runsText = run.getText(0);
if (runsText.contains("${") || (runsText.contains("$") && runs.get(i + 1).getText(0).substring(0, 1).equals("{"))) {
while (!runsText.contains("}")) {
nextRun = runs.get(i + 1);
runsText = runsText + nextRun.getText(0);
//删除该节点下的数据
paragraph.removeRun(i + 1);
}
Object value = changeValue(runsText, textMap);
//判断key在Map中是否存在
if (textMap.containsKey(runsText)) {
run.setText(value.toString(), 0);
} else {
//如果匹配不到,则不修改
run.setText(runsText, 0);
}
}
}
}
/**
* @Author: chongchong
* @Description: 替换图片内容
* @DateTime: 2023/10/11 17:15
* @Params: paragraph picData
* @Return void
*/
public static void replacePicValue(XWPFParagraph paragraph, Map<String, Object> picData) throws Exception {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
Object value = changeValue(run.toString(), picData);
if (picData.containsKey(run.toString())) {
//清空内容
run.setText("", 0);
FileInputStream is = new FileInputStream((String) value);
//规定图片宽度、高度
int width = Units.toEMU(30), height = Units.toEMU(30);
//添加图片信息,段落高度需要在模板中自行调整
run.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, (String) value, width, height);
}
}
}
/**
* @Author: chongchong
* @Description: 匹配参数
* @DateTime: 2023/10/11 17:16
* @Params: value textMap
* @Return java.lang.Object
*/
public static Object changeValue(String value, Map<String, Object> textMap) {
Object valu = "";
for (Map.Entry<String, Object> textSet : textMap.entrySet()) {
// 匹配模板与替换值 格式${key}
String key = textSet.getKey();
if (value.contains(key)) {
valu = textSet.getValue();
}
}
return valu;
}
/**
* @Author: chongchong
* @Description: 批量替换表格内容
* @DateTime: 2023/10/11 17:16
* @Params: index(表格索引:第几个表格) tableList(批量增加的数据源)
* @Return void
*/
public static void replaceTable(XWPFDocument document,int index, List<List<String>> tableList) {
XWPFTable table = document.getTables().get(index);
//创建行,根据需要插入的数据添加新行,不处理表头
/*for (int i = 1; i <= tableList.size(); i++) {
table.createRow();
}*/
//遍历表格插入数据
List<XWPFTableRow> rows = table.getRows();
for (int i = 1; i < tableList.size()+1; i++) {
XWPFTableRow newRow = table.getRow(i);
List<XWPFTableCell> cells = newRow.getTableCells();
List<String> rowData = tableList.get(i - 1);
for (int j = 0; j < rowData.size(); j++) {
XWPFTableCell cell = cells.get(j);
String text = rowData.get(j);
cell.setText(text);
if (text.equals("阳性")){
cell.setColor("ff0000");
}
//表格样式一致-->没有此段表格会默认左对齐
//有此段会使表格格式一致
/*CTTc cttc = cell.getCTTc();
CTTcPr ctPr = cttc.addNewTcPr();
ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);*/
}
}
}
/**
* @Author: chongchong
* @Description: 根据模板所需替换的形式调用不同的方法向模板中添加信息,然后导出写入数据的新的文档
* @DateTime: 2023/10/11 17:18
* @Params: data(表格内单文本插入) picData(表格内图片) index(默认:1,即批量插入文本数据的表格) tableList(批量插入文本数据集)
* @Return void
*/
public static void operateWord(String modelWord,String replaceWord,Map<String, Object> data,
Map<String, Object> picData,
int index,List<List<String>> tableList){
try {
//读取模板word的文件路径
FileInputStream is = new FileInputStream(modelWord);
XWPFDocument document = new XWPFDocument(is);
if (data.size() > 0) {
// 替换掉表格之外的文本(仅限文本)
ReplaceWordService.changeText(document, data);
// 替换表格内的文本对象
ReplaceWordService.changeTableText(document, data);
}
if (picData.size() > 0) {
// 替换内容图片
ReplaceWordService.changePic(document, picData);
// 替换表格内的图片对象
ReplaceWordService.changeTablePic(document, picData);
}
if (tableList.size() > 0) {
//往表格中批量插入文本
ReplaceWordService.replaceTable(document,index,tableList);
}
//写入数据后的模板存储文件路径
FileOutputStream out = new FileOutputStream(replaceWord);
document.write(out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Author: chongchong
* @Description: 通过获取网络链接图片存储到本地,然后选择插入数据
* @DateTime: 2023/10/13 9:47
* @Params: imageUrl:网络链接 localImagePath:本地存储地址
* @Return void
*/
public static void UrlImg(String imageUrl,String localImagePath) throws IOException {
URL url = new URL(imageUrl);
InputStream in = url.openStream();
FileOutputStream out = new FileOutputStream(localImagePath);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
in.close();
out.close();
}
}
word文档格式转换pdf方法参考上一篇文章word转pdf:https://www.cnblogs.com/chongchongstyle/p/17761878.html
标签:word,String,表格,picData,void,paragraph,POI,Apache,document From: https://www.cnblogs.com/chongchongstyle/p/17761889.html