根据word模板生成pdf文件

news2024/11/17 13:39:58

1、首先建一个word,插入一个表格,需要填充的值用${parame}代替

(注意:这里的参数要和java实体类里面的参数对应起来,代码放在下面)

2、制作完成后另存为xml格式

3、然后用文本编辑工具打开这个xml文件,复制源码

4、 打开:https://mp.csdn.net/mp_blog/creation/editor/131155433,在线格式化xml文件

5、复制到xml文件,然后将名称改为:exam.ftl 。这里后缀名也需要变更,如图

6、项目目录结构:

7、OK,模板制作完成开始搞代码,pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>greate</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>greate</name>
    <description>greate</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--freemarker模板引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!-- 构建pdf-->
        <dependency>
            <groupId>wiki.xsx</groupId>
            <artifactId>x-easypdf</artifactId>
            <version>2.9.10</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.3</version>
        </dependency>
        <!-- doc转pdf-->
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-words</artifactId>
            <version>15.8.0</version>
            <scope>system</scope>
            <systemPath>${basedir}/lib/aspose-words-15.8.0.jar</systemPath>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
8、填充表格的实体类:Exam.java、GradeVo.java
package com.example.greate.model;

import lombok.Data;

@Data
public class GradeVo {
    private String name;
    private String code;
    private int chinese;
    private int mathematics;
    private int english;
    private int synthesize;
    private int information;
    private int total;
}



package com.example.greate.model;

import lombok.Data;
import java.util.List;

@Data
public class Exam {
    private String date;
    private String desc;
    private List<GradeVo> gradeList;
}

 9、生成pdf工具类:GeneratePdfUtil.java

package com.example.greate.util;

import com.aspose.words.License;
import com.example.greate.model.Exam;
import com.example.greate.model.GradeVo;
import freemarker.template.Version;
import io.micrometer.common.util.StringUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import freemarker.core.XMLOutputFormat;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import wiki.xsx.core.pdf.convertor.XEasyPdfConvertor;


public class GeneratePdfUtil {

    private static final Logger log = LogManager.getLogger(GeneratePdfUtil.class);

    public static void main(String[] args) throws IOException {
        GeneratePdfUtil.acceptList();
    }


    /**
     * 高考成绩单
     * @throws IOException
     */
    public static void acceptList() throws IOException {
        
        String fileName = "高考成绩单";
        Exam exam = new Exam();
        List<GradeVo> list = new ArrayList<>();
        GradeVo vo1 = new GradeVo();
        vo1.setName("张三");
        vo1.setCode("GK000001");
        vo1.setChinese(100);
        vo1.setMathematics(120);
        vo1.setEnglish(120);
        vo1.setSynthesize(180);
        vo1.setInformation(60);
        vo1.setTotal(580);

        GradeVo vo2 = new GradeVo();
        vo2.setName("李四");
        vo2.setCode("GK000002");
        vo2.setChinese(120);
        vo2.setMathematics(130);
        vo2.setEnglish(125);
        vo2.setSynthesize(180);
        vo2.setInformation(65);
        vo2.setTotal(620);

        list.add(vo1);
        list.add(vo2);
        exam.setDate("2023年06月11日");
        exam.setDesc("省高校招生办");
        exam.setGradeList(list);
        createDocByObj(exam,fileName,"exam.ftl");
    }

    /**
     * 根据模板生成word文档
     *
     * @param obj map中一定要有filePath键值对
     * @param fileName 文件名称
     * @param templates 模板文件
     * @throws IOException
     */
    public static String createDocByObj(Object obj,String fileName,String templates) throws IOException {
        String saveFilePath = "F:\\";
        ResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource("classpath:templates");
        if (StringUtils.isEmpty(saveFilePath)) {
            throw new IOException("保存文件路径不存在!");
        }
        if (templates == null) {
            throw new IOException("未获取到模板文件,请确认路径是否正确!");
        }
        String ftlName = templates;
        Version v = new Version("2.3.0",true,new Date());
        Configuration configuration = new Configuration(v);
        configuration.setDefaultEncoding("utf-8");
        configuration.setOutputFormat(XMLOutputFormat.INSTANCE);
        configuration.setDirectoryForTemplateLoading(resource.getFile());
        String outFileName = "";
        if(fileName.contains(".doc")){
            outFileName = fileName;
        }else{
            outFileName = fileName+".doc";
        }
        Template t = configuration.getTemplate(ftlName);
        String of = saveFilePath + "/" + outFileName;
        File df = new File(saveFilePath);
        if (!df.exists()) {
            df.mkdir();
        }
        File outFile = new File(of);
        log.info("文件名称:" + outFileName + ",文件路径:" + outFile);
        Writer out = null;
        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        try {
            fos = new FileOutputStream(outFile);
            osw = new OutputStreamWriter(fos, "utf-8");
            out = new BufferedWriter(osw);
            t.process(obj, out);
            String  filePath = saveFilePath+outFileName;
            docTransitionPdf(filePath,filePath.replace(".doc",".pdf"));
        } catch (Exception e) {
            log.error("根据模板生成word文档:", e);
        } finally {
            try {
                out.close();
                osw.close();
                fos.close();
                //删除doc文件
                if(outFile.exists()){
                    log.info("删除:{}",outFileName);
                    outFile.delete();
                }
            } catch (Exception e) {
                log.error("关闭文件流异常:",e);
            }
        }
        return saveFilePath+outFileName.replace(".doc",".pdf");
    }



