Word模板替换

Word2007格式,用于替换类似${name}格式字符,支持word内嵌表格形式,代码如下:

package com.authweb.tools.bookmarkprocess;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.impl.piccolo.io.FileFormatException;

import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static feign.Util.toByteArray;

/**
 * Created by clyyan on 2019/7/2 15:15.
 */
public class Word2007 {
    private String wordPath = "";
    private String tempFilePath = "";
    private Object obj = null;
    Map<String, Object> map = new HashMap<String, Object>();

    /*
        path:文件路径
        dataSource/objectMap:数据源.
    */
    public Word2007(String path, String userAccount, Object dataSource, Map<String, Object> objectMap) throws IOException {

        File file = new File(path);

        if (file.exists() == false || file.isFile() == false) {
            throw new FileNotFoundException("文件不存在");
        }

        InputStream is = new FileInputStream(file);
        byte[] bytes = new byte[10];

        if (is.read(bytes, 0, bytes.length) == -1) {
            is.close();
            throw new FileFormatException("文件格式错误,本文件只能解析docx文件");
        }
        String fileCode = bytesToHexString(bytes).toLowerCase();

        if (fileCode.length() > 1) {
            if (fileCode.equals("504b0304140006000800") == false) {
                is.close();
                throw new FileFormatException("文件格式错误,本文件只能解析docx文件");
            }
        }
        is.close();

        wordPath = path;
        obj = dataSource;
        File testFile = new File(path.substring(0, path.lastIndexOf("\\")) + "\\" + "文书-" + userAccount + "\\");
        if (!testFile.exists()) {
            testFile.mkdirs();
        }
        tempFilePath = path.substring(0, path.lastIndexOf("\\")) + "\\" + "文书-" + userAccount + "\\" + path.substring(path.lastIndexOf("\\") + 1);

        if (dataSource != null) {
            pickFields();
        } else {
            this.map = objectMap;
        }
    }

    public String parseTemplate() {

        try {
            InputStream is = new FileInputStream(wordPath);
            XWPFDocument doc = new XWPFDocument(OPCPackage.open(is));
            List<XWPFParagraph> list = doc.getParagraphs();

            for (int i = 0; i < list.size(); i++) {
                XWPFParagraph graph = list.get(i);
                replaceInXWPFParagraph(graph, map);
            }
            replaceTables(map, doc);
            OutputStream os = new FileOutputStream(tempFilePath);
            doc.write(os);
            os.flush();
            close(os);
            close(is);

        } catch (Exception ex) {
            System.out.print(ex.getStackTrace());
        }
        return tempFilePath;
    }

    private void replaceInXWPFParagraph(XWPFParagraph para, Map<String, Object> params) {

        List<XWPFRun> runs = null;
        Matcher matcher;
        String runText = "";

        if (matcher(para.getParagraphText()).find()) {
            runs = para.getRuns();
            if (runs.size() > 0) {
                int j = runs.size();
                for (int i = 0; i < j; i++) {
                    XWPFRun run = runs.get(i);
                    String i1 = run.toString();
                    runText += i1;
                }
            }
            matcher = matcher(runText);
            if (matcher.find()) {
                while ((matcher = matcher(runText)).find()) {
                    runText = String.valueOf(params.get(matcher.group(1)));
                }
                //数据源不存在时跳过,以便检查
                if (runText != "null" && runs.size() > 0) {
                    boolean handler = false;
                    for (int i = 0; i < runs.size(); i++) {

                        XWPFRun run = runs.get(i);
                        String temp = run.toString();

                        if (handler == false && temp.indexOf("$") >= 0) {
                            handler = true;
                        }
                        if (handler == true) {
                            if (temp.equals("$") || temp.indexOf("$") == 0) {
                                if (temp.indexOf("}") >= 0) {
                                    run.setText(runText, 0);
                                    handler = false;
                                } else {
                                    run.setText("", 0);
                                }
                                continue;
                            }
                            if (temp.indexOf("}") < 0) {
                                run.setText("", 0);
                                continue;
                            }
                            if (temp.indexOf("}") >= 0) {
                                run.setText(runText, 0);
                                handler = false;
                            }
                        }
                    }
                }
            }
        }
    }

    private void pickFields() {
        Class dataClass = (Class) obj.getClass();
        Field[] fs = dataClass.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            f.setAccessible(true);
            Object val = new Object();
            try {
                val = f.get(obj);
                map.put(f.getName(), val);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    private byte[] generalFileContent() throws IOException {
        InputStream is = new FileInputStream(tempFilePath);
        byte[] data = toByteArray(is);
        is.close();
        return data;
    }

    private void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (null == src || src.length < 1)
            return null;
        for (byte b : src) {
            int v = b & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2)
                stringBuilder.append(0);
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    private static Matcher matcher(String str) {
        Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }

    private void replaceTable(Map<String, Object> params, XWPFTable table) {
        int count = table.getNumberOfRows();
        for (int i = 0; i < count; i++) {
            XWPFTableRow row = table.getRow(i);
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                List<XWPFParagraph> list = cell.getParagraphs();
                for (int j = 0; j < list.size(); j++) {
                    replaceInXWPFParagraph(list.get(j), params);
                }
            }
        }
    }

    private void replaceTables(Map<String, Object> params, XWPFDocument document) {
        Iterator<XWPFTable> itTable = document.getTablesIterator();
        while (itTable.hasNext()) {
            XWPFTable table = itTable.next();
            replaceTable(params, table);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/jizhong/p/11423002.html