【itext学习之路】-------(第七篇)将html转成pdf(解决中文不显示)

2024-04-15 16:08

本文主要是介绍【itext学习之路】-------(第七篇)将html转成pdf(解决中文不显示),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

版权声明:如需转载使用,请注明原文地址

在上一篇文章中,我们学习了使用对pdf进行盖章/签章/数字签名,到此为止,常用的pdf操作已经全部实现,但是实际开发中很多人比较喜欢将html转成pdf,本文介绍将html转pdf的方法(之前用的都是itext5,这次需要用到itext7中的html2pdf这个强大的组件)

  • 首先,先贴上代码之前一直使用的itext5的方式,将html转pdf(很多标签无法兼容)
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.ElementList;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.css.CssFile;
import com.itextpdf.tool.xml.css.StyleAttrCSSResolver;
import com.itextpdf.tool.xml.html.CssAppliers;
import com.itextpdf.tool.xml.html.CssAppliersImpl;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.ElementHandlerPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import com.jfinal.log.Log;
import com.jfinal.template.Engine;/** 
* @author 作者 : tomatocc
* pdf工具类
*/
public class PdfKit {private static Log log = Log.getLog(PdfKit.class);private PdfKit() {}/*** Creates a PDF with the words* * @param html* @param file* @throws IOException* @throws DocumentException*/public static void creatHtmlpdf(String html, String file) throws IOException, DocumentException {// step 1 new Document 默认大小A4Document document = new Document(PageSize.A4.rotate());// step 2PdfWriter.getInstance(document, new FileOutputStream(file));// step 3document.open();// step 4Paragraph context = new Paragraph();ElementList elementList = parseToElementList(html, null);for (Element element : elementList) {context.add(element);}document.add(context);// step 5document.close();}/*** 设置字体信息* @return*/private static Font getFontInf() {// 字体路径String fontPath =  PathKit.getWebRootPath() + "/WEB-INF/vm/font/simhei.ttf";BaseFont baseFont = null;Font font = null;try {// 设置字体路径,字体编码,是否将字体嵌入pdf(默认false)baseFont = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);// 设置默认字体数据font = new Font(baseFont, 12f,Font.NORMAL,BaseColor.BLACK);} catch (DocumentException e) {log.error("get pdf font info DocumentException " , e );} catch (IOException e) {log.error("get pdf font info IOException " , e );}return font;}/*** html转pdf 写法* @param html* @param css* @return* @throws IOException*/public static ElementList parseToElementList(String html, String css) throws IOException {// CSSCSSResolver cssResolver = new StyleAttrCSSResolver();if (css != null) {CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(css.getBytes()));cssResolver.addCss(cssFile);}// HTMLMyFontsProvider fontProvider = new MyFontsProvider();CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());htmlContext.autoBookmark(false);// PipelinesElementList elements = new ElementList();ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, end);CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);// XML WorkerXMLWorker worker = new XMLWorker(cssPipeline, true);XMLParser p = new XMLParser(worker);html = html.replace("<br>", "").replace("<hr>", "").replace("<img>", "").replace("<param>", "").replace("<link>", "");p.parse(new ByteArrayInputStream(html.getBytes()));return elements;}static class MyFontsProvider extends XMLWorkerFontProvider {public MyFontsProvider() {super(null, null);}@Overridepublic Font getFont(final String fontname, String encoding, float size, final int style) {return getFontInf();}}public static void main(String[] args) throws IOException, DocumentException {Map<String, Object> paramMap = new HashMap<String, Object>();// pdf路径String file = "d:/test2.pdf";// 读取html模板String html = Engine.use().setBaseTemplatePath(PathKit.getWebRootPath()).getTemplate("WEB-INF/vm/test.html").renderToString(paramMap);PdfKit.creatHtmlpdf(html, file);}
}
  • 下面是html
<html>
<head>
<style>
.col {padding: 3px 20px 3px 20px
}
</style>
</head>
<body><div style="background:rgb(230,230,230); padding:5px ;border:1px solidblack;"><b style="color:rgb(51,153,255)">测试html</b></div><br /><table border="0" style='border-collapse: collapse;'><tr><td class="col">姓名:</td><td class="col">tomatocc</td></tr><tr><td class="col">年龄:</td><td class="col">0age</td></tr><tr><td class="col">性别:</td><td class="col">boy</td></tr><tr><td class="col">职业:</td><td class="col">段子手</td></tr></table><br /><br /><br /><hr /><br />
</body>
</html>
接下来我们使用itext7中的html2pdf来实现html转pdf
  1. 首先需要下载jar包 点击下载,maven项目用下面坐标即可。
		  <dependency><groupId>com.itextpdf</groupId><artifactId>html2pdf</artifactId><version>2.1.4</version></dependency>
  1. 下面是代码部分
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.io.font.FontProgram;
import com.itextpdf.io.font.FontProgramFactory;
import com.itextpdf.layout.font.FontProvider;
import com.jfinal.log.Log;
import com.jfinal.template.Engine;/*** itext7中将html转pdf*/
public class Pdf7Kit {private static Log log = Log.getLog(Pdf7Kit.class);/*** 设置BaseFont* @param fontPath  字体路径* @return*/private static ConverterProperties creatBaseFont(String fontPath) {if(StrKit.isBlank(fontPath)) {fontPath =  PathKit.getWebRootPath() + "/WEB-INF/vm/font/simhei.ttf";}ConverterProperties properties = new ConverterProperties();FontProvider fontProvider = new DefaultFontProvider();FontProgram fontProgram;try {fontProgram = FontProgramFactory.createFont(fontPath);fontProvider.addFont(fontProgram);properties.setFontProvider(fontProvider);} catch (IOException e) {log.error("creat base font erro" , e );}return properties;}/*** 将html文件转换成pdf* @param htmlPath* @param pdfPath* @param fontPath* @throws IOException*/public static void creatPdf(String htmlPath , String pdfPath,String fontPath) throws IOException {if(StrKit.isBlank(htmlPath) || StrKit.isBlank(pdfPath)) {log.warn("html2pdf fail. htmlPath or pdfPath is null .");return;}// 拼接html路径String src = PathKit.getWebRootPath() + htmlPath;ConverterProperties properties = creatBaseFont(fontPath);HtmlConverter.convertToPdf(new File(src), new File(pdfPath),properties);}/*** 通过模板创建pdf* @param html html路径* @param pdf 生成的pdf路径* @param font  字体文件路径* @param paramMap 参数* @throws IOException*/public static void creatPdfByTem(String html , String pdf,String font ,Map<String, Object> paramMap) throws IOException {if(StrKit.isBlank(html) || StrKit.isBlank(pdf)) {log.warn("html2pdf fail. htmlPath or pdfPath is null .");return;}// 拼接临时文件目录String srctmp = PathKit.getWebRootPath() + html + StrKit.genUuid(true);File file = new File(srctmp);// 使用文件模板Engine.use().setBaseTemplatePath(PathKit.getWebRootPath()).getTemplate(html).render(paramMap, srctmp);ConverterProperties properties = creatBaseFont(font);HtmlConverter.convertToPdf(file, new File(pdf),properties);// 删除临时文件if(file.exists()) {file.delete();}}public static void main(String[] args) throws IOException {String pdfPath = "d:/test1.pdf";Map<String, Object> paramMap = new HashMap<String, Object>();paramMap.put("name","tomatocc");String htmlPath =  "/WEB-INF/vm/test.html";// 使用html模板创建pdf// creatPdfByTem(htmlPath, pdfPath, null, paramMap);// 将html转换成pdfcreatPdf(htmlPath, pdfPath, null);}}

代码中写了两个方法,第一个是将html转为pdf,是比较简单的,第二种是用html模板,将html转换成pdf,我的模板引擎用的是jfinal模板引擎,其他模板引擎是类似的,需要注意的是HtmlConverter.convertToPdf方法的第一个参数必须是FIle类型,之前模板引擎后的返回值都是String,因此需要做代码改造即可。

这里需要说明一个情况,如果项目中不引入字体文件,那么生成的pdf将不会显示文字(因为生产环境的服务器不会有任何字体文件,而本地运行的话,会自动去电脑中的字体文件库中去寻找字体文件),因此,如果是需要发布的项目,务必将字体文件放到项目中,然后进行使用。

【itext学习之路】系列教程

【itext学习之路】-----(第一篇)创建一个简单的pdf文档
【itext学习之路】-----(第二篇)设置pdf的一些常用属性
【itext学习之路】-----(第三篇)对pdf文档进行加密和权限设置
【itext学习之路】-----(第四篇)给pdf增加文本水印和图片水印
【itext学习之路】-----(第五篇)对pdf进行盖章/签章/数字签名
【itext学习之路】-----(第六篇)将html转成pdf(解决中文不显示)

欢迎关注本人个人公众号,交流更多技术信息

在这里插入图片描述

这篇关于【itext学习之路】-------(第七篇)将html转成pdf(解决中文不显示)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/906278

相关文章

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

Go语言实现将中文转化为拼音功能

《Go语言实现将中文转化为拼音功能》这篇文章主要为大家详细介绍了Go语言中如何实现将中文转化为拼音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 有这么一个需求:新用户入职 创建一系列账号比较麻烦,打算通过接口传入姓名进行初始化。想把姓名转化成拼音。因为有些账号即需要中文也需要英

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

基于C#实现PDF文件合并工具

《基于C#实现PDF文件合并工具》这篇文章主要为大家详细介绍了如何基于C#实现一个简单的PDF文件合并工具,文中的示例代码简洁易懂,有需要的小伙伴可以跟随小编一起学习一下... 界面主要用于发票PDF文件的合并。经常出差要报销的很有用。代码using System;using System.Col

Java操作PDF文件实现签订电子合同详细教程

《Java操作PDF文件实现签订电子合同详细教程》:本文主要介绍如何在PDF中加入电子签章与电子签名的过程,包括编写Word文件、生成PDF、为PDF格式做表单、为表单赋值、生成文档以及上传到OB... 目录前言:先看效果:1.编写word文件1.2然后生成PDF格式进行保存1.3我这里是将文件保存到本地后

Mysql DATETIME 毫秒坑的解决

《MysqlDATETIME毫秒坑的解决》本文主要介绍了MysqlDATETIME毫秒坑的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 今天写代码突发一个诡异的 bug,代码逻辑大概如下。1. 新增退款单记录boolean save = s

通过C#获取PDF中指定文本或所有文本的字体信息

《通过C#获取PDF中指定文本或所有文本的字体信息》在设计和出版行业中,字体的选择和使用对最终作品的质量有着重要影响,然而,有时我们可能会遇到包含未知字体的PDF文件,这使得我们无法准确地复制或修改文... 目录引言C# 获取PDF中指定文本的字体信息C# 获取PDF文档中用到的所有字体信息引言在设计和出

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情