    /**
     * word文档转pdf文件
     * @param Address 要不转化的文档地址
     * @param pdfName pdf名称
     */
    public static void docTransitionPdf(String Address, String pdfName) throws IOException {
        // 验证License 若不验证则转化出的pdf文档会有水印产生
        if (!getLicense()) {
            return;
        }
        log.info("==XEasyPdfConvertor start");
        XEasyPdfConvertor.toPdf(Address, pdfName);
        log.info("==XEasyPdfConvertor end");
    }

    /**
     * 验证证书
     * @return
     */
    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = GeneratePdfUtil.class.getClassLoader().getResourceAsStream("license.xml");
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            log.error("获取license失败:", e);
        }
        return result;
    }
}

 10、运行代码,生成pdf文件如图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/634408.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS基础学习--6 CSS Text(文本)

一、文本颜色 color:red; 颜色属性被用来设置文字的颜色。 颜色是通过CSS最经常的指定&#xff1a; 十六进制值 - 如: &#xff03;FF0000一个RGB值 - 如: RGB(255,0,0)颜色的名称 - 如: red body {color:red;} h1 {color:#00ff00;} h2 {color:rgb(255,0,0);} 二、文本的…

【备战秋招】每日一题:4月18日美团春招:题面+题目思路 + C++/python/js/Go/java带注释

2023大厂笔试模拟练习网站&#xff08;含题解&#xff09; www.codefun2000.com 最近我们一直在将收集到的各种大厂笔试的解题思路还原成题目并制作数据&#xff0c;挂载到我们的OJ上&#xff0c;供大家学习交流&#xff0c;体会笔试难度。现已录入200道互联网大厂模拟练习题&a…

8 channel、反射、网络编程【Go语言教程】

8 channel、反射、网络编程【Go语言教程】 1 channel 1.1 概念及快速入门 channel:管道&#xff0c;主要用于不同goroutine之间的通讯 需求&#xff1a;现在要计算 1-200 的各个数的阶乘&#xff0c;并且把各个数的阶乘放入到 map 中。最后显示出来。要求使用 goroutine 完成…

[LeetCode周赛复盘] 第 349 场周赛20230611

[LeetCode周赛复盘] 第 349 场周赛20230611 一、本周周赛总结6470. 既不是最小值也不是最大值1. 题目描述2. 思路分析3. 代码实现 6465. 执行子串操作后的字典序最小字符串1. 题目描述2. 思路分析3. 代码实现 6449. 收集巧克力1. 题目描述2. 思路分析3. 代码实现 6473. 最大和…

测试老鸟总结,接口自动化测试用例设计编写,高级测试之路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口信息来源 与…

百度图像识别 API

首先预览下效果 feaa250077a543a39f037ae8e78a3e80~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp (640594) (byteimg.com) 从以上预览图中可看出&#xff0c;每张图片识别出5条数据&#xff0c;每条数据根据识别度从高往下排&#xff0c;每条数据包含物品名称、识别度…

VisualStdio中scanf报错问题

VisualStdio中scanf报错问题 目录 一&#xff0e; 概述二&#xff0e; 解决方法 一&#xff0e; 概述 报错代码及说明 报错代码为C4996 会在哪种编译器中报错&#xff1f; VisualStdio系列编译器 为什么会报错&#xff1f; 因为VisualStdio比较严谨&#xff0c;认为scanf不…

内网安全:横向传递攻击( RDP || Cobalt Strike )

内网安全&#xff1a;横向传递攻击&#xff08; RDP || Cobalt Strike &#xff09; 横向移动就是在拿下对方一台主机后&#xff0c;以拿下的那台主机作为跳板&#xff0c;对内网的其他主机再进行后面渗透&#xff0c;利用既有的资源尝试获取更多的凭据、更高的权限&#xff0…

