引入资源库
implementation 'org.apache.poi:poi:4.1.2'
implementation 'org.apache.poi:poi-ooxml:4.1.2'
implementation 'org.apache.poi:poi-ooxml-schemas:4.1.2'
public void test(HttpServletResponse response){
try {
//定义一个Entity放要输出的数据
EditWordEntity report = new EditWordEntity();
report.setMonth("April");
report.setCode("202102");
report.setTestDate("2020-04-01 to 2020-04-31");
report.setAAAAA("aaaaaaa");
report.setBBBBB("bbbbbbb");
Map<String, String> replaceMap = new HashMap<>();
replaceMap.put("month", report.getMonth());
replaceMap.put("code", report.getCode());
replaceMap.put("testDate", report.getTestDate());
replaceMap.put("AAAAA", report.getAAAAA());
replaceMap.put("BBBBB", report.getBBBBB());
PoiEditWord poiEditWord = new PoiEditWord();
poiEditWord.downloadReportFile("test poi.docx", replaceMap, response);
} catch (IOException e) {
e.printStackTrace();
}
public class PoiEditWord {
public void downloadReportFile(String fileName, Map<String, String> replaceMap, HttpServletResponse response) throws IOException {
InputStream in = null;
XWPFDocument document = null;
response.reset();
response.setContentType("application/x-msdownload");
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
OutputStream os = null;
try {
response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
//找到项目中模板文件的位置
in = Thread.currentThread().getContextClassLoader().getResourceAsStream("test poi.docx");
//获取docx解析对象
document = new XWPFDocument(in);
WordUtil.changeText(document, replaceMap);
os = response.getOutputStream();
document.write(os);
os.write(ostream.toByteArray());os.close();ostream.close();
} catch (IOException e) { e.printStackTrace(); }
finally {
try {
if (in != null) { in.close(); }
if (document != null) { document.close(); }
if (os != null) { os.close(); }
if (ostream != null) { ostream.close(); }
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//工具类
public class WordUtil {
/**
* 遍历文本
*
* @param document docx解析对象
*/
public static void traverse(XWPFDocument document) {
//获取文档中各段落集合
List<XWPFParagraph> paragraphs = document.getParagraphs();
//遍历各段落
for (XWPFParagraph paragraph : paragraphs) {
//判断此段落时候需要进行替换
String text = paragraph.getText();
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
// TODO 处理文本
}
}
}
/**
* 替换段落文本
*
* @param document docx解析对象
* @param textMap 需要替换的信息集合
*/
public static void changeText(XWPFDocument document, Map<String, String> 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) {
//替换模板原来位置
run.setText(changeValue(run.toString(), textMap), 0);
}
}
}
replaceTableValue(document, textMap);
}
public static void replaceTableValue(XWPFDocument document, Map<String, String> textMap){
Iterator<XWPFTable> it = document.getTablesIterator();
//表格内容替换添加
while(it.hasNext()){
XWPFTable table = it.next();
int rcount = table.getNumberOfRows();
for(int i =0 ;i < rcount;i++){
XWPFTableRow row = table.getRow(i);
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells){
for(Map.Entry<String, String> e : textMap.entrySet()){
if(checkText(cell.getText())){
List<XWPFParagraph> tableParagraphsList = cell.getParagraphs();
for (XWPFParagraph paragraph : tableParagraphsList) {
String text = paragraph.getText(); //获取到段落中的所有文本内容
if (checkText(text)) { //判断此段落中是否有需要进行替换的文本
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
run.setText(changeValue(run.toString(), textMap), 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 (value.contains(key)) {
value = textSet.getValue();
}
}
//模板未匹配到区域替换为空
if (checkText(value)) {
value = "";
}
return value;
}
/**
* 为表格插入数据,行数不够添加新行
*
* @param table 需要插入数据的表格
* @param tableList 插入数据集合
*/
public static void insertTable(XWPFTable table, List<String[]> tableList) {
//创建行,根据需要插入的数据添加新行,不处理表头
for (int i = 1; i < tableList.size(); i++) {
table.createRow();
}
//遍历表格插入数据
List<XWPFTableRow> rows = table.getRows();
for (int i = 1; i < rows.size(); i++) {
XWPFTableRow newRow = table.getRow(i);
List<XWPFTableCell> cells = newRow.getTableCells();
for (int j = 0; j < cells.size(); j++) {
XWPFTableCell cell = cells.get(j);
cell.setText(tableList.get(i - 1)[j]);
}
}
}
// 给生成的表格设置样式
public static void setCellWitchAndAlign(XWPFTableCell cell, String width, STVerticalJc.Enum typeEnum, STJc.Enum align){
CTTc cttc = cell.getCTTc();
CTTcPr ctPr = cttc.addNewTcPr();
ctPr.addNewVAlign().setVal(typeEnum);
cttc.getPList().get(0).addNewPPr().addNewJc().setVal(align);
CTTblWidth ctTblWidth = (ctPr != null && ctPr.isSetTcW() && ctPr.getTcW()!=null &&ctPr.getTcW().getW()!=null) ? ctPr.getTcW(): ctPr.addNewTcW();
if(StringUtils.isNotBlank(width)){
ctTblWidth.setW(new BigInteger(width));
ctTblWidth.setType(STTblWidth.DXA);
}
}
}
最终下载文件效果如图:
参考:https://www.cnblogs.com/bb1008/p/10605943.html