SpringBoot-Poi-Word

x33g5p2x  于2021-09-22 转载在 Spring  
字(9.1k)|赞(0)|评价(0)|浏览(326)

SpringBoot-Poi-Word

不多解释看代码就明白了

  1. 先准备一个word模板 doc 和docx都行
  2. 给模板空值添加占位符
  3. 使用poi给占位置赋值

Maven

<dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-scratchpad</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-examples</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-excelant</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>4.0.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.xmlbeans</groupId>
        <artifactId>xmlbeans</artifactId>
        <version>3.0.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>ooxml-schemas</artifactId>
        <version>1.1</version>
        <type>pom</type>
    </dependency>

    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.9.3</version>
    </dependency>

准备word模板

因为是演示所以准备两份 为了演示 doc 和docx都支持

文件内容如下:

${} 就是占位符 { } 内的是变量用于使用poi时候替换成实际值

将模板放入resources下面

word-poi工具类

package com.word.utils;

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.xwpf.usermodel.*;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WordTemplateParse {

   public enum WordType {
        doc, docx
    }

    /** * * @param data 替换的数据 * @param tempFileStream 模板文件 * @param targetFileStream 输出的文件 * @param type 文件;类型 * @return */
    public static Boolean generate(Map<String, String> data, String  tempFileStream, String targetFileStream, WordType type) throws FileNotFoundException {

        try {
            InputStream in=new FileInputStream(tempFileStream);
            OutputStream outputStream=  new FileOutputStream(targetFileStream);
            if (WordType.docx.equals(type) ) {
                return generate_docx(data, in, outputStream);
            } else if (WordType.doc.equals(type)){
                return generate_doc(data, in, outputStream);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return  false;
    }

   private static Boolean generate_docx(Map<String, String> data, InputStream tempFileStream, OutputStream targetFileStream) {
        try {
            // 加载磁盘的 temp.docx 文件
            XWPFDocument document = new XWPFDocument(tempFileStream);

            // 解析文档中的【段落】的插值 ${..}
            List<XWPFParagraph> paragraphs = document.getParagraphs();
            for (XWPFParagraph paragraph : paragraphs) {
                String text = paragraph.getText();
                // 如果该单元格为空就遍历下一个
                if (text == null || "".equals(text)) {
                    continue;
                }

                // 得到解析 ${...} 后的内容
                String newText = replaceByMap(text, null, data);
                // 判断值是否改变,如果没有改变就不做处理
                if (!text.equals(newText)) {
                    int runSize = paragraph.getRuns().size();
                    // 清空该段落所有值
                    for (int i = 0; i < runSize; i++) {
                        paragraph.removeRun(i);
                    }

                    XWPFRun run = paragraph.createRun();
                    run.setText(newText);
                }

            }

            // 解析文档中【表格】的插值 ${..}
            // 获取文档中的表格
            List<XWPFTable> tables = document.getTables();
            for (XWPFTable table : tables) {
                // 得到所有行的集合并遍历
                List<XWPFTableRow> rows = table.getRows();
                for (XWPFTableRow row : rows) {
                    // 得到所有列的集合并遍历
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        // 获取整个单元格的值
                        String text = cell.getText();
                        // 如果该单元格为空就遍历下一个
                        if (text == null || "".equals(text)) {
                            continue;
                        }

                        // 得到解析 ${...} 后的内容
                        String newText = replaceByMap(text, null, data);
                        // 判断值是否改变,如果没有改变就不做处理
                        if (!text.equals(newText)) {
                            // 清空单元格内容
                            int paragraphsNums = cell.getParagraphs().size();
                            for (int i = 0; i < paragraphsNums; i++) {
                                cell.removeParagraph(i);
                            }
                            cell.setText(newText);
                        }
                    }
                }
            }

            // 将文档写入目标文件中
            document.write(targetFileStream);
            // 关闭流
            tempFileStream.close();
            targetFileStream.close();
            document.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    private static Boolean generate_doc(Map<String, String> data, InputStream tempFileStream, OutputStream targetFileStream) {

        try {
            // 加载磁盘的 temp.docx 文件
            HWPFDocument document = new HWPFDocument(tempFileStream);
            Range range = document.getRange();
            //把range范围内的${reportDate}替换为当前的日期
            for (Map.Entry<String, String> stringStringEntry : data.entrySet()) {

                range.replaceText("${" + stringStringEntry.getKey() + "}", stringStringEntry.getValue());

            }

            //把doc输出到输出流中
            document.write(targetFileStream);

            targetFileStream.close();
            tempFileStream.close();
            document.close();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    // 如果根据正则表达式规则匹配成功则替换,否则返回原值
    private static String replaceByMap(String content, String regex, Map<String, String> map) {
        // 匹配插值 ${...}
        if (regex == null) {
            regex = "\\$\\{[\\w\\W]+\\}";
        }

        // 初始化正则
        Pattern p = Pattern.compile(regex);
        Matcher matcher = p.matcher(content);

        // 找到匹配的内容的 key
        if (matcher.find()) {
            // 提前key值
            String matchContent = matcher.group(0);
            int start = matchContent.indexOf("{");
            int end = matchContent.indexOf("}");

            // 获取key
            String key = matchContent.substring(start + 1, end);

            // 从map中取出key的值
            String value = map.get(key);
            if (value == null) {
                return content;
            }

            // 得到替换后的值
            String newContent = matcher.replaceAll(value);
            return newContent;
        }

        // 没有匹配到,返回原值
        return content;
    }

}

获取resources的路径工具类

package com.word.utils;

import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;

/** * @Description: 项目静态资源文件工具类 * 仅可用于包含在web项目中的资源文件路径,资源文件必须放置于 web 模块下 * @Author: junqiang.lu * @Date: 2019/1/4 */
public class ResourceFileUtil {

    /** * 获取资源绝对路径 (就只使用这个 ) * * @param relativePath 资源文件相对路径(相对于 resources路径,路径 + 文件名) * eg: "templates/pdf_export_demo.ftl" * @return * @throws FileNotFoundException */
    public static String getAbsolutePath(String relativePath) throws FileNotFoundException {
        return getFile(relativePath).getAbsolutePath();
    }

    /** * 获取资源文件 * * @param relativePath 资源文件相对路径(相对于 resources路径,路径 + 文件名) * eg: "templates/pdf_export_demo.ftl" * @return * @throws FileNotFoundException */
    public static File getFile(String relativePath) throws FileNotFoundException {
        if (relativePath == null || relativePath.length() == 0) {
            return null;
        }
        if (relativePath.startsWith("/")) {
            relativePath = relativePath.substring(1);
        }
        File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX
                + relativePath);

        return file;
    }


    /** * 获取资源父级目录 * * @param relativePath 资源文件相对路径(相对于 resources路径,路径 + 文件名) * eg: "templates/pdf_export_demo.ftl" * @return * @throws FileNotFoundException */
    public static String getParent(String relativePath) throws FileNotFoundException {
        return getFile(relativePath).getParent();
    }

    /** * 获取资源文件名 * * @param relativePath 资源文件相对路径(相对于 resources路径,路径 + 文件名) * eg: "templates/pdf_export_demo.ftl" * @return * @throws FileNotFoundException */
    public static String getFileName(String relativePath) throws FileNotFoundException {
        return getFile(relativePath).getName();
    }

}

测试

package com.word.utils;

import org.junit.Test;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class WordTemplateParseText {

    @Test
    public void test01() throws FileNotFoundException {
        // 数据
        TreeMap<String, String> data = new TreeMap<String, String>();
        data.put("yue1", "33");
        data.put("yue2", "22");
        data.put("yue3", "55");
        data.put("yue4", "12");
        data.put("yue5", "2");
        data.put("yue6", "151");
        data.put("yue7", "33");
        data.put("yue8", "34");
        data.put("yue9", "123");
        data.put("yue10", "15");
        data.put("yue11", "2");
        data.put("yue12", "10");

        // 加载模型【模型】
        String absolutePath = ResourceFileUtil.getAbsolutePath("temp.docx"); //模板位置

        // 输出位置【输出】 生成新的word位置和模板在一个目录下
        String newabsolutePath = ResourceFileUtil.getParent("temp.docx")+ File.separator+"new_temp.docx";
        System.out.println(newabsolutePath);

        Boolean generate = WordTemplateParse.generate(data, absolutePath, newabsolutePath, WordTemplateParse.WordType.docx);
        System.out.println(generate);


    }

    @Test
    public void test011() throws IOException {
        // 数据
        TreeMap<String, String> data = new TreeMap<String, String>();
        data.put("yue1", "33");
        data.put("yue2", "22");
        data.put("yue3", "55");
        data.put("yue4", "12");
        data.put("yue5", "2");
        data.put("yue6", "151");
        data.put("yue7", "33");
        data.put("yue8", "34");
        data.put("yue9", "123");
        data.put("yue10", "15");
        data.put("yue11", "2");
        data.put("yue12", "10");

        // 加载模型【模型】
        String absolutePath = ResourceFileUtil.getAbsolutePath("temp1.doc"); //模板位置

        // 输出位置【输出】 生成新的word位置和模板在一个目录下
        String newabsolutePath = ResourceFileUtil.getParent("temp1.doc")+ File.separator+"new_temp1.doc";
        System.out.println(newabsolutePath);


        Boolean generate = WordTemplateParse.generate(data, absolutePath, newabsolutePath, WordTemplateParse.WordType.doc);
        System.out.println(generate);


    }

}

运行上面代码后会在target下面生成对应的word

相关文章

微信公众号

最新文章

更多