Java利用poi生成word(包含插入图片,动态表格,行合并)
测试模板样式:
图表 1
Word生成结果:
图表 2
需要的jar包:(具体jar可自行去maven下载)
Test测试类:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
//需要进行文本替换的信息
Map<String, Object> data = new HashMap<String, Object>();
data.put("${date}", "2018-03-06");
data.put("${name}", "东方明珠");
data.put("${address}", "华东院");
data.put("${communityvalue}", "");
data.put("${safetycode}", "华东院");
data.put("${picture2}", "");
data.put("${picture3}", "");
data.put("${buildingvalue2}", "华东院");
data.put("${patrolPhoto1}", "");
data.put("${patrolPhoto2}", "");
data.put("${buildingvalue3}", "中国");
//图片,如果是多个图片,就新建多个map
Map<String,Object> picture1 = new HashMap<String, Object>();
picture1.put("width", 100);
picture1.put("height", 150);
picture1.put("type", "jpg");
picture1.put("content", WorderToNewWordUtils.inputStream2ByteArray(new FileInputStream("D:/timg.jpg"), true));
data.put("${picture1}",picture1);
//需要进行动态生成的信息
List<Object> mapList = new ArrayList<Object>();
//第一个动态生成的数据列表
List<String[]> list01 = new ArrayList<String[]>();
list01.add(new String[]{"A","11111111111","22","22"});
list01.add(new String[]{"A","22222222222","33","22"});
list01.add(new String[]{"B","33333333333","44","22"});
list01.add(new String[]{"C","44444444444","55","22"});
//第二个动态生成的数据列表
List<String[]> list02 = new ArrayList<String[]>();
list02.add(new String[]{"A","11111111111","22","22"});
list02.add(new String[]{"d","22222222222","33","22"});
list02.add(new String[]{"B","33333333333","44","22"});
list02.add(new String[]{"C","44444444444","55","22"});
mapList.add(list01);
mapList.add(list02);
//需要动态改变表格的位置;第一个表格的位置为0
int[] placeList = {1,4};
CustomXWPFDocument doc = WorderToNewWordUtils.changWord("C:/Users/user/Desktop/test1.docx",data,mapList,placeList);
FileOutputStream fopts = new FileOutputStream("D:/呵呵.docx");
doc.write(fopts);
fopts.close();
}
}
WorderToNewWordUtils类:
import org.apache.poi.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* Created by 王景伟 on 2018/12/19.
*/
public class WorderToNewWordUtils {
/**
* 根据模板生成word文档
* @param inputUrl 模板路径
* @param textMap 需要替换的文本内容
* @param mapList 需要动态生成的内容
* @return
*/
public static CustomXWPFDocument changWord(String inputUrl, Map<String, Object> textMap, List<Object> mapList,int[] placeList) {
CustomXWPFDocument document = null;
try {
//获取docx解析对象
document = new CustomXWPFDocument(POIXMLDocument.openPackage(inputUrl));
//解析替换文本段落对象
WorderToNewWordUtils.changeText(document, textMap);
//解析替换表格对象
WorderToNewWordUtils.changeTable(document, textMap, mapList,placeList);
} catch (IOException e) {
e.printStackTrace();
}
return document;
}
/**
* 替换段落文本
* @param document docx解析对象
* @param textMap 需要替换的信息集合
*/
public static void changeText(CustomXWPFDocument document, Map<String, Object> textMap){
//获取段落集合
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
//判断此段落时候需要进行替换
String text = paragraph.getText();
if(checkText(text)){
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
//替换模板原来位置
Object ob = changeValue(run.toString(), textMap);
System.out.println("段落:"+run.toString());
if (ob instanceof String){
run.setText((String)ob,0);
}
}
}
}
}
/**
* 替换表格对象方法
* @param document docx解析对象
* @param textMap 需要替换的信息集合
* @param mapList 需要动态生成的内容
*/
public static void changeTable(CustomXWPFDocument document, Map<String, Object> textMap, List<Object> mapList,int[] placeList){
//获取表格对象集合
List<XWPFTable> tables = document.getTables();
//循环所有需要进行替换的文本,进行替换
for (int i = 0; i < tables.size(); i++) {
XWPFTable table = tables.get(i);
if(checkText(table.getText())){
List<XWPFTableRow> rows = table.getRows();
System.out.println("简单表格替换:"+rows);
//遍历表格,并替换模板
eachTable(document,rows, textMap);
}
}
int index=0;
//操作word中的表格
for (int i = 0; i < tables.size(); i++) {
//只处理行数大于等于2的表格,且不循环表头
XWPFTable table = tables.get(i);
if(placeList[index]==i){
List<String[]> list = (List<String[]>) mapList.get(index);
//第二个表格使用daList,插入数据
if (null != list && 0 < list.size()){
insertTable(table, null,list,2);
List<Integer[]> indexList = startEnd(list);
for (int c=0;c<indexList.size();c++){
//合并行
mergeCellVertically(table,0,indexList.get(c)[0]+1,indexList.get(c)[1]+1);
}
}
index++;
}
}
}
/**
* 遍历表格
* @param rows 表格行对象
* @param textMap 需要替换的信息集合
*/
public static void eachTable(CustomXWPFDocument document, List<XWPFTableRow> rows , Map<String, Object> textMap){
for (XWPFTableRow row : rows) {
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
//判断单元格是否需要替换
if(checkText(cell.getText())){
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {