package com.terra.system.helper;
|
|
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.LogFactory;
|
import org.apache.poi.xwpf.usermodel.*;
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
|
|
import java.io.*;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Set;
|
|
/**
|
* Word帮助类
|
*
|
* @author WWW
|
* @date 2024-03-21
|
*/
|
@SuppressWarnings("ALL")
|
public class WordHelper {
|
private final static Log log = LogFactory.getLog(WordHelper.class);
|
|
/**
|
* 通过word模板生成word的主方法
|
* https://blog.csdn.net/qq_46112324/article/details/128156675
|
*/
|
public static void generateWord(String inputFile, String outPutFile, Map<String, String> textMap, List<String[]> tableList) {
|
FileInputStream inputStream = null;
|
FileOutputStream outputStream = null;
|
|
try {
|
inputStream = new FileInputStream(inputFile);
|
outputStream = new FileOutputStream(outPutFile);
|
|
// 获取docx解析对象
|
XWPFDocument document = new XWPFDocument(inputStream);
|
|
// 处理所有文段数据,除了表格
|
if (null != textMap && textMap.size() > 0) {
|
handleParagraphs(document, textMap);
|
//changeText(document, textMap);
|
}
|
|
// 解析替换表格对象
|
if (null != tableList && tableList.size() > 0) {
|
handleTable(document, textMap, tableList);
|
//changeTable(document, textMap, tableList);
|
}
|
|
// 写入数据
|
document.write(outputStream);
|
document.close();
|
} catch (Exception ex) {
|
log.error(ex.getMessage(), ex);
|
} finally {
|
try {
|
if (outputStream != null) {
|
outputStream.close();
|
}
|
if (inputStream != null) {
|
inputStream.close();
|
}
|
} catch (Exception e) {
|
log.error(e.getMessage(), e);
|
}
|
}
|
}
|
|
/**
|
* 替换表格对象方法
|
*
|
* @param document docx解析对象
|
* @param textMap 需要替换的信息集合
|
* @param tableList 需要插入的表格信息集合
|
*/
|
public static void changeTable(XWPFDocument document, Map<String, String> textMap, List<String[]> tableList) {
|
// 获取表格对象集合
|
List<XWPFTable> tables = document.getTables();
|
for (int i = 0; i < tables.size(); i++) {
|
XWPFTable table = tables.get(i);
|
if (table.getRows().size() > 1) {
|
// 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
|
if (!checkText(table.getText())) {
|
insertTable(table, tableList);
|
}
|
}
|
}
|
}
|
|
/**
|
* 替换段落文本
|
*
|
* @param document docx解析对象
|
* @param textMap 需要替换的信息集合
|
*/
|
public static void changeText(XWPFDocument document, Map<String, String> textMap) {
|
// 获取段落集合
|
List<XWPFTable> tables = document.getTables();
|
for (XWPFTable table : tables) {
|
if (checkText(table.getText())) {
|
List<XWPFTableRow> rows = table.getRows();
|
for (XWPFTableRow row : rows) {
|
List<XWPFTableCell> tableCells = row.getTableCells();
|
for (XWPFTableCell cell : tableCells) {
|
if (checkText(cell.getText())) {
|
List<XWPFParagraph> paragraphs = cell.getParagraphs();
|
for (XWPFParagraph paragraph : paragraphs) {
|
// 判断此段落时候需要进行替换
|
String text = paragraph.getText();
|
if (checkText(text)) {
|
List<XWPFRun> runs = paragraph.getRuns();
|
for (XWPFRun run : runs) {
|
// 替换模板原来位置
|
if (checkText(run.toString())) {
|
run.setText(changeValue(paragraph.getText(), textMap), 0);
|
} else {
|
run.setText("", 0);
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
/**
|
* 判断文本中时候包含$
|
*
|
* @param text 文本
|
* @return 包含返回true, 不包含返回false
|
*/
|
public static boolean checkText(String text) {
|
boolean check = false;
|
if (text.contains("$")) {
|
check = true;
|
}
|
return check;
|
}
|
|
/**
|
* 匹配传入信息集合与模板
|
*
|
* @param value 模板需要替换的区域
|
* @param textMap 传入信息集合
|
* @return 模板需要替换区域信息集合对应值
|
*/
|
public static String changeValue(String value, Map<String, String> textMap) {
|
Set<Map.Entry<String, String>> textSets = textMap.entrySet();
|
for (Map.Entry<String, String> textSet : textSets) {
|
// 匹配模板与替换值 格式${key}
|
String key = "${" + textSet.getKey() + "}";
|
if (key.contains(value)) {
|
value = textSet.getValue();
|
}
|
}
|
return value;
|
}
|
|
/**
|
* 为表格插入数据,行数不够添加新行
|
*
|
* @param table 需要插入数据的表格
|
* @param tableList 插入数据集合
|
*/
|
public static void insertTable(XWPFTable table, List<String[]> tableList) {
|
// 记录需要插入的第一行
|
int start = -1;
|
for (int i = 0; i < table.getRows().size(); i++) {
|
for (int j = 0; j < table.getRows().get(i).getTableCells().size(); j++) {
|
if ("".equals(table.getRows().get(i).getTableCells().get(j).getText())) {
|
start = i;
|
break;
|
}
|
}
|
}
|
// 创建行,根据需要插入的数据添加新行
|
if (start != -1) {
|
for (int i = 1; i < tableList.size(); i++) {
|
insertRow(table, start, start + i);
|
}
|
}
|
|
// 遍历表格插入数据
|
List<XWPFTableRow> rows = table.getRows();
|
for (int i = start; i < rows.size(); i++) {
|
List<XWPFTableCell> cells = rows.get(i).getTableCells();
|
for (int j = 0; j < table.getRow(start).getTableCells().size(); j++) {
|
XWPFTableCell cell = cells.get(j);
|
cell.setText(tableList.get(0)[j]);
|
}
|
tableList.remove(0);
|
}
|
}
|
|
/**
|
* 为表格插入数据,行数不够添加新行
|
*
|
* @param table 需要插入数据的表格
|
* @param copyRowIndex 复制行号
|
* @param newRowIndex 新行号
|
*/
|
public static void insertRow(XWPFTable table, int copyRowIndex, int newRowIndex) {
|
// 在表格中指定的位置新增一行
|
XWPFTableRow targetRow = table.insertNewTableRow(newRowIndex);
|
|
// 获取需要复制行对象
|
XWPFTableRow copyRow = table.getRow(copyRowIndex);
|
|
// 复制行对象
|
targetRow.getCtRow().setTrPr(copyRow.getCtRow().getTrPr());
|
//或许需要复制的行的列
|
List<XWPFTableCell> copyCells = copyRow.getTableCells();
|
// 复制列对象
|
XWPFTableCell targetCell = null;
|
for (XWPFTableCell copyCell : copyCells) {
|
targetCell = targetRow.addNewTableCell();
|
targetCell.getCTTc().setTcPr(copyCell.getCTTc().getTcPr());
|
if (copyCell.getParagraphs() != null && copyCell.getParagraphs().size() > 0) {
|
targetCell.getParagraphs().get(0).getCTP().setPPr(copyCell.getParagraphs().get(0).getCTP().getPPr());
|
if (copyCell.getParagraphs().get(0).getRuns() != null
|
&& copyCell.getParagraphs().get(0).getRuns().size() > 0) {
|
XWPFRun cellR = targetCell.getParagraphs().get(0).createRun();
|
cellR.setBold(copyCell.getParagraphs().get(0).getRuns().get(0).isBold());
|
}
|
}
|
}
|
}
|
|
|
/**
|
* 处理所有文段数据,除了表格
|
*/
|
public static void handleParagraphs(XWPFDocument xwpfDocument, Map<String, String> insertTextMap) {
|
for (XWPFParagraph paragraph : xwpfDocument.getParagraphs()) {
|
String text = paragraph.getText();
|
if (isReplacement(text)) {
|
for (XWPFRun run : paragraph.getRuns()) {
|
// 判断带有 ${} 的run
|
run.setText(matchesValue(run.text(), insertTextMap), 0);
|
}
|
}
|
}
|
}
|
|
/**
|
* 处理表格数据方法
|
*/
|
public static void handleTable(XWPFDocument xwpfDocument, Map<String, String> map, List<String[]> addList) {
|
List<XWPFTable> tables = xwpfDocument.getTables();
|
for (XWPFTable table : tables) {
|
List<XWPFTableRow> rows = table.getRows();
|
if (rows.size() < 2) {
|
continue;
|
}
|
|
if (isReplacement(table.getText())) {
|
if (null == map || map.isEmpty()) {
|
continue;
|
}
|
|
replaceData(rows, map);
|
} else {
|
insertData(table, addList);
|
}
|
}
|
}
|
|
/**
|
* 替换数据
|
*/
|
private static void replaceData(List<XWPFTableRow> rows, Map<String, String> map) {
|
for (XWPFTableRow row : rows) {
|
List<XWPFTableCell> tableCells = row.getTableCells();
|
for (XWPFTableCell tableCell : tableCells) {
|
if (isReplacement(tableCell.getText())) {
|
List<XWPFParagraph> paragraphs = tableCell.getParagraphs();
|
for (XWPFParagraph paragraph : paragraphs) {
|
List<XWPFRun> runs = paragraph.getRuns();
|
for (XWPFRun run : runs) {
|
run.setText(matchesValue(tableCell.getText(), map), 0);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
/**
|
* 插入数据
|
*/
|
private static void insertData(XWPFTable table, List<String[]> addList) {
|
for (int i = 1, c = addList.size(); i < c; i++) {
|
table.createRow();
|
}
|
|
List<XWPFTableCell> oldCells = table.getRow(1).getTableCells();
|
List<XWPFTableRow> rowList = table.getRows();
|
for (int i = 0, c = addList.size(); i < c; i++) {
|
XWPFTableRow xwpfTableRow = rowList.get(i + 1);
|
|
List<XWPFTableCell> tableCells = xwpfTableRow.getTableCells();
|
for (int j = 0; j < tableCells.size(); j++) {
|
XWPFTableCell oldCell = oldCells.get(j);
|
XWPFTableCell newCell = tableCells.get(j);
|
|
if (0 == i) {
|
// newCell.setText(addList.get(i)[j])
|
setCellText(newCell, addList.get(i)[j]);
|
} else {
|
setCellText(oldCell, newCell, addList.get(i)[j]);
|
}
|
}
|
}
|
}
|
|
/**
|
* 设置单元格文本
|
*/
|
private static void setCellText(XWPFTableCell cell, String text) {
|
List<XWPFParagraph> paragraphs = cell.getParagraphs();
|
for (XWPFParagraph paragraph : paragraphs) {
|
List<XWPFRun> runs = paragraph.getRuns();
|
for (XWPFRun run : runs) {
|
run.setText(text, 0);
|
}
|
}
|
}
|
|
/**
|
* 有${}的值匹配出替换的数据,没有${}就返回原来的数据
|
*
|
* @param wordValue ${...} 带${}的变量
|
* @param map 存储需要替换的数据
|
* @return java.lang.String
|
*/
|
public static String matchesValue(String wordValue, Map<String, String> map) {
|
for (String s : map.keySet()) {
|
String s1 = "${" + s + "}";
|
/*if (s1.equals(wordValue)) {
|
wordValue = map.get(s);
|
}*/
|
if (wordValue.contains(s1)) {
|
wordValue = wordValue.replace(s1, map.get(s));
|
}
|
}
|
|
return wordValue;
|
}
|
|
/**
|
* 测试是否包含需要替换的数据
|
*/
|
public static boolean isReplacement(String text) {
|
return text.contains("${");
|
}
|
|
/**
|
* 复制模板行的属性
|
*/
|
private static void setCellText(XWPFTableCell tmpCell, XWPFTableCell cell, String text) {
|
CTTc cttc2 = tmpCell.getCTTc();
|
CTTcPr ctPr2 = cttc2.getTcPr();
|
CTTc cttc = cell.getCTTc();
|
CTTcPr ctPr = cttc.addNewTcPr();
|
if (ctPr2.getTcW() != null) {
|
ctPr.addNewTcW().setW(ctPr2.getTcW().getW());
|
}
|
if (ctPr2.getVAlign() != null) {
|
ctPr.addNewVAlign().setVal(ctPr2.getVAlign().getVal());
|
}
|
if (ctPr2.getTcBorders() != null) {
|
ctPr.setTcBorders(ctPr2.getTcBorders());
|
}
|
|
XWPFParagraph tmpP = tmpCell.getParagraphs().get(0);
|
XWPFParagraph cellP = cell.getParagraphs().get(0);
|
XWPFRun tmpR = null;
|
if (tmpP.getRuns() != null && tmpP.getRuns().size() > 0) {
|
tmpR = tmpP.getRuns().get(0);
|
}
|
XWPFRun cellR = cellP.createRun();
|
cellR.setText(text);
|
|
// 复制字体信息
|
copyFontInfo(cellR, tmpR);
|
|
// 复制段落信息
|
cellP.setAlignment(tmpP.getAlignment());
|
cellP.setVerticalAlignment(tmpP.getVerticalAlignment());
|
cellP.setBorderBetween(tmpP.getBorderBetween());
|
cellP.setBorderBottom(tmpP.getBorderBottom());
|
cellP.setBorderLeft(tmpP.getBorderLeft());
|
cellP.setBorderRight(tmpP.getBorderRight());
|
cellP.setBorderTop(tmpP.getBorderTop());
|
cellP.setPageBreak(tmpP.isPageBreak());
|
|
if (tmpP.getCTP() != null && tmpP.getCTP().getPPr() != null) {
|
CTPPr tmpPpr = tmpP.getCTP().getPPr();
|
CTPPr cellPpr = cellP.getCTP().getPPr() != null ? cellP.getCTP().getPPr() : cellP.getCTP().addNewPPr();
|
|
// 复制段落间距信息
|
copySpacing(tmpPpr, cellPpr);
|
|
// 复制段落缩进信息
|
copyParagraph(tmpPpr, cellPpr);
|
}
|
}
|
|
/**
|
* 复制字体信息
|
*/
|
private static void copyFontInfo(XWPFRun cellR, XWPFRun tmpR) {
|
if (tmpR == null) {
|
return;
|
}
|
if (!cellR.isBold()) {
|
cellR.setBold(tmpR.isBold());
|
}
|
cellR.setItalic(tmpR.isItalic());
|
cellR.setUnderline(tmpR.getUnderline());
|
cellR.setColor(tmpR.getColor());
|
cellR.setTextPosition(tmpR.getTextPosition());
|
if (tmpR.getFontSize() != -1) {
|
cellR.setFontSize(tmpR.getFontSize());
|
}
|
if (tmpR.getFontFamily() != null) {
|
cellR.setFontFamily(tmpR.getFontFamily());
|
}
|
if (tmpR.getCTR() != null) {
|
if (tmpR.getCTR().isSetRPr()) {
|
CTRPr tmpRpr = tmpR.getCTR().getRPr();
|
if (tmpRpr.isSetRFonts()) {
|
CTFonts tmpFonts = tmpRpr.getRFonts();
|
CTRPr cellRpr = cellR.getCTR().isSetRPr() ? cellR.getCTR().getRPr() : cellR.getCTR().addNewRPr();
|
CTFonts cellFonts = cellRpr.isSetRFonts() ? cellRpr.getRFonts() : cellRpr.addNewRFonts();
|
cellFonts.setAscii(tmpFonts.getAscii());
|
cellFonts.setAsciiTheme(tmpFonts.getAsciiTheme());
|
cellFonts.setCs(tmpFonts.getCs());
|
cellFonts.setCstheme(tmpFonts.getCstheme());
|
cellFonts.setEastAsia(tmpFonts.getEastAsia());
|
cellFonts.setEastAsiaTheme(tmpFonts.getEastAsiaTheme());
|
cellFonts.setHAnsi(tmpFonts.getHAnsi());
|
cellFonts.setHAnsiTheme(tmpFonts.getHAnsiTheme());
|
}
|
}
|
}
|
}
|
|
/**
|
* 复制段落间距信息
|
*/
|
private static void copySpacing(CTPPr tmpPpr, CTPPr cellPpr) {
|
CTSpacing tmpSpacing = tmpPpr.getSpacing();
|
if (tmpSpacing != null) {
|
CTSpacing cellSpacing = cellPpr.getSpacing() != null ? cellPpr.getSpacing() : cellPpr.addNewSpacing();
|
if (tmpSpacing.getAfter() != null) {
|
cellSpacing.setAfter(tmpSpacing.getAfter());
|
}
|
if (tmpSpacing.getAfterAutospacing() != null) {
|
cellSpacing.setAfterAutospacing(tmpSpacing.getAfterAutospacing());
|
}
|
if (tmpSpacing.getAfterLines() != null) {
|
cellSpacing.setAfterLines(tmpSpacing.getAfterLines());
|
}
|
if (tmpSpacing.getBefore() != null) {
|
cellSpacing.setBefore(tmpSpacing.getBefore());
|
}
|
if (tmpSpacing.getBeforeAutospacing() != null) {
|
cellSpacing.setBeforeAutospacing(tmpSpacing
|
.getBeforeAutospacing());
|
}
|
if (tmpSpacing.getBeforeLines() != null) {
|
cellSpacing.setBeforeLines(tmpSpacing.getBeforeLines());
|
}
|
if (tmpSpacing.getLine() != null) {
|
cellSpacing.setLine(tmpSpacing.getLine());
|
}
|
if (tmpSpacing.getLineRule() != null) {
|
cellSpacing.setLineRule(tmpSpacing.getLineRule());
|
}
|
}
|
}
|
|
/**
|
* 复制段落缩进信息
|
*/
|
private static void copyParagraph(CTPPr tmpPpr, CTPPr cellPpr) {
|
CTInd tmpInd = tmpPpr.getInd();
|
if (tmpInd != null) {
|
CTInd cellInd = cellPpr.getInd() != null ? cellPpr.getInd() : cellPpr.addNewInd();
|
if (tmpInd.getFirstLine() != null) {
|
cellInd.setFirstLine(tmpInd.getFirstLine());
|
}
|
if (tmpInd.getFirstLineChars() != null) {
|
cellInd.setFirstLineChars(tmpInd.getFirstLineChars());
|
}
|
if (tmpInd.getHanging() != null) {
|
cellInd.setHanging(tmpInd.getHanging());
|
}
|
if (tmpInd.getHangingChars() != null) {
|
cellInd.setHangingChars(tmpInd.getHangingChars());
|
}
|
if (tmpInd.getLeft() != null) {
|
cellInd.setLeft(tmpInd.getLeft());
|
}
|
if (tmpInd.getLeftChars() != null) {
|
cellInd.setLeftChars(tmpInd.getLeftChars());
|
}
|
if (tmpInd.getRight() != null) {
|
cellInd.setRight(tmpInd.getRight());
|
}
|
if (tmpInd.getRightChars() != null) {
|
cellInd.setRightChars(tmpInd.getRightChars());
|
}
|
}
|
}
|
}
|