java POI 导出到word文档 (附工具类)
阅读原文时间:2023年07月10日阅读:5

1,导入poi相关依赖

org.apache.poi poi-ooxml 4.0.1
org.apache.poi poi-scratchpad 4.0.1

2,直接附工具类,注解很详细

package com.hl.bluetooth.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @author hwx
* @date 2021-9-22 11:31:09
*/
public class WordUtils {
/**
* 根据模板生成word
*
* @param path 模板的路径
* @param params 需要替换的参数 (静态替换 格式 params.put("${releaeTime}", releaeTime);)
* @param tableList 需要插入的参数 (动态替换)
* @param fileName 生成word文件的文件名
* @param response
*/
public void getWord(String path, Map params, List tableList, String fileName, HttpServletResponse response) throws Exception {
File file = new File(path);
InputStream is = new FileInputStream(file);
XWPFDocument doc = new XWPFDocument(is);
this.createHeader(doc, (String) params.get("${id}")); //设置页眉
this.replaceInPara(doc, params); //替换文本里面的变量
this.replaceInTable(doc, params, tableList); //替换表格里面的变量
List tables = doc.getTables();
XWPFTable xwpfTable = tables.get(4);
insertTable(xwpfTable, tableList); //插入数据

    OutputStream os = response.getOutputStream();  
    response.setHeader("Content-disposition", "attachment; filename=" + fileName);  
    doc.write(os);  
    this.close(os);  
    this.close(is);

}

/\*\*  
 \* description: 添加不带图片的页眉  
 \* create by: hwx  
 \* create time: 2021-10-8 15:01:16  
 \*/  
public void createHeader(XWPFDocument docx, String orgFullName) throws Exception {

    CTP ctp = CTP.Factory.newInstance();  
    XWPFParagraph paragraph = new XWPFParagraph(ctp, docx);//段落对象  

// ctp.addNewR().addNewT().setStringValue("山东电力研究院检测报告 报告编号:"+orgFullName);//设置页眉参数
if (StringUtils.isNotEmpty(orgFullName)) {
XWPFRun run = paragraph.createRun();
run.setText(" 山东电力研究院检测报告 报告编号:" + orgFullName);
setXWPFRunStyle(run, "黑体", 11);
}

    ctp.addNewR().addNewT().setSpace(SpaceAttribute.Space.PRESERVE);  
    CTSectPr sectPr = docx.getDocument().getBody().isSetSectPr() ? docx.getDocument().getBody().getSectPr() : docx.getDocument().getBody().addNewSectPr();  
    XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(docx, sectPr);  
    XWPFHeader header = policy.createHeader(STHdrFtr.DEFAULT, new XWPFParagraph\[\]{paragraph});  
    header.setXWPFDocument(docx);

}

/\*\*  
 \* 设置页脚的字体样式  
 \*  
 \* @param r1 段落元素  
 \*/  
private void setXWPFRunStyle(XWPFRun r1, String font, int fontSize) {  
    r1.setFontSize(fontSize);  
    CTRPr rpr = r1.getCTR().isSetRPr() ? r1.getCTR().getRPr() : r1.getCTR().addNewRPr();  
    CTFonts fonts = rpr.isSetRFonts() ? rpr.getRFonts() : rpr.addNewRFonts();  
    fonts.setAscii(font);  
    fonts.setEastAsia(font);  
    fonts.setHAnsi(font);  
}

/\*\*  
 \* 替换段落里面的变量  
 \*  
 \* @param doc    要替换的文档  
 \* @param params 参数  
 \*/  
private void replaceInPara(XWPFDocument doc, Map<String, Object> params) {  
    Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();  
    XWPFParagraph para;  
    while (iterator.hasNext()) {  
        para = iterator.next();  
        this.replaceInPara(para, params, doc);  
    }  
}

/\*\*  
 \* 替换段落里面的变量  
 \*  
 \* @param para   要替换的段落  
 \* @param params 参数  
 \*/  
private void replaceInPara(XWPFParagraph para, Map<String, Object> params, XWPFDocument doc) {  
    List<XWPFRun> runs;  
    Matcher matcher;  
    if (this.matcher(para.getParagraphText()).find()) {  
        runs = para.getRuns();  
        int start = -1;  
        int end = -1;  
        String str = "";  
        for (int i = 0; i < runs.size(); i++) {  
            XWPFRun run = runs.get(i);  
            String runText = run.toString();  
            if ('$' == runText.charAt(0) && '{' == runText.charAt(1)) {  
                start = i;  
            }  
            if ((start != -1)) {  
                str += runText;  
            }  
            if ('}' == runText.charAt(runText.length() - 1)) {  
                if (start != -1) {  
                    end = i;  
                    break;  
                }  
            }  
        }

        for (int i = start; i <= end; i++) {  
            para.removeRun(i);  
            i--;  
            end--;  
        }

        for (Map.Entry<String, Object> entry : params.entrySet()) {  
            String key = entry.getKey();  
            if (str.indexOf(key) != -1) {  
                Object value = entry.getValue();  
                if (value instanceof String) {  
                    str = str.replace(key, value.toString());  
                    para.createRun().setText(str, 0);  
                    break;  
                } else if (value instanceof Map) {  
                    str = str.replace(key, "");  
                    Map pic = (Map) value;  
                    int width = Integer.parseInt(pic.get("width").toString());  
                    int height = Integer.parseInt(pic.get("height").toString());  
                    int picType = getPictureType(pic.get("type").toString());  
                    byte\[\] byteArray = (byte\[\]) pic.get("content");  
                    ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);  
                    try {  
                        //int ind = doc.addPicture(byteInputStream,picType);  
                        //doc.createPicture(ind, width , height,para);  
                        doc.addPictureData(byteInputStream, picType);  

// doc.createPicture(doc.getAllPictures().size() - 1, width, height, para);
para.createRun().setText(str, 0);
break;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

    }  
}

/\*\*  
 \* 为表格插入数据,行数不够添加新行  
 \*  
 \* @param table     需要插入数据的表格  
 \* @param tableList 插入数据集合  
 \*/  
private static void insertTable(XWPFTable table, List<String\[\]> tableList) {  
    //创建行,根据需要插入的数据添加新行,不处理表头  

/* for (int i = 0; i < tableList.size(); i++) { XWPFTableRow row = table.createRow(); } //遍历表格插入数据 List rows = table.getRows();
int length = table.getRows().size();
for (int i = 1; i < length - 1; i++) { XWPFTableRow newRow = table.getRow(i); List cells = newRow.getTableCells();
for (int j = 0; j < cells.size(); j++) {
XWPFTableCell cell = cells.get(j);
String s = tableList.get(i - 1)[j];
cell.setText(s);
}
}*/

    //创建行和创建需要的列  
    for (int i = 1; i < tableList.size(); i++) {  
        //添加一个新行  
        XWPFTableRow row = table.insertNewTableRow(1);  
        for (int k = 0; k < tableList.get(0).length; k++) {  
            row.createCell();//根据String数组第一条数据的长度动态创建列  
        }  
    }

    //创建行,根据需要插入的数据添加新行,不处理表头  
    for (int i = 0; i < tableList.size(); i++) {  
        List<XWPFTableCell> cells = table.getRow(i + 1).getTableCells();  
        for (int j = 0; j < cells.size(); j++) {  
            XWPFTableCell cell02 = cells.get(j);  
            cell02.setText(tableList.get(i)\[j\]);  
        }  
    }

}

/\*\*  
 \* 替换表格里面的变量  
 \*  
 \* @param doc    要替换的文档  
 \* @param params 参数  
 \*/  
private void replaceInTable(XWPFDocument doc, Map<String, Object> params, List<String\[\]> tableList) {  
    Iterator<XWPFTable> iterator = doc.getTablesIterator();  
    XWPFTable table;  
    List<XWPFTableRow> rows;  
    List<XWPFTableCell> cells;  
    List<XWPFParagraph> paras;  
    while (iterator.hasNext()) {  
        table = iterator.next();  
        if (table.getRows().size() > 0) {  
            //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入  
            if (this.matcher(table.getText()).find()) {  
                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, doc);  
                        }  
                    }  
                }  
            } else {  
                insertTable(table, tableList);  //插入数据  
            }  
        }

    }  
}

