javaPOI实现填充Word文档中的内容并导出

本文介绍如何利用Java的POI库来填充复杂的Word文档内容,并将其导出到本地。这个过程涉及到从模板中读取结构,用数据替换占位符,最后保存为完整文档。
摘要由CSDN通过智能技术生成

#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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值