Java 在word指定位置插入图片,生成Word后转PDF

背景:在 Word 文档的指定位置插入图片,并将 Word 文档转换为 PDF,可以使用 Apache POI 库来操作 Word 文档

准备工作:  在word文档新建一个属于自己模版,用${}占位符来表示,字段信息就是代码里返回的信息

 第一步:引入相关的依赖,依赖没给全的看代码提示自行添加

<!-- poi库 -->  
       <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>
<!-- Apache PDFBox库(用于处理PDF文件) -->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.27</version>
        </dependency>
 
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.9.0</version>
        </dependency>

 第二步: 把自己定义好的模版放到项目的resources下面,然后下面就是业务代码和一些工具    类,直接拿来用就可以了

 

第三步:用到的工具类代码,分别是 替换文本和转换PDF工具类

public class ReplaceWordUtils {


    /**
     * 执行文本和图片替换的方法
     *
     * @param data        文本数据
     * @param picData     图片数据
     * @param outWordFile Word生成地址
     */
    public static void operateWord(Map<String, Object> data, Map<String, Object> picData, String outWordFile) {
        try {
            //指定Word模板文件
            FileInputStream is = new FileInputStream(outWordFile);
            XWPFDocument document = new XWPFDocument(is);
            if (data.size() > 0) {
                // 替换掉表格之外的文本(仅限文本)
                ReplaceWordUtils.changeText(document, data);
                // 替换表格内的文本对象
                ReplaceWordUtils.changeTableText(document, data);
            }
            if (picData.size() > 0) {
                // 替换内容图片
                ReplaceWordUtils.changePic(document, picData);
                // 替换表格内的图片对象
                ReplaceWordUtils.changeTablePic(document, picData);
            }
            //导出替换后的文件
            FileOutputStream out = new FileOutputStream(outWordFile);
            document.write(out);
            is.close();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /***
     * @Description :替换段落文本
     * @param document docx解析对象
     * @param textMap  需要替换的信息集合
     * @return void
     * @Date 2022/11/17 17:22
     */
    public static void changeText(XWPFDocument document, Map<String, Object> textMap) {
        // 获取段落集合
        Iterator<XWPFParagraph> iterator = document.getParagraphsIterator();
        XWPFParagraph paragraph = null;
        while (iterator.hasNext()) {
            paragraph = iterator.next();
            // 判断此段落是否需要替换
            if (checkText(paragraph.getText())) {
                replaceValue(paragraph, textMap);
            }
        }
    }

    /***
     * @Description :检查文本中是否包含指定的字符(此处为“$”)
     * @param text
     * @return boolean
     * @Date 2022/11/17 17:22
     */
    public static boolean checkText(String text) {
        boolean check = false;
        if (text.contains("$")) {
            check = true;
        }
        return check;
    }

    /**
     * 替换图片
     *
     * @param document
     * @param picData
     * @throws Exception
     */

    public static void changePic(XWPFDocument document, Map<String, Object> picData) throws Exception {
        // 获取段落集合
        Iterator<XWPFParagraph> iterator = document.getParagraphsIterator();
        XWPFParagraph paragraph;
        while (iterator.hasNext()) {
            paragraph = iterator.next();
            // 判断此段落是否需要替换
            String text = paragraph.getText();
            if (checkText(text)) {
                replacePicValue(paragraph, picData);
            }
        }
    }

    /***
     * @Description :替换表格内的文字
     * @param document
     * @param data
     * @return void
     * @Date 2022/11/18 11:29
     */
    public static void changeTableText(XWPFDocument document, Map<String, Object> data) {
        // 获取文件的表格
        Iterator<XWPFTable> tableList = document.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        // 循环所有需要进行替换的文本,进行替换
        while (tableList.hasNext()) {
            table = tableList.next();
            if (checkText(table.getText())) {
                rows = table.getRows();
                // 遍历表格,并替换模板
                for (XWPFTableRow row : rows) {
                    cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        // 判断单元格是否需要替换
                        if (checkText(cell.getText())) {
                            List<XWPFParagraph> paragraphs = cell.getParagraphs();
                            for (XWPFParagraph paragraph : paragraphs) {
                                replaceValue(paragraph, data);
                            }
                        }
                    }
                }
            }
        }
    }

    /***
     * @Description :替换表格内图片
     * @param document
     * @param picData
     * @return void
     * @Date 2022/11/18 11:29
     */
    public static void changeTablePic(XWPFDocument document, Map<String, Object> picData) throws Exception {
        // 获取文件的表格
        Iterator<XWPFTable> tableList = document.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        // 循环所有需要进行替换的文本,进行替换
        while (tableList.hasNext()) {
            table = tableList.next();
            if (checkText(table.getText())) {
                rows = table.getRows();
                // 遍历表格,并替换模板
                for (XWPFTableRow row : rows) {
                    cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        // 判断单元格是否需要替换
                        if (checkText(cell.getText())) {
                            List<XWPFParagraph> paragraphs = cell.getParagraphs();
                            for (XWPFParagraph paragraph : paragraphs) {
                                replacePicValue(paragraph, picData);
                            }
                        }
                    }
                }
            }
        }
    }