/\*\*  
 \* 正则匹配字符串  
 \*  
 \* @param str  
 \* @return  
 \*/  
private Matcher matcher(String str) {  
    Pattern pattern = Pattern.compile("\\\\$\\\\{(.+?)\\\\}", Pattern.CASE\_INSENSITIVE);  
    Matcher matcher = pattern.matcher(str);  
    return matcher;  
}

/\*\*  
 \* 根据图片类型,取得对应的图片类型代码  
 \*  
 \* @param picType  
 \* @return int  
 \*/  
private static int getPictureType(String picType) {  
    int res = XWPFDocument.PICTURE\_TYPE\_PICT;  
    if (picType != null) {  
        if (picType.equalsIgnoreCase("png")) {  
            res = XWPFDocument.PICTURE\_TYPE\_PNG;  
        } else if (picType.equalsIgnoreCase("dib")) {  
            res = XWPFDocument.PICTURE\_TYPE\_DIB;  
        } else if (picType.equalsIgnoreCase("emf")) {  
            res = XWPFDocument.PICTURE\_TYPE\_EMF;  
        } else if (picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")) {  
            res = XWPFDocument.PICTURE\_TYPE\_JPEG;  
        } else if (picType.equalsIgnoreCase("wmf")) {  
            res = XWPFDocument.PICTURE\_TYPE\_WMF;  
        }  
    }  
    return res;  
}

/\*\*  
 \* 将输入流中的数据写入字节数组  
 \*  
 \* @param in  
 \* @return  
 \*/  
public static byte\[\] inputStream2ByteArray(InputStream in, boolean isClose) {  
    byte\[\] byteArray = null;  
    try {  
        int total = in.available();  
        byteArray = new byte\[total\];  
        in.read(byteArray);  
    } catch (IOException e) {  
        e.printStackTrace();  
    } finally {  
        if (isClose) {  
            try {  
                in.close();  
            } catch (Exception e2) {  
                e2.getStackTrace();  
            }  
        }  
    }  
    return byteArray;  
}

/\*\*  
 \* 关闭输入流  
 \*  
 \* @param is  
 \*/  
private void close(InputStream is) {  
    if (is != null) {  
        try {  
            is.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}

/\*\*  
 \* 关闭输出流  
 \*  
 \* @param os  
 \*/  
private void close(OutputStream os) {  
    if (os != null) {  
        try {  
            os.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}

}

3,对应的模板

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器