All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.loocme.utils.WordUtil Maven / Gradle / Ivy

There is a newer version: 7.1.11
Show newest version
package com.loocme.utils;

import com.loocme.sys.constance.DateFormatConst;
import com.loocme.sys.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;

import java.io.*;
import java.util.*;

@Slf4j
public class WordUtil
{

    public static boolean fillTemplate(OutputStream outputStream, InputStream templateInputStream, Map params)
    {
        try
        {
            XWPFDocument document = new XWPFDocument(templateInputStream);
            Iterator paragraphsIt = document.getParagraphsIterator();
            while (paragraphsIt.hasNext())
            {
                XWPFParagraph paragraph = paragraphsIt.next();
                List matches = matchValue(paragraph);
                if (ListUtil.isNotNull(matches))
                {
                    replaceMapValue(paragraph, matches, params);
                }
            }

            Iterator tableIt = document.getTablesIterator();
            while (tableIt.hasNext())
            {
                XWPFTable table = tableIt.next();
                String text = table.getText();
                if (isMapMatch(text))
                {
                    replaceMapValue(table, params);
                }
                else if (isListMatch(text))
                {
                    replaceListValue(table, params);
                }
            }

            document.write(outputStream);
            return true;
        }
        catch (IOException e)
        {
            log.error("create word by template failed. ", e);
            return false;
        }
    }

    public static void main(String[]  args) throws Exception
    {
        Map params = new HashMap<>();
        Map>> datas = new HashMap<>();
        params.put("test1", "aaa");
        params.put("test2", "中文");
        params.put("test3", "ab测试&!*#");
        params.put("test4", ")(#特殊字符_ _+!");
        params.put("abc", "甲方名称");
        params.put("def", "乙方名称");
        params.put("ppp", -12);
        params.put("extension_b", 100392.3);
        List> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Map map = new HashMap<>();
            map.put("num", i + 1);
            map.put("no", "车牌" + i);
            map.put("time", DateUtil.getFormat(new Date(), DateFormatConst.YMDHMS_));
            map.put("mm", 123);
            map.put("nn", "abc");
            list.add(map);
        }
        params.put("data", list);

