背景
有一个如下图所示的word模板,需要根据不同的数据生成对应的文件
代码
添加所需依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.15</version>
</dependency>
工具类
public class WordUtils {
/***
* @Description :替换段落文本
* @param document docx解析对象
* @param 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);
}
}
}
/***
* @Description :替换表格内的文字
* @param document
* @param 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);
}
}
}
}
}
}
}
/***
* @Description :检查文本中是否包含指定的字符(此处为“$”)
* @param text
* @return boolean
*/
public static boolean checkText(String text) {
boolean check = false;
if (text.contains("$")) {
check = true;
}
return check;
}
/***
* @Description :替换内容
* @param paragraph
* @param 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中是否存在
String replaceText = runsText.replace("${", "").replace("}", "");
if (textMap.containsKey(replaceText)) {
run.setText(value.toString(), 0);
} else {
//如果匹配不到,则不修改
run.setText(runsText, 0);
}
}
}
}
/***
* @Description :匹配参数
* @param value
* @param 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;
}
}
测试
public class WordTextTest {
public static void main(String[] args) throws IOException {
WordTextTest.fillWord();
}
public static void fillWord() throws IOException {
//文件模板输入流
InputStream inputStream = new ClassPathResource("document/demo2.docx").getInputStream();
XWPFDocument document = new XWPFDocument(inputStream);
Map<String, Object> map = new HashMap<>();
map.put("title", "标题");
map.put("name", "_小半q");
map.put("sex", "男");
if (map1.size() > 0) {
// 替换掉表格之外的文本(仅限文本)
WordUtils.changeText(document, map);
// 替换表格内的文本对象
WordUtils.changeTableText(document, map);
}
FileOutputStream fos = new FileOutputStream("C:\\Users\\MHGIS\\Desktop\\text1" + ".docx");
document.write(fos);
}
}
效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jQoxnqdr-1690191201159)(https://gitee.com/xustgis/image-repository/raw/master/img/16901911204541690191119634.png)]