**操作方式:**
1.对于固定格,可以遍历格子然后替换其中指定的值例如在要替换的cell写入${example} 这样格式,遍历到之后替换。
2.对于需要增长的表格,可以将整行置为空,然后遍历到空格,找到当前那一行,之后,通过生成行,之后再写入。
poi文档地址 https://poi.apache.org/
有两种操作word的接口推荐使用下面的
表格组成从
XWPFDocument-->XWPFTable-->XWPFTableRow-->XWPFTableCell-->XWPFParagraph-->XWPFRun
可以从xwpfDocument往下找到最里面xwpfRun.
其中XWPFParagraph为样式,可以从XWPFTable,XWPFTableRow,XWPFTableCell等中得到其对象
下面给出实例代码
使用这样的word,***注意在此例子代码中要分成两个表格***
运行结果如下
代码
```java
package com.example.demo.Test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.poi.xwpf.usermodel.*;
/**
* 通过word模板生成新的word工具类
* @author benran
*
*
*/
public class GenerateWordByModel {
/**
* 根据模板生成新word文档
* 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
* @param inputUrl 模板存放地址
* @param outputUrl 新文档存放地址
* @param textMap 需要替换的信息集合
* @param tableList 需要插入的表格信息集合
* @return 成功返回true,失败返回false
*/
public static void changWord(String inputUrl, String outputUrl,
Map<String, String> textMap, List<String[]> tableList) {
XWPFDocument document=null;
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream=null;
try {
fileInputStream = new FileInputStream(inputUrl);
//获取docx解析对象
document = new XWPFDocument(fileInputStream);
//解析替换文本段落对象
GenerateWordByModel.changeText(document, textMap);
//解析替换表格对象
GenerateWordByModel.changeTable(document, textMap, tableList);
// fileInputStream.close();
fileOutputStream = new FileOutputStream(outputUrl);
document.write(fileOutputStream);
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 替换段落文本
* @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 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 table 需要插入数据的表格
* @param tableList 插入数据集合
*/
public static void insertTable(XWPFTable table, List<String[]> tableList){
//记录需要插入的第一行
int start =-1;
boolean findStartFlat=false;
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(findStartFlat){
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);
}
}
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 (int i = 0; i < copyCells.size(); i++) {
XWPFTableCell copyCell = copyCells.get(i);
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());
}
}
}
}
/**
* 判断文本中时候包含$
* @param text 文本
* @return 包含返回true,不包含返回false
*/
public static boolean checkText(String text){
boolean check = false;
if(text.indexOf("$")!= -1){
check = true;
}
return check;
}
/**
* 匹配传入信息集合与模板
* @param value 模板需要替换的区域
* @param textMap 传入信息集合
* @return 模板需要替换区域信息集合对应值
*/
public static String changeValue(String value, Map<String, String> textMap){
Set<Entry<String, String>> textSets = textMap.entrySet();
for (Entry<String, String> textSet : textSets) {
//匹配模板与替换值 格式${key}
String key = "${"+textSet.getKey()+"}";
if(key.indexOf(value)!= -1){
value = textSet.getValue();
}
}
return value;
}
public static void main(String[] args) {
//模板文件地址
String inputUrl = "C:\\Users\\admin\\Desktop\\ffsss.docx";
//新生产的模板文件
String outputUrl = "C:\\Users\\admin\\Desktop\\replitResult.docx";
Map<String, String> testMap = new HashMap<String, String>();
testMap.put("name", "名字");
testMap.put("sex", "性别");
testMap.put("address", "住址");
testMap.put("phone", "电话");
testMap.put("nation", "民族");
List<String[]> testList = new ArrayList<String[]>();
testList.add(new String[]{"111","22","33","44"});
testList.add(new String[]{"111","22","33","--"});
testList.add(new String[]{"111","22","33","00"});
testList.add(new String[]{"111","22","33","99"});
testList.add(new String[]{"111","22","33","88"});
testList.add(new String[]{"111","22","33","77"});
testList.add(new String[]{"111","22","33","66"});
testList.add(new String[]{"111","22","33","55"});
testList.add(new String[]{"111","22","33","12"});
GenerateWordByModel.changWord(inputUrl, outputUrl, testMap, testList);
}
}
```
**修改代码时注意**
**${name} 会被分为多个XWPFParagraph,分成\$, name,{,} , name可能被分为多个XWPFRun 分成n ,a,m,e**
每个属性都会有 getText方法会遍历返回该对象下所有文字。