    /***
     * @Description :替换内容
     * @param paragraph
     * @param textMap
     * @return void
     * @Date 2022/11/18 11:33
     */
    public static void replaceValue(XWPFParagraph paragraph, Map<String, Object> textMap) {
        XWPFRun run, nextRun;
        String runsText;
        List<XWPFRun> runs = paragraph.getRuns();
        for (int i = 0; i < runs.size(); i++) {
            run = runs.get(i);
            runsText = run.getText(0);
            if (runsText.contains("${") || (runsText.contains("$") && runs.get(i + 1).getText(0).substring(0, 1).equals("{"))) {
                while (!runsText.contains("}")) {
                    nextRun = runs.get(i + 1);
                    runsText = runsText + nextRun.getText(0);
                    //删除该节点下的数据
                    paragraph.removeRun(i + 1);
                }
                Object value = changeValue(runsText, textMap);
                //判断key在Map中是否存在
                if (textMap.containsKey(runsText)) {
                    run.setText(value.toString(), 0);
                } else {
                    //如果匹配不到,则不修改
                    run.setText(runsText, 0);
                }
            }
        }
    }

    /***
     * @Description :替换图片内容
     * @param paragraph
     * @param picData
     * @return void
     * @Date 2022/11/18 11:33
     */
    public static void replacePicValue(XWPFParagraph paragraph, Map<String, Object> picData) throws Exception {
        List<XWPFRun> runs = paragraph.getRuns();
        for (XWPFRun run : runs) {
            Object value = changeValue(run.toString(), picData);
            if (picData.containsKey(run.toString())) {
                //清空内容
                run.setText("", 0);
                FileInputStream is = new FileInputStream((String) value);
                //图片宽度、高度
                int width = Units.toEMU(150), height = Units.toEMU(100);
                //添加图片信息,段落高度需要在模板中自行调整
                run.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, (String) value, width, height);
            }
        }
    }

    /***
     * @Description :匹配参数
     * @param value
     * @param textMap
     * @return java.lang.Object
     * @Date 2022/11/18 11:33
     */
    public static Object changeValue(String value, Map<String, Object> textMap) {
        Object valu = "";
        for (Map.Entry<String, Object> textSet : textMap.entrySet()) {
            // 匹配模板与替换值 格式${key}
            String key = textSet.getKey();
            if (value.contains(key)) {
                valu = textSet.getValue();
            }
        }
        return valu;
    }

    public static File getFileByHttpURL(String path) {
        String newUrl = path.split("[?]")[0];
        String[] suffix = newUrl.split("/");
        //得到最后一个分隔符后的名字
        String fileName = suffix[suffix.length - 1];
        File file = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            file = File.createTempFile("report", fileName);//创建临时文件
            URL urlFile = new URL(newUrl);
            inputStream = urlFile.openStream();
            outputStream = new FileOutputStream(file);

            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != outputStream) {
                    outputStream.close();
                }
                if (null != inputStream) {
                    inputStream.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return file;
    }
}