【基础知识整理】时间复杂度 空间复杂度

概览 时间复杂度与空间复杂度的作用是在衡量一个算法的优劣性&#xff0c;以及在二者之间进行权衡&#xff0c;寻找二者的平衡点。 时间复杂度是指执行算法所需时间的增长率&#xff0c;而空间复杂度则是指执行算法所需存储空间的增长率。 高时间复杂度的算法可能需要在短时间…

合金氢化物动力学与瞬时流量

在经典的合金氢化物动力学描述中&#xff0c;有一种是用JMAK方程来描述和拟合合金的吸放氢过程&#xff0c;方程很简洁&#xff1a;&#xff0c;其中是反应程度或者百分比&#xff0c;表示合金氢化物吸氢或者放氢的程度&#xff0c;是该合金吸氢或放氢的一种特征常数&#xff0…

使用wab2app将网页打包成APK

前言 通过开源项目ChatGPT-Next-Web部署完了私人网页ChatGPT&#xff0c;为了使访问更加便捷&#xff0c;便想着使用wab2app打包为APK&#xff0c;虽然最终达成了效果&#xff0c;可一路走来遇到了很多坑儿&#xff0c;记录下 打包流程 有要打包的网站和软件HBuilder X&…

【Kubernetes存储篇】持久化存储PV、PVC详解

文章目录 一、PV、PVC持久化存储理论1、PV、PVC是什么&#xff1f;2、PV的供应方式3、PV、PVC的回收策略 二、案例&#xff1a;PV、PVC持久化存储案例演示1、搭建NFS服务端2、创建PV&#xff0c;并使用NFS共享存储3、创建PVC&#xff0c;并和PV绑定4、创建Pod&#xff0c;并挂载…

docker中运行PostgreSQL容器

我们如何在docker中运行postgresql容器&#xff0c;要进过如下几个步骤就可以了。 拉取postgresql容器 docker pull postgres:latest使用上述命令将从 Docker Hub 存储库中提取最新可用版本的 PostgreSQL。 从 PostgreSQL 服务器 Docker 镜像运行容器 在部署之前&#xff0c;…

2023年6月DAMA-CDGA/CDGP数据治理工程师认证报名特惠

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

WinDbg安装入坑3(C#)

由于作者水平有限&#xff0c;如有写得不对的地方&#xff0c;请指正。 使用WinDbg的过程中&#xff0c;坑特别的多&#xff0c;对版本要求比较严格&#xff0c;如&#xff1a; 1 32位应用程序导出的Dump文件要用32位的WinDbg打开&#xff0c;想要没有那么多的问题&#xf…

Xcode 15 beta (15A5160n) - Apple 平台 IDE

Xcode 15 beta (15A5160n) - Apple 平台 IDE IDE for iOS/iPadOS/macOS/watchOS/tvOS/visonOS 请访问原文链接&#xff1a;https://sysin.org/blog/apple-xcode-14/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Xcode 15 使…

windows系统cmd命令设置别名,并添加到环境变量

众所周知&#xff0c;Linux 命令很强大&#xff0c;使用起来也很方便&#xff0c;但是想在 windows 系统上使用 Linux 命令有些困难&#xff0c;要么下载第三方终端工具&#xff0c;要么就是安装一系列命令环境。 作为一个前端开发&#xff0c;其实可以全局安装一下 npm 命令行…

分库分表-ShardingSphere

分库分表拆常见分方法与特点 分片策略 数据分布 以后扩展 基于Hash&#xff1a;hash(分片键)%分片数 数据分布均匀 不易扩容&#xff0c;扩容需要数据迁移 范围分片&#xff1a;例如按年分&#xff0c;按月&#xff0c;按日 数据分表可能不均匀 易扩展&#xff0c;扩展…

API自动化测试利器Postman,帮助你更好地进行 API 自动化测试

目录 前言&#xff1a; 一、基本功能 二、测试工具 三、示例 前言&#xff1a; Postman 是一个易于使用的 API 开发和测试工具&#xff0c;可以在其中快速构建、测试和文档化 Web API。Postman 提供了一个直观的用户界面&#xff0c;可以轻松地创建 HTTP 请求、测试响应、…

深入解析XMLHttpRequest:实现异步通信的利器

文章目录 介绍什么是XMLHttpRequest&#xff1f;XMLHttpRequest的基本用法1.创建XMLHttpRequest对象2.配置请求3.发送请求 XMLHttpRequest 属性sendreadyStatestatusstatusTextresponseresponseTextresponseTyperesponseURLtimeoutwithCredentials 异步请求与同步请求请求类型和…