        fillTemplate(
                new FileOutputStream(new File("/Users/liuchi/Downloads/test1/word模板测试_result.docx")),
                new FileInputStream(new File("/Users/liuchi/Downloads/test1/word模板测试.docx")),
                params
        );

//        XWPFDocument document = new XWPFDocument(new FileInputStream(new File("/Users/liuchi/Downloads/test1/word模板测试.docx")));
//        Iterator paragraphsIt = document.getParagraphsIterator();
//        while (paragraphsIt.hasNext())
//        {
//            XWPFParagraph paragraph = paragraphsIt.next();
//            List matches = matchValue(paragraph);
//            if (ListUtil.isNotNull(matches))
//            {
//                replaceMapValue(paragraph, matches, params);
//            }
//        }
//
//        Iterator tableIt = document.getTablesIterator();
//        while (tableIt.hasNext())
//        {
//            XWPFTable table = tableIt.next();
//            String text = table.getText();
//            if (isMapMatch(text))
//            {
//                replaceMapValue(table, params);
//            }
//            else if (isListMatch(text))
//            {
//                replaceListValue(table, params);
//            }
//        }
//
//        document.write(new FileOutputStream(new File("/Users/liuchi/Downloads/test1/word模板测试_result.docx")));
    }

    private static List matchValue(XWPFParagraph paragraph)
    {
        return PatternUtil.getMatches(paragraph.getText(), "\\$\\{([^\\}]+)\\}");
    }
    private static boolean isMapMatch(String text)
    {
        return PatternUtil.isMatch(text, "\\$\\{([^\\}\\.]+)\\}");
    }
    private static boolean isListMatch(String text)
    {
        return PatternUtil.isMatch(text, "\\$\\{([^\\}\\.]+)\\.([^\\}\\.]+)\\}");
    }
    private static void replaceMapValue(XWPFParagraph paragraph, List matches, Map params)
    {
        List runs = paragraph.getRuns();
        if (ListUtil.isNull(runs) || ListUtil.isNull(matches))
            return;

        int matchIdx = 0;
        String[] currMatchArr = matches.get(matchIdx);
        if (null == currMatchArr || currMatchArr.length <= 1)
            return;
        String currMatch = currMatchArr[0];
        String currMatchValue = currMatchArr[1];

        for (int i = 0; i < runs.size(); i++)
        {
            if (StringUtil.isNull(currMatch))
                break;

            XWPFRun run = runs.get(i);
            String text = run.text();
            boolean replaced = false;
            while (StringUtil.isNotNull(currMatch) && text.contains(currMatch))
            {
                text = text.replace("${" + currMatchValue + "}", MapUtil.getString(params, currMatchValue));
                replaced = true;
                if (++ matchIdx < matches.size())
                {
                    currMatchArr = matches.get(matchIdx);
                    currMatch = currMatchArr[0];
                    currMatchValue = currMatchArr[1];
                }
                else
                {
                    currMatchArr = null;
                    currMatch = "";
                }
            }
            if (text.contains("${"))
            {
                int keyLength = currMatchValue.length();
                keyLength -= (text.length() - text.indexOf("${") - 3);
                while (keyLength > 0)
                {
                    if (i == runs.size() - 1)
                        break;
                    int nextI = i + 1;
                    String nextText = runs.get(nextI).text();
                    paragraph.removeRun(nextI);
                    keyLength -= nextText.length();
                    text += nextText;
                }
                if (text.contains(currMatch))
                {
                    text = text.replace("${" + currMatchValue + "}", MapUtil.getString(params, currMatchValue));
                    replaced = true;
                    if (++ matchIdx < matches.size())
                    {
                        currMatchArr = matches.get(matchIdx);
                        currMatch = currMatchArr[0];
                        currMatchValue = currMatchArr[1];
                    }
                    else
                    {
                        currMatchArr = null;
                        currMatch = "";
                    }
                }
            }
            if (replaced)
            {
                run.setText(text, 0);
            }
        }
    }

    private static void replaceMapValue(XWPFTable table, Map params)
    {
        List rows = table.getRows();
        if (ListUtil.isNull(rows))
            return;

        for (int i = 0; i < rows.size(); i++)
        {
            XWPFTableRow row = rows.get(i);
            List cells = row.getTableCells();
            if (ListUtil.isNull(cells))
                continue;
            for (int j = 0; j < cells.size(); j++)
            {
                XWPFTableCell cell = cells.get(j);
                String text = cell.getText();
                if (isMapMatch(text))
                {
                    List paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs)
                    {
                        List paraMatches = matchValue(paragraph);
                        if (ListUtil.isNotNull(paraMatches))
                        {
                            replaceMapValue(paragraph, paraMatches, params);
                        }
                    }
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    private static void replaceListValue(XWPFTable table, Map params)
    {
        String key = PatternUtil.getMatch(table.getText(), "\\$\\{([^\\}\\.]+)\\.([^\\}\\.]+)\\}", 0, 1);
        if (StringUtil.isNull(key) || !params.containsKey(key))
            return;
        Object keyValue = params.get(key);
        if (!(keyValue instanceof List))
            return;
        List> list = (List>) params.get(key);

        List rows = table.getRows();
        if (ListUtil.isNull(rows))
            return;

        int templatePoi = -1;
        CTRow templateCtRow = null;
        for (int i = 0; i < rows.size(); i++)
        {
            XWPFTableRow row = rows.get(i);
            List cells = row.getTableCells();
            if (ListUtil.isNull(cells))
                continue;
            for (int j = 0; j < cells.size(); j++)
            {
                XWPFTableCell cell = cells.get(j);
                String text = cell.getText();
                if (isListMatch(text))
                {
                    templatePoi = i;
                    templateCtRow = row.getCtRow();
                    break;
                }
            }
            if (templatePoi >= 0)
                break;
        }

        if (0 > templatePoi)
            return;

        int currPoi = templatePoi + 1;
        for (int i = 0; i < list.size(); i++)
        {
            Map map = list.get(i);
            Map cellParams = new HashMap<>();
            map.forEach((k, v) -> {
                cellParams.put(key + "." + k, v);
            });
            CTRow ctRow = (CTRow) templateCtRow.copy();
            XWPFTableRow row = new XWPFTableRow(ctRow, table);
            List cells = row.getTableCells();
            for (int j = 0; j < cells.size(); j++)
            {
                XWPFTableCell cell = cells.get(j);
                String text = cell.getText();
                if (isListMatch(text))
                {
                    List paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs)
                    {
                        List paraMatches = matchValue(paragraph);
                        if (ListUtil.isNotNull(paraMatches))
                        {
                            replaceMapValue(paragraph, paraMatches, cellParams);
                        }
                    }
                }
            }
            table.addRow(row, currPoi ++);
        }
        table.removeRow(templatePoi);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy