使用poi-tl填充word模板,并转化为pdf输出

后端

依赖

java 复制代码
<dependency>
    <groupId>com.deepoove</groupId>
    <artifactId>poi-tl</artifactId>
    <version>1.12.0</version>
</dependency>

Word版本

Word版本填充代码

java 复制代码
		// 培训详情
       


        HashMap<String, Object> textMap = new HashMap<>();
        textMap.put("projectNo", projectInitiation.getProjectNo());
        textMap.put("projectName", projectInitiation.getProjectName());
        textMap.put("organization1", organization.getName());
        textMap.put("email", Objects.isNull(user.getEmail()) ? "" : user.getEmail());
        textMap.put("headPhone", Objects.isNull(deviceManage.getHeadPhone()) ? "" : deviceManage.getHeadPhone());
        // 查看培训人员(扫码查看)
        QrConfig config = new QrConfig(300, 300);
        // 设置边距,既二维码和背景之间的边距
        config.setMargin(3);
        HashMap<String, String> qrMap = new HashMap<>();
        qrMap.put("type", RandomUtil.randomString(5));
        qrMap.put("data", AESUtils.encodeBase64(String.valueOf(visitationTask.getId())));
        String qr = QrCodeUtil.generateAsBase64(JsonUtils.objectToJsonString(qrMap), config, ImgUtil.IMAGE_TYPE_JPG);
        textMap.put("detailPages", Pictures.ofBase64(qr, PictureType.JPEG).size(100, 100).create());

        // 选中
        textMap.put("redio", "\u2611");

        textMap.put("customerSignature", Objects.isNull(cultivateDetail.getCustomerSignature()) ? "" : Pictures.ofUrl(cultivateDetail.getCustomerSignature(), PictureType.JPEG).size(100, 50).create());
        textMap.put("engineerSignature", Objects.isNull(cultivateDetail.getEngineerSignature()) ? "" : Pictures.ofUrl(cultivateDetail.getEngineerSignature(), PictureType.JPEG).size(100, 50).create());


        // 获取文件流
        try {
            InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/培训服务报告.docx");
            XWPFTemplate template = XWPFTemplate.compile(inputStream).render(textMap);

            Map<String, Object> map = new HashMap<>();
            ByteArrayOutputStream fos = new ByteArrayOutputStream();
            template.write(fos);
            byte[] bytes = fos.toByteArray();
            byte[] convertToPdf = Doc2PdfUtil.doc2Pdf(bytes);
            String bytesRes = StringUtils.bytesToHexString2(convertToPdf);
            map.put("bytes", bytesRes);
            map.put("title", System.currentTimeMillis() + "培训服务报告.docx");
            fos.close();
            template.close();


            return Response.successJson(map);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

pdf版本

依赖

java 复制代码
		<!--aspose 破解 word转pdf-->
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-words</artifactId>
            <version>16.8.0-jdk16</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/aspose-words-16.8.0-jdk16.jar</systemPath>
        </dependency>

license放到resources下面 license.xml

java 复制代码
<License>
    <Data>
        <Products>
            <Product>Aspose.Total for Java</Product>
            <Product>Aspose.Words for Java</Product>
        </Products>
        <EditionType>Enterprise</EditionType>
        <SubscriptionExpiry>20991231</SubscriptionExpiry>
        <LicenseExpiry>20991231</LicenseExpiry>
        <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
    </Data>
    <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>

word转pdf工具类

java 复制代码
package com.gangwantech.web.utils;

import com.aspose.words.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

public class Doc2PdfUtil {

    /**
     * 加载授权配置文件
     *
     * @return
     */
    private static boolean getLicense() {
        boolean result = false;
        try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("license.xml")) {
            // License的包路径必须为com.aspose.words.License
            License license = new License();
            license.setLicense(in);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * doc转pdf
     *
     * @return
     */
    public static byte[] doc2Pdf(byte[] bytes) {
        System.out.println("pdf转换中...");
        long old = System.currentTimeMillis();

        try (ByteArrayOutputStream fos = new ByteArrayOutputStream()) {
            // 验证
            if (!getLicense()) {
                throw new RuntimeException("文件转换失败!");
            }
            // 加载字体
            //FontSettings settings = FontSettings.getDefaultInstance();
            //String[] fontFamilyNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
            //settings.setFontsFolders(fontFamilyNames, true);
            //LoadOptions loadOptions = new LoadOptions();
            //loadOptions.setFontSettings(settings);

             加载字体
            //FontSettings settings = FontSettings.getDefaultInstance();
            //settings.setFontsFolder("C:\\Windows\\Fonts", true);
            //LoadOptions loadOptions = new LoadOptions();
            //loadOptions.setFontSettings(settings);

            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
            //Document document = new Document(inputStream, loadOptions);
            Document document = new Document(inputStream);

            document.save(fos, SaveFormat.PDF);
            byte[] buffer = fos.toByteArray();
            long now = System.currentTimeMillis();
            System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒");
            return buffer;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("文件转换失败!");
        }
    }
}

pdf版本填充代码,并生成pdf下载

java 复制代码
		// 培训详情
        CultivateDetail cultivateDetail = cultivateDetailService.selectOne(new QueryWrapper<CultivateDetail>()
                .eq("work_id", visitationTask.getWorkOrderId())
        );
        
        HashMap<String, Object> textMap = new HashMap<>();
        textMap.put("projectNo", projectInitiation.getProjectNo());
        textMap.put("projectName", projectInitiation.getProjectName());
        // 查看培训人员(扫码查看)
        QrConfig config = new QrConfig(300, 300);
        // 设置边距,既二维码和背景之间的边距
        config.setMargin(3);
        HashMap<String, String> qrMap = new HashMap<>();
        qrMap.put("type", RandomUtil.randomString(5) + "train");
        qrMap.put("data", AESUtils.encodeBase64(String.valueOf(visitationTask.getId())));
        String qr = QrCodeUtil.generateAsBase64(JsonUtils.objectToJsonString(qrMap), config, ImgUtil.IMAGE_TYPE_JPG);
        textMap.put("detailPages", Pictures.ofBase64(qr, PictureType.JPEG).size(100, 100).create());

        // 选中
        textMap.put("redio", "\u2611");

        textMap.put("customerSignature", Objects.isNull(cultivateDetail.getCustomerSignature()) ? "" : Pictures.ofUrl(cultivateDetail.getCustomerSignature(), PictureType.JPEG).size(100, 50).create());
        textMap.put("engineerSignature", Objects.isNull(cultivateDetail.getEngineerSignature()) ? "" : Pictures.ofUrl(cultivateDetail.getEngineerSignature(), PictureType.JPEG).size(100, 50).create());


        // 获取文件流
        try {
            InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/培训服务报告.docx");
            XWPFTemplate template = XWPFTemplate.compile(inputStream).render(textMap);

            Map<String, Object> map = new HashMap<>();
            ByteArrayOutputStream fos = new ByteArrayOutputStream();
            template.write(fos);
            byte[] bytes = fos.toByteArray();
            byte[] convertToPdf = Doc2PdfUtil.doc2Pdf(bytes);
            String bytesRes = StringUtils.bytesToHexString2(convertToPdf);
            map.put("bytes", bytesRes);
            map.put("title", System.currentTimeMillis() + "培训服务报告.docx");
            fos.close();
            template.close();


            return Response.successJson(map);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

前端下载方法

word下载

java 复制代码
		if (res.data.code === 0) {
          const data = res.data.data
          const bytes = hexStr2Byte(data.bytes)
          const blob = new Blob([bytes], {
            type: `application/vnd.openxmlformats-officedocument.wordprocessingml.document`
          })
          const objectUrl = URL.createObjectURL(blob)
          const link = document.createElement('a')
          link.href = objectUrl
          link.setAttribute('download', data.title)
          document.body.appendChild(link)
          link.click()
        } else {
          this.$message.error(res.data.msg)
        }

pdf下载

java 复制代码
		  const data = res.data.data
          const bytes = hexStr2Byte(data.bytes)
          const blob = new Blob([bytes], {
            type: `application/pdf`
          })
          const objectUrl = URL.createObjectURL(blob)
          const link = document.createElement('a')
          link.href = objectUrl
          link.setAttribute('download', `${data.title}.pdf`)
          document.body.appendChild(link)
          link.click()
        } else {
          this.$message.error(res.data.msg)
        }
相关推荐
l1t7 小时前
DeepSeek总结的使用实体-组件-系统和基于存在性处理进行Python编程7-8
开发语言·python
俊哥工具7 小时前
无广告免费壁纸工具,手机电脑壁纸随心更换
python·智能手机·django·计算机外设·virtualenv·pygame
scan7247 小时前
大模型调用多个工具
python
暴躁小师兄数据学院7 小时前
【AI大模型应用开发工程师特训笔记】第04讲(第 2 章):Python 项目企业级开发规范
人工智能·笔记·python
wuweijianlove8 小时前
算法中的记忆化思想与重复子问题优化的技术5
算法
小江的记录本8 小时前
【JVM虚拟机】垃圾回收GC:垃圾判定算法:引用计数法、可达性分析算法(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·spring·面试
Hello.Reader8 小时前
算法基础(十四)—— 随机化快速排序为什么平均表现很好
算法
清水白石0088 小时前
构建企业级 Python 服务:配置、日志、指标与追踪的稳健之道
开发语言·python·elasticsearch
吴可可1238 小时前
Teigha中OdGe几何库详解及C#使用
算法
爱喝水的鱼丶9 小时前
SAP-ABAP:变量、常量、结构与内表声明(10篇博客合集) 第六篇:ABAP 7.40+新特性:声明语法的简化写法与兼容注意事项
运维·服务器·开发语言·学习·算法·sap·abap