Word转PDF工具类:

public class AsposeUtil {


    public static boolean getLicense() {
        boolean result = false;
        try {
            String os = System.getProperty("os.name");
            if (!os.toLowerCase().startsWith("win")) {
//                FontSettings fontSettings = new FontSettings();
//                fontSettings.setFontsFolder("/usr/share/fonts/chinese" + File.separator, true);
            }
            InputStream inputStream = new ClassPathResource("license.xml").getInputStream();
            License license = new License();
            license.setLicense(inputStream);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static boolean docPdf(InputStream inputStream, OutputStream outputStream) throws UnsupportedEncodingException {
        return exchange2(inputStream, SaveFormat.PDF, outputStream);
    }

    public static boolean docPng(InputStream inputStream, HttpServletResponse response) throws UnsupportedEncodingException {
        return exchange(inputStream, SaveFormat.PNG, response);
    }

    private static boolean exchange(InputStream inputStream, int saveFormat, HttpServletResponse response) {
        boolean flag = false;
        // 验证License 若不验证则会有水印产生
        if (getLicense()) {
            ServletOutputStream outputStream = null;
            try {
                response.setCharacterEncoding(Constants.UTF8);
                response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
                outputStream = response.getOutputStream();
                Document doc = new Document(inputStream);
                if (saveFormat == SaveFormat.PNG) {
                    ImageSaveOptions iso = new ImageSaveOptions(saveFormat);
                    // 设置图片分辨率
                    iso.setResolution(512);
                    doc.save(outputStream, iso);
                } else {
                    doc.save(outputStream, saveFormat);
                }
                flag = true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(outputStream);
                IOUtils.closeQuietly(inputStream);
            }
        }
        return flag;
    }

    public static boolean exchange2(InputStream inputStream, int saveFormat, OutputStream outputStream) {
        boolean flag = false;
        // 验证License 若不验证则会有水印产生
        if (getLicense()) {
            try {
                Document doc = new Document(inputStream);
                if (saveFormat == SaveFormat.PNG) {
                    ImageSaveOptions iso = new ImageSaveOptions(saveFormat);
                    // 设置图片分辨率
                    iso.setResolution(512);
                    doc.save(outputStream, iso);
                } else {
                    doc.save(outputStream, saveFormat);
                }
                flag = true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(outputStream);
                IOUtils.closeQuietly(inputStream);
            }
        }
        return flag;
    }

第四步:测试代码 

   @GetMapping("/get/{id}")
    public R<?> createPDF(){
   
        //替换文本
        Map<String, Object> data = new HashMap<>();
        //替换图片
        Map<String, Object> picData = new HashMap<>();
        data.put("${name}", "张三");
        data.put("${sex}", "男");
        //指定图片地址
        picData.put("${url}", "C:\\Users\\admin\\Desktop\\日落.jpg");
        //生成Word,这里的路径就是项目里模版的位置
        XWPFDocument doc = WordExportUtil.exportWord07("word/测试.docx", data);
        outputStream = new FileOutputStream(这里是Word路径地址);
        doc.write(outputStream);
        outputStream.close();
        //执行替换方法
        ReplaceWordUtils.operateWord(data, picData, Word路径地址);

        FileInputStream fileInputStream = new FileInputStream(Word路径地址);
        FileOutputStream fileOutputStream = new FileOutputStream(PDF路径地址);
         //Word转换PDF
        AsposeUtil.docPdf(fileInputStream, fileOutputStream);
    }

因为测试的自己本地的图片,如果是自己项目中接口中获取的链接,需要调用ReplaceWordUtils.getFileByHttpURL(链接).getAbsolutePath()方法。

也就是这样:picData.put("${url}", ReplaceWordUtils.getFileByHttpURL(链接).getAbsolutePath());

最后测试的效果图: 

 

测试OK,可以根据自己的需求自定义实现

本人写博文完全是为了自己去巩固一些知识点,做笔记,但同时也希望可以帮助到大家,如果有什么不好的地方,也希望大家见谅!希望大家一起进步!!

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个射手座的程序猿!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值