springboot整合xwpf将world转为pdf

springboot整合xwpf将world转为pdf

该案例实现:
1.读取world模版
2.动态填充world模版数据
3.将填充好的world转换为pdf

目录结构

springboot整合xwpf将world转为pdf_第1张图片

引入pom依赖

<dependency>
    <groupId>fr.opensagres.xdocreportgroupId>
    <artifactId>org.apache.poi.xwpf.converter.pdfartifactId>
    <version>1.0.6version>
dependency>

Controller

package com.example.demo.controller;

import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

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

@Controller
@RequestMapping( "/pdf" )
public class WorldToPDF4 {

    private static final Logger logger = LoggerFactory.getLogger(WorldToPDF4.class);

    @GetMapping("/pdf")
    public void test(HttpServletResponse response) throws Exception {
        logger.info("获取world模板...");
        File inputWordFile = new File("src/main/resources/templet/c.docx");
        InputStream source = new FileInputStream(inputWordFile);
        BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        PdfOptions options = PdfOptions.create();
        XWPFDocument doc = new XWPFDocument(source);
        logger.info("读取world模版成功!");

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("heroName", "司马徽");
        params.put("time", "2021-06-06");

        // 替换变量占位符 ${xxx}格式,如:${name}
        replaceParams(doc, params);
        logger.info("替换world模版动态数据成功!");
        // 转换为pdf
        PdfConverter.getInstance().convert(doc, outputStream, options);
        logger.info("转换pdf成功!");

        byte[] buffer = new byte[1024];
        int lenght = 0;
        while ((lenght = source.read(buffer)) > 0) {
            outputStream.write(buffer, 0, lenght);
        }
        close(outputStream);
        close(source);
        logger.info("下载pdf成功!");
    }

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

    /**
     * 替换段落里面的变量
     *
     * @param paragraph 要替换的段落
     * @param params    参数
     */
    private void replaceParam(XWPFParagraph paragraph, Map<String, Object> params) {
        List<XWPFRun> runs;
        Matcher matcher;
        String runText = "";

        if (matcher(paragraph.getParagraphText()).find()) {
            runs = paragraph.getRuns();
            int j = runs.size();
            for (int i = 0; i < j; i++) {
                runText += runs.get(0).toString();
                //保留最后一个段落,在这段落中替换值,保留段落样式
                if (!((j - 1) == i)) {
                    paragraph.removeRun(0);
                }
            }
            matcher = matcher(runText);
            if (matcher.find()) {
                while ((matcher = matcher(runText)).find()) {
                    runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
                }
                runs.get(0).setText(runText, 0);
            }
        }

    }

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

    /**
     * 关闭输入流
     *
     * @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();
            }
        }
    }
}

world文档内容

springboot整合xwpf将world转为pdf_第2张图片

测试

启动服务,访问接口:localhost:2080/pdf/pdf

转换出来的pdf为:
springboot整合xwpf将world转为pdf_第3张图片

控制台打印结果:
springboot整合xwpf将world转为pdf_第4张图片

抛了一个异常。没有去处理
测试OK!
这是一个简单的填充模版。如果复杂的话,需要好好设置world模版,包括排版,不然的话转换出来的pdf会走样了。

欢迎大佬们留言评论,共同学习!!!感谢!!!

===========================
原创文章,转载注明出处!

你可能感兴趣的:(技术,world转pdf)