使用freemarker和itextpdf结合,将html转化为pdf

工作中遇到模板中的html,需要转化成pdf作为附件上传到系统

于是经过研究分析,得出用freemarker和itextpdf结合

maven需要导入包:

		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>${itextpdf.version}</version></dependency><dependency><groupId>com.itextpdf.tool</groupId><artifactId>xmlworker</artifactId><version>5.5.8</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency>

新建FreemarkerUtils工具类

package com.example.common.util;import cn.hutool.core.util.StrUtil;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import freemarker.core.HTMLOutputFormat;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;import com.itextpdf.tool.xml.XMLWorkerHelper;@Component
@Slf4j
public class FreemarkerUtils {@Resourceprivate Configuration stringConfiguration;private static final String FONT = "fonts/simhei.ttf";/*** 根据模板构建* @param content 模板内容* @param dataModel 模板数据**/public String buildByTemplate(String content, Map<String,Object> dataModel){return buildByTemplate(content, dataModel, StrUtil.EMPTY);}/*** 根据模板替换变量,得到变量替换后的内容* @param content 模板内容* @param dataModel 模板数据* @param defaultString 构建失败返回的默认值**/public String buildByTemplate(String content, Map<String,Object> dataModel,String defaultString) {try {
//            stringConfiguration.setOutputFormat(HTMLOutputFormat.INSTANCE);return FreeMarkerTemplateUtils.processTemplateIntoString(new Template("", content,   stringConfiguration),dataModel);}catch (Exception e){log.warn("解析模板失败", e);}return defaultString;}public void htmlToPdf(String content) {// 创建一个Document对象Document document = new Document();try {// 创建一个PdfWriter实例来写PDF文件PdfWriter writer = PdfWriter.getInstance(document, Files.newOutputStream(Paths.get("E:\\张三测试.pdf")));// 打开文档document.open();InputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));FontProviderUtil fontProviderUtil = new FontProviderUtil();// 读取HTML文件并将其转换为PDFXMLWorkerHelper.getInstance().parseXHtml(writer, document,inputStream, null, StandardCharsets.UTF_8, fontProviderUtil);// 关闭文档document.close();} catch (DocumentException | IOException e) {e.printStackTrace();}}}

 解决中文乱码和生成的pdf中文不显示问题

package com.example.common.util;import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import lombok.extern.slf4j.Slf4j;/*** 字体*/
@Slf4j
public class FontProviderUtil extends XMLWorkerFontProvider {/*** 黑体 常规**/public static final String SIMHEI_TTF = "fonts/simhei.ttf";/*** 解决乱码和中文在pdf不显示问题* @param fontname    the name of the font* @param encoding    the encoding of the font* @param embedded    true if the font is to be embedded in the PDF* @param size	    the size of this font* @param style	    the style of this font* @param color	    the <CODE>BaseColor</CODE> of this font.* @param cached 		true if the font comes from the cache or is added to* 				the cache if new, false if the font is always created new* @return*/@Overridepublic Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color, boolean cached) {BaseFont bf = null;try {bf = BaseFont.createFont(SIMHEI_TTF, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);} catch (Exception e) {log.info(e.getMessage());e.printStackTrace();}Font font = new Font(bf, size, style, color);font.setColor(color);return font;}}

在业务层调用即可

  freemarkerUtils.htmlToPdf(content);

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

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

相关文章

【力扣每日一题】力扣1696跳跃游戏VI

题目来源 力扣1696跳跃游戏VI 题目概述 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 一开始你在下标 0 处。每一步&#xff0c;你最多可以往前跳 k 步&#xff0c;但你不能跳出数组的边界。也就是说&#xff0c;你可以从下标 i 跳到** [i 1&#xff0c; min(n …

代码随想录 Leetcode491. 非递减子序列

题目&#xff1a; 代码(首刷看解析 2024年2月3日&#xff09;&#xff1a; class Solution { private:vector<vector<int>> res;vector<int> path; public:void backtracking(vector<int>& nums, int startIndex) {if (path.size() > 1) {res.…

iframe通信,window.postMessage父子项目数据通信

父 > 子 父项目 <iframe:src"cockpitUrl"id"cockpitIframe"load"handleLoad" ></iframe>// 向子系统传递数据&#xff08;注意要再iframe的load中注册&#xff0c;保证iframe已经加载完成&#xff0c;这样子项目才能监听到&…

HSM加密机原理:密钥管理和加密操作从软件层面转移到物理设备中 DUKPT 安全行业基础8

HSM加密机原理 硬件安全模块&#xff08;HSM&#xff09;是一种物理设备&#xff0c;设计用于安全地管理、处理和存储加密密钥和数字证书。HSM广泛应用于需要高安全性的场景&#xff0c;如金融服务、数据保护、企业安全以及政府和军事领域。HSM提供了一种比软件存储密钥更安全…

Web html和css

目录 1 前言2 HTML2.1 元素(Element)2.1.1 块级元素和内联(行级)元素2.1.2 空元素 2.2 html页面的文档结构2.3 常见标签使用2.3.1 注释2.3.2 标题2.3.3 段落2.3.4 列表2.3.5 超链接2.3.6 图片2.3.7 内联(行级)标签2.3.8 换行 2.4 属性2.4.1 布尔属性 2.5 实体引用2.6 空格2.7 D…

当前小程序跳转另一个小程序

原生小程序&#xff1a; wx.navigateToMiniProgram()&#xff1a; 参数值&#xff1a; appId要打开的小程序 appIdpath要跳转小程序的路径 uniapp小程序&#xff1a; uni.navigateToMiniProgram()&#xff1a; 参数值&#xff1a; appId要打开的小程序 appIdpath要跳转小…

vue3 之 组合式API—生命周期函数

vue3的生命周期API 生命周期函数基本使用 1️⃣导入生命周期函数 2️⃣执行生命周期函数 传入回调 <scirpt setup> import { onMounted } from vue onMounted(()>{// 组件挂载完毕mounted执行了 }) </script>执行多次 生命周期函数是可以执行多次的&#xff…

python 在气象、水文中数据处理及结果分析、绘图实践技术应用

Python在气象、水文数据处理和结果分析以及绘图方面的实践技术应用广泛&#xff0c;下面列举了一些主要的实践技术应用&#xff1a; 数据处理和分析&#xff1a;Python有强大的数据处理库&#xff0c;如NumPy和Pandas&#xff0c;使得数据的导入、处理和分析变得容易。使用这些…

支持多字体、静动态的.NET图片验证码的开源项目

上次分享过 SkiaSharp 这个开源图形项目&#xff0c;并举了一个生成验证码的例子&#xff0c;具体见文章&#xff1a;《SkiaSharp&#xff1a;.NET强大而灵活的跨平台图形库》。 但文中验证码比较简单&#xff0c;刚好看到一个非常不错的图片验证码&#xff0c;分享给大家。 …

ChatGPT之搭建API代理服务

简介 一行Docker命令部署的 OpenAI/GPT API代理&#xff0c;支持SSE流式返回、腾讯云函数 。 项目地址&#xff1a;https://github.com/easychen/openai-api-proxy 这个项目可以自行搭建 OpenAI API 代理服务器工具&#xff0c;该项目是代理的服务器端&#xff0c;不是客户端。…

reactive 与 ref 的区别

在 Vue.js 中&#xff0c;reactive 是 Vue 3 引入的一个新的 API&#xff0c;用于创建响应式对象。这种方法是 Composition API 的一部分&#xff0c;它提供了一种更灵活的方式来组织和重用逻辑。 reactive 的基本用法 使用 reactive&#xff0c;你可以将普通的 JavaScript 对…

MySQL 用户管理

重点&#xff1a; 视图&#xff0c;函数&#xff0c;存储过程&#xff0c;触发器&#xff0c;事件&#xff08; 了解 &#xff09; 用户管理&#xff0c;密码管理 grant revoke 权限管理 MySQL 架构&#xff08; 了解 &#xff09; 存储引擎&#xff1a;MyISAM 和 InnoDB …

算法训练营day22, 回溯2

216. 组合总和 III func combinationSum3(k int, n int) [][]int { //存储全部集合 result : make([][]int, 0) //存储单次集合 path : make([]int, 0) var backtrace func(k int, n int, sum int, startIndex int) backtrace func(k int, n int, sum int, startIndex int) {…

【JavaScript 漫游】【008】错误处理机制

文章简介 本文为【JavaScript 漫游】专栏的第 008 篇文章&#xff0c;记录了笔者所学习到的错误处理机制的所有知识点。 Error 实例对象原生错误类型&#xff0c;包括 SyntaxError、ReferenceError、RangeError、TypeError、URIError对象自定义错误throw 语句try...catch 结构…

【iOS ARKit】3D人体姿态估计实例

与2D人体姿态检测一样&#xff0c;在ARKit 中&#xff0c;我们不必关心底层的人体骨骼关节点检测算法&#xff0c;也不必自己去调用这些算法&#xff0c;在运行使用 ARBodyTrackingConfiguration 配置的 ARSession 之后&#xff0c;基于摄像头图像的3D人体姿态估计任务也会启动…

Python中的HTTP代理与网络安全

在当今数字化的世界里&#xff0c;网络安全已经成为我们无法忽视的重要议题。无数的信息在网络上传递&#xff0c;而我们的隐私和敏感数据也在这个过程中可能面临被窃取或滥用的风险。在Python编程中&#xff0c;HTTP代理作为一种工具&#xff0c;能够在网络安全方面发挥重要的…

docker重建镜像

DockerFile如下&#xff1a; FROM k8s-registry.qhtx.local/base/centos7-jdk8-haitong0704RUN yum -y update && yum install -y python3-devel && yum install -y python36 RUN mv /usr/bin/python /usr/bin/python_old RUN ln -s /usr/bin/python3 /usr/bi…

虹科技术|一文详解IO-Link Wireless技术如何影响工业无线自动化

导读&#xff1a;在工业无线自动化的飞速发展进程中&#xff0c;IO-Link Wireless技术成为了一项具有颠覆性的创新。它将IO-Link协议与无线连接完美结合&#xff0c;解决了传统通信技术在工业应用中的痛点。本文将深入解析IO-Link Wireless技术的原理、应用领域、优势以及实际案…

小华和小为的聚餐地点 - 华为OD统一考试

OD统一考试(C卷) 分值: 200分 题解: Java / Python / C++ 题目描述 小华和小为是很要好的朋友,他们约定周末一起吃饭。 通过手机交流,他们在地图上选择了多个聚餐地点(由于自然地形等原因,部分聚餐地点不可达)。 求小华和小为都能到达的聚餐地点有多少个? 输入描述…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--强化学习、模仿学习、机器人

专属领域论文订阅 关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 为了答谢各位网友的支持&#xff0c;从今日起…