#javaPOI实现填充Word文档中的内容并导出
###此类实现将Word文档内容填充并将Word文档导出之本地。此类适用于复杂的Word文档。为了弄这花费了不少功夫。此类中的一些方法借鉴了一些大佬的博客,如有侵权请您速与我联系,我将马上删除。
具体工具代码类如下:
package com.hyzh.security.supervise.utils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author xuyong
* @version 1.0
* @Title: WordExport.java
* @Description: 导出word文档
*/
public class WordExport {
private static final Logger logger = LoggerFactory.getLogger(WordExport.class);
private String templatePath;
private XWPFDocument doc = null;
private FileInputStream is = null;
private OutputStream os = null;
public WordExport(int i) throws FileNotFoundException {
File file = ResourceUtils.getFile("C:hyzhFile/modul模板文件一.docx");
templatePath=file.getAbsolutePath();
}
public WordExport() throws FileNotFoundException {
//File file = ResourceUtils.getFile("classpath:wordTemplate/wordTemp.docx");
File file = ResourceUtils.getFile("C://hyzhFile/modul/模板文件二.docx");
templatePath=file.getAbsolutePath();
}
public WordExport(String templatePath) {
this.templatePath = templatePath;
}
public void init() throws IOException {
is = new FileInputStream(new File(this.templatePath));
doc = new XWPFDocument(is);
}
/**
* 替换掉占位符
*
* @param params
* @return
* @throws Exception
*/
public boolean export(Map<String, Object> params) throws Exception {
this.replaceInPara(doc, params);
return true;
}
/**
* export 替换掉表格中的占位符
* @param params
* @param index
* @return
* @create 2019/11/11 23:06
* @auther: mgg
*/
public boolean export(Map<String, Object> params,int index) throws Exception {
this.replaceInTable(doc, params, 0);
return true;
}
/**
* 循环生成表格
*
* @param params
* @param tableIndex
* @return
* @throws Exception
*/
public boolean export(List<Map<String, Object>> params, int tableIndex) throws Exception {
return export(params, tableIndex, false);
}
public boolean export(List<Map<String, Object>> params, int tableIndex, Boolean hasTotalRow) throws Exception {
this.insertValueToTables(doc, params, tableIndex, hasTotalRow);
return true;
}
/**
* 导出图片
*
* @param params
* @return
* @throws Exception
*/
public boolean exportImg(Map<String, Object> params) throws Exception {
/*List<XWPFParagraph> list = doc.getParagraphs();
for(XWPFParagraph para : list){
logger.info(para.getText());
}*/
List<XWPFTable> list = doc.getTables();
System.out.print(list.size());
return true;
}
/**
* 生成word文档
*
* @param outDocPath
* @return
* @throws IOException
*/
public boolean generate(String outDocPath) throws IOException {
os = new FileOutputStream(outDocPath);
doc.write(os);
this.close(os);
this.close(is);
return true;
}
/**
* 替换表格里面的变量
*
* @param doc 要替换的文档
* @param params 参数
* @throws Exception
*/
private void replaceInTable(XWPFDocument doc, Map<String, Object> params, int tableIndex) throws Exception {
List<XWPFTable> tableList = doc.getTables();
if (tableList.size() <= tableIndex) {
throw new Exception("tableIndex对应的表格不存在");
}
for (int j = 0; j < tableList.size(); j++) {
tableIndex = j;
XWPFTable table = tableList.get(tableIndex);
List<XWPFTableRow> rows;
List<XWPFTableCell> cells;
List<XWPFParagraph> paras;
rows = table.getRows();
for (XWPFTableRow row : rows) {
cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
paras = cell.getParagraphs();
for (XWPFParagraph para : paras) {
this.replaceInPara(para, params);
}
}
}
}
}
/**
* 替换段落里面的变量
*
* @param doc 要替换的文档
* @param params 参数
* @throws Exception
*/
private void replaceInPara(XWPFDocument doc, Map<String, Object> params) throws Exception {
Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
XWPFParagraph para;
while (iterator.hasNext()) {
para = iterator.next();
this.replaceInPara(para, params);
}
}
/**
* 替换段落里面的变量
*
* @param para 要替换的段落
* @param params 参数
* @throws Exception
* @throws IOException
* @throws InvalidFormatException
*/
private boolean replaceInPara(XWPFParagraph para, Map<String, Object> params) throws Exception {
boolean data = false;
List<XWPFRun> runs;
//有符合条件的占位符
if (this.matcher(para.getParagraphText()).find()) {
runs = para.getRuns();
data = true;
Map<Integer, String> tempMap = new HashMap<Integer, String>();
for (int i = 0; i < runs.size(); i++) {
XWPFRun run = runs.get(i);
String runText = run.toString();
//以"$"开头
boolean begin = runText.indexOf("$") > -1;
boolean end = runText.indexOf("}") > -1;
if (begin && end) {
tempMap.put(i, runText);
fillBlock(para, params, tempMap, i);
continue;
} else if (begin && !end) {
tempMap.put(i, runText);
continue;
} else if (!begin && end) {
tempMap.put(i, runText);
fillBlock(para, params, tempMap, i);
continue;
} else {
if (tempMap.size() > 0) {
tempMap.put(i, runText);
continue;
}
continue;
}
}
} else if (this.matcherRow(para.getParagraphText())) {
runs = para.getRuns();
data = true;
}
return data;
}
/**
* 填充run内容
*
* @param para
* @param params
* @param tempMap
* @throws InvalidFormatException
* @throws IOException
* @throws Exception
*/
@SuppressWarnings("rawtypes")
private void fillBlock(XWPFParagraph para, Map<String, Object> params,
Map<Integer, String> tempMap, int index)
throws InvalidFormatException, IOException, Exception {
Matcher matcher;
if (tempMap != null && tempMap.size() > 0) {
String wholeText = "";
List<Integer> tempIndexList = new ArrayList<Integer>();
for (Map.Entry<Integer, String> entry : tempMap.entrySet()) {
tempIndexList.add(entry.getKey());
wholeText += entry.getValue();
}
if (wholeText.equals("")) {
return;
}
matcher = this.matcher(wholeText);
if (matcher.find()) {
boolean isPic = false;
int width = 0;
int height = 0;
int picType = 0;
String path = null;
String keyText = matcher.group().substring(2, matcher.group().length() - 1);
Object value = params.get(keyText);
String newRunText = "";
if (value instanceof String) {
newRunText = matcher.replaceFirst(String.valueOf(value));
} else if (value instanceof Map) {//插入图片
isPic = true;
Map pic = (Map) value;
width = Integer.parseInt(pic.get("width").toString());
height = Integer.parseInt(pic.get("height").toString());
picType = getPictureType(pic.get("type").toString());
path = pic.get("path").toString();
}
//模板样式
XWPFRun tempRun = null;
// 直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,
// 所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。
for (Integer pos : tempIndexList) {
tempRun = para.getRuns().get(pos);
tempRun.setText("", 0);
}
if (isPic) {
//addPicture方法的最后两个参数必须用Units.toEMU转化一下
//para.insertNewRun(index).addPicture(getPicStream(path), picType, "测试",Units.toEMU(width), Units.toEMU(height));
tempRun.addPicture(getPicStream(path), picType, "测试", Units.toEMU(width), Units.toEMU(height));
} else {
//样式继承
if (newRunText.indexOf("\n") > -1) {
String[] textArr = newRunText.split("\n");
if (textArr.length > 0) {
//设置字体信息
String fontFamily = tempRun.getFontFamily();
int fontSize = tempRun.getFontSize();
//logger.info("------------------"+fontSize);
for (int i = 0; i < textArr.length; i++) {
if (i == 0) {
tempRun.setText(textArr[0], 0);
} else {
if (StringUtils.isNotEmpty(textArr[i])) {
XWPFRun newRun = para.createRun();
//设置新的run的字体信息
newRun.setFontFamily(fontFamily);
if (fontSize == -1) {
newRun.setFontSize(10);
} else {
newRun.setFontSize(fontSize);
}
newRun.addBreak();
newRun.setText(textArr[i], 0);
}
}
}
}
} else {
tempRun.setText(newRunText, 0);
}
}
}
tempMap.clear();
}
}
/**
* Clone Object
*
* @param obj
* @return
* @throws Exception
*/
@SuppressWarnings("unused")
private Object cloneObject(Object ob