山东网站推广有限公司,建立个人网站的目的,江苏10大网站建设公司,网页浏览器软件有来源#xff1a;【itext学习之路】-------#xff08;第七篇#xff09;将html转成pdf(解决中文不显示)_tomatocc的博客-CSDN博客
在上一篇文章中#xff0c;我们学习了使用对pdf进行盖章/签章/数字签名#xff0c;到此为止#xff0c;常用的pdf操作已经全部实现#x…来源【itext学习之路】-------第七篇将html转成pdf(解决中文不显示)_tomatocc的博客-CSDN博客
在上一篇文章中我们学习了使用对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默认falsebaseFont 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 {MapString, Object paramMap new HashMapString, 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
bodydiv stylebackground:rgb(230,230,230); padding:5px ;border:1px solidblack;b stylecolor:rgb(51,153,255)测试html/b/divbr /table border0 styleborder-collapse: collapse;trtd classcol姓名/tdtd classcoltomatocc/td/trtrtd classcol年龄/tdtd classcol0age/td/trtrtd classcol性别/tdtd classcolboy/td/trtrtd classcol职业/tdtd classcol段子手/td/tr/tablebr /br /br /hr /br /
/body
/html接下来我们使用itext7中的html2pdf来实现html转pdf
首先需要下载jar包 点击下载maven项目用下面坐标即可。dependencygroupIdcom.itextpdf/groupIdartifactIdhtml2pdf/artifactIdversion2.1.4/version/dependency下面是代码部分
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 ,MapString, 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;MapString, Object paramMap new HashMapString, 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将不会显示文字因为生产环境的服务器不会有任何字体文件而本地运行的话会自动去电脑中的字体文件库中去寻找字体文件因此如果是需要发布的项目务必将字体文件放到项目中然后进行使用。