Java使用ftl模板文件生成Word,以及Word转换图片或Pdf工具类

news2025/1/8 6:28:03

Java使用ftl模板文件生成Word

一、写在前面

最近在项目中使用打印功能,发现这个功能我已经写过多次了,下面这个文章的发步日期在2020年,不得不感慨时间之快啊。
https://blog.csdn.net/weixin_43238452/article/details/109636200?spm=1001.2014.3001.5501
下面介绍一下应用场景:这次项目依旧是springboot项目,使用ftl模版生成的word文件。比上一版相比更加灵活而且实用性更高,还可插入base64图片进行展示
关于ftl模板我会简单介绍一下使用的心得,其实也是一些标签而已,熟悉以后操作起来也比较快

二、word转ftl模板,ftl标签简单介绍

1.找到使用的word模板(如图是我自己编写的一个word模板,后续会以此进行操作)

在这里插入图片描述

2.左上角点击另存为xml文件

在这里插入图片描述

3.直接将保存的xml文件改后缀名为 ftl 然后放到项目 resources/static 目录下。进去之后idea会自动格式化,如果没有,建议按ctrl+f搜索对应的汉字进行定位(注:模板必须在static目录下,改个英文名防止乱码)

在这里插入图片描述

4.标签及语法

(1)替换标签可以是对象点属性也可以是单个变量

在这里插入图片描述

(2) 循环标签,如图会根据list的大小进行循环赋值

在这里插入图片描述

(3)判断标签如图,第一个为判断cks遍历下标是否大于5,第二层为判断cks是否拥有下一个数据

在这里插入图片描述

5.代码编写

1.导入maven依赖,freemarker和word工具类依赖aspose-words,后者可点击下载,下载jar包后自行打入maven仓库,我是直接导入的依赖坐标
		 <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>

        <dependency>
            <groupId>com.luhuiguo</groupId>
            <artifactId>aspose-words</artifactId>
            <version>22.10</version>
        </dependency>
2.模板替换工具类

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
/**
     * 
     * @param dataMap 存储数据的map集合
     * @param savePath 生成word保存路径
     */
    public static void ftl2Word(Map<String, Object> dataMap, String savePath) {
        try {
            Configuration configuration = new Configuration(new Version("2.3.0"));
            configuration.setDefaultEncoding("utf-8");
            //.ftl配置文件所在路径
            Template template = configuration.getTemplate("demo.ftl", "utf-8");
            /*File file = new File("resources/static");
            String absolutePath = file.getAbsolutePath();*/
            //上面获取路径有bug,absolutePath 既存demo.ftl的路径,不包含demo.ftl
            // 如:D:\IdeaProjectsTwo\beauty-master\beauty-main\src\main\resources\static
            configuration.setDirectoryForTemplateLoading(new File(absolutePath));
            //输出文档路径及名称
            File outFile = new File(savePath);
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),
                    "utf-8"), 10240);
            template.process(dataMap, out);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
3.word工具类
/**
 * @Author: SongTiankai
 * @Description: word工具类
 * @Date: 2022/12/9 19:34
 * @Version: 1.0
 */
public class WordUtil {


    /**
     * @Description: 验证aspose.word组件是否授权:无授权的文件有水印标记
     */
    public static boolean isWordLicense() {
        boolean result = false;
        try {
            String s = "<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>";
            ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());
            com.aspose.words.License license = new com.aspose.words.License();
            license.setLicense(inputStream);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    
    public static void word2pdf(String docPath, String savePath) {
        try {
            String s = "<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>";
            ByteArrayInputStream is = new ByteArrayInputStream(s.getBytes());
            License license = new License();
            license.setLicense(is);
            com.aspose.words.Document document = new com.aspose.words.Document(docPath);
            document.save(new FileOutputStream(new File(savePath)), SaveFormat.PDF);
        } catch (Exception e) {

            e.printStackTrace();
        }
    }


    public static void word2Image(String docPath, String savePath) {
        try {
            String s = "<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>";
            ByteArrayInputStream is = new ByteArrayInputStream(s.getBytes());
            License license = new License();
            license.setLicense(is);
            com.aspose.words.Document document = new com.aspose.words.Document(docPath);
            document.save(new FileOutputStream(new File(savePath)), SaveFormat.PNG);
        } catch (Exception e) {

            e.printStackTrace();
        }
    }

}

6.工具测试

1.测试代码
@ApiOperation("word测试接口")
    @PostMapping("/testCreat")
    public ResultData testCreat() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("ckd", "生产一车间");
        dataMap.put("llrq", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        dataMap.put("llbm", "领料部");
        dataMap.put("kgy", "王武");
        dataMap.put("zg", "占山");
        dataMap.put("llr", "里斯");
        WordUtil.ftl2Word(dataMap, "D:\\home\\word\\ckd.doc");
        WordUtil.word2Image("D:\\home\\word\\ckd.doc", "D:\\home\\word\\ckd.png");
        WordUtil.word2pdf("D:\\home\\word\\ckd.doc", "D:\\home\\word\\ckd.pdf");
        return new SuccessResultData();
    }
2.pdf

在这里插入图片描述

3.word

在这里插入图片描述

4.png

在这里插入图片描述

7.小结

至此功能实现,今天太晚了,明天研究一下路径获取,更新后给大家贴代码!
如果对你有帮助,希望可以一键三连!
感谢!

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

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

相关文章

this关键字,是如何把你难倒的?

作为一名实战前端工程师&#xff0c;在jq时代&#xff0c;是经常被this关键字难倒的。几年前每次我意识到程序出现问题的时候&#xff0c;都本能反应是自己的this没有绑定好&#xff0c;于是重新绑定一下&#xff0c;就能解决了。但是他确实一直为难着我。 转眼到了2022年底&a…

图解LeetCode——1780. 判断一个数字是否可以表示成三的幂的和(难度:中等)

一、题目 给你一个整数 n &#xff0c;如果你可以将 n 表示成若干个不同的三的幂之和&#xff0c;请你返回 true &#xff0c;否则请返回 false 。 对于一个整数 y &#xff0c;如果存在整数 x 满足 y 3^x &#xff0c;我们称这个整数 y 是三的幂。 二、示例 2.1> 示例…

SpringBoot面试杀手锏——自动配置原理

引言 不论在工作中&#xff0c;亦或是求职面试&#xff0c;Spring Boot已经成为我们必知必会的技能项。除了某些老旧的政府项目或金融项目持有观望态度外&#xff0c;如今的各行各业都在飞速的拥抱这个已经不是很新的Spring启动框架。 当然&#xff0c;作为Spring Boot的精髓…

凌恩客户文章|JCR 一区:多组学联合分析揭示PCOS真元凶

期刊&#xff1a;Journal of Ovarian Research 影响因子&#xff1a;5.506 发表时间&#xff1a;2022年10月 客户单位&#xff1a;汕头大学医学院第一附属医院鄞国书课题组 一、研究背景 多囊卵巢综合征(PCOS)是导致育龄妇女不孕的最常见内分泌疾病…

MyBatis二 MyBatis常见面试题

一 MyBatis是什么&#xff1f; MyBatis是一款优秀的持久层框架&#xff0c;一个半ORM &#xff08;对象关系映射&#xff09;框架&#xff0c;它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XM…

postman+newman+jenkins持续集成

今天为大家带来的是postmannewmanjenkins进行API接口测试的持续集成: 一. postman测试实战 postman测试API接口是通过JavaScript脚本完成测试中的功能, 在请求发起前后实现测试操作. 常用功能: 请求前脚本(pre-request scripts)设置请求前置操作如设置变量等 请求后在tests…

UE多实例云渲染之Nginx代理

Nginx的Https代理 我们实现UE像素流时大部分使用的是http协议&#xff0c;但是某些时候前端由于某些功能问题需要使用https的协议(如前端调用本地摄像头&#xff09;需要使用https协议。如果此时在内部使用http请求就会被block掉。其中一种简单的方案就是通过修改浏览器的安全…

SOLID设计原则

1. SRP单一职责原则 任何一个软件模块都应该有且仅有一个被修改的原因。 反例是一个类的三个方法给三个部门提供服务&#xff0c;而这三个方法有一些公共子方法&#xff0c;很有可能因为A部门的代码变更改动&#xff0c;导致B、C部门调用的方法出现意料之外的结果。 2. OCP开…

nginx请求转发webSocket

原由 1.我有一个socket服务&#xff0c;用ip访问是成功的&#xff0c;但是老板说用这个不行&#xff0c;要用nginx请求转发&#xff0c;转发内网地址到某个域名 2.但是我改成了指定域名后失败&#xff0c;因为我没有配置nginx.conf 3.接下来一起学习下&#xff0c;怎么在ngin…

华硕电脑怎么录屏?华硕电脑录屏功能在哪?简单实用教程来了

​有很多小伙伴对如何录制华硕电脑的屏幕知识和信息知之甚少。现在大家都想多了解一些关于华硕电脑怎么录屏的相关知识和信息。所以今天小编收集了一些关于如何录制华硕电脑屏幕的知识和信息&#xff0c;与大家分享。 华硕电脑怎么录屏方法一&#xff1a;使用Windows自带的录屏…

day45 PHP反序列化POP链构造魔术方法原生类

前言 #知识点&#xff1a; 1、什么是反序列化操作&#xff1f;-格式转换 2、为什么会出现安全漏洞&#xff1f;-魔术方法 3、反序列化漏洞如何发现&#xff1f; -对象逻辑 4、反序列化漏洞如何利用&#xff1f;-POP链构造 补充&#xff1a;反序列化利用大概分类三类 -魔…

重磅来袭!共600页,又一分牛逼的Python文档面世!

前言 本文是为了帮大家快速学习 Python 中知识点&#xff0c;这套资料涵盖了诸多学习内容&#xff1a;面试题&#xff0c;教材视频&#xff0c;实战资料&#xff0c;电子书籍。 相信可以帮助大家在最短的时间内&#xff0c;能达到事半功倍效果&#xff0c;用来复习也是非常不…

150行代码写个低配版WPS?:手把手教你实现+附完整源码

前言&#xff1a;通过一个简单实例来实现Java的GUI编程&#xff0c;对于新手较为友好&#xff0c;且有一定的实用性&#xff0c;正在学习Java的同学看过来&#xff01;&#xff01;包教包会&#xff0c;如有疑问欢迎私信询问&#xff01; 目录 实例展示 一、GUI编程基本概念 …

java面向对象----抽象类 接口

目录 抽象类与抽象方法 概念 抽象类应用 接 口 概念 接口的特点&#xff1a; 接口应用举例 Java 8中关于接口的改进 内部类 如何声明局部内部类 局部内部类的特点 匿名内部类 总结 抽象类与抽象方法 概念 随着继承层次中一个个新子类的定义&#xff0c;类变得越…

机器学习之多元线性回归

1、多元线性回归模型&#xff1a;定义&#xff1a;具有多个特征的线性回归模型 多元线性回归模型&#xff0c;见下图&#xff1a; 多元线性回归总结&#xff08;参数、模型、损失函数、梯度下降算法&#xff09;见下图&#xff1a;【注意&#xff1a;梯度下降算法每次都是同时…

Vue2中过滤器的用法详解

目录 一、过滤器的概念 二、过滤器的使用位置 三、过滤器的分类 1、全局过滤器 2、本地过滤器 四、过滤器应用实例 1、使用过滤器实现省略号 2、使用过滤器处理时间戳 五、Vue3中已废弃过滤器 过滤器是vue中的一个特性&#xff0c;作用是用于对文本进行格式化的作用。…

动态与静态获取元素

&#x1f335;知识点简介 静态获取&#xff08;querySelectorAll&#xff09;时&#xff0c;选出的所有元素的数组&#xff0c;不会随着文档操作而改变&#xff1b; 动态获取&#xff08;getElementById&#xff09;时&#xff0c;选出的所有元素的数组&#xff0c;会随着文档的…

Paddle 点灯人 之 Tensor

Paddle 点灯人 之 Tensor 文章目录Paddle 点灯人 之 TensorPaddle点灯人介绍Tensor介绍Pytorch和Paddle的相似之处创建张量Tensor图片/文本转TensorDataLoader不需要加ToTensorPaddle中的 Tensor 的属性形状 shape数据类型&#xff08;dtype&#xff09;Tensor 的设备位置&…

高压放大器驱动压电器件工作原理

高压放大器在实际应用中经常会进行电容性负载驱动&#xff0c;对压电器件进行驱动&#xff0c;那么工作原理是什么呢&#xff0c;下面就请安泰电子来为我们讲解一下。 高压放大器是提高信号电压的装置&#xff0c;当负载是谐振电路或者耦合电路的时候&#xff0c;要求特定频率范…

Mybatis源码解析(十):一级缓存和二级缓存

Mybatis源码系列文章 手写源码&#xff08;了解源码整体流程及重要组件&#xff09; Mybatis源码解析(一)&#xff1a;环境搭建 Mybatis源码解析(二)&#xff1a;全局配置文件的解析 Mybatis源码解析(三)&#xff1a;映射配置文件的解析 Mybatis源码解析(四)&#xff1a;s…