來(lái)源:【itext學(xué)習(xí)之路】-------(第七篇)將html轉(zhuǎn)成pdf(解決中文不顯示)_tomatocc的博客-CSDN博客
在上一篇文章中,我們學(xué)習(xí)了使用對(duì)pdf進(jìn)行蓋章/簽章/數(shù)字簽名,到此為止,常用的pdf操作已經(jīng)全部實(shí)現(xiàn),但是實(shí)際開(kāi)發(fā)中很多人比較喜歡將html轉(zhuǎn)成pdf,本文介紹將html轉(zhuǎn)pdf的方法(之前用的都是itext5,這次需要用到itext7中的html2pdf這個(gè)強(qiáng)大的組件)
- 首先,先貼上代碼之前一直使用的itext5的方式,將html轉(zhuǎn)pdf(很多標(biāo)簽無(wú)法兼容)
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 默認(rèn)大小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();}/*** 設(shè)置字體信息* @return*/private static Font getFontInf() {// 字體路徑String fontPath = PathKit.getWebRootPath() + "/WEB-INF/vm/font/simhei.ttf";BaseFont baseFont = null;Font font = null;try {// 設(shè)置字體路徑,字體編碼,是否將字體嵌入pdf(默認(rèn)false)baseFont = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);// 設(shè)置默認(rèn)字體數(shù)據(jù)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轉(zhuǎn)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>
<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)">測(cè)試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">職業(yè):</td><td class="col">段子手</td></tr></table><br /><br /><br /><hr /><br />
</body>
</html>
接下來(lái)我們使用itext7中的html2pdf來(lái)實(shí)現(xiàn)html轉(zhuǎn)pdf
首先需要下載jar包?點(diǎn)擊下載,maven項(xiàng)目用下面坐標(biāo)即可。
<dependency><groupId>com.itextpdf</groupId><artifactId>html2pdf</artifactId><version>2.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轉(zhuǎn)pdf*/
public class Pdf7Kit {private static Log log = Log.getLog(Pdf7Kit.class);/*** 設(shè)置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文件轉(zhuǎn)換成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);}/*** 通過(guò)模板創(chuàng)建pdf* @param html html路徑* @param pdf 生成的pdf路徑* @param font 字體文件路徑* @param paramMap 參數(shù)* @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;}// 拼接臨時(shí)文件目錄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);// 刪除臨時(shí)文件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模板創(chuàng)建pdf// creatPdfByTem(htmlPath, pdfPath, null, paramMap);// 將html轉(zhuǎn)換成pdfcreatPdf(htmlPath, pdfPath, null);}}
代碼中寫了兩個(gè)方法,第一個(gè)是將html轉(zhuǎn)為pdf,是比較簡(jiǎn)單的,第二種是用html模板,將html轉(zhuǎn)換成pdf,我的模板引擎用的是jfinal模板引擎,其他模板引擎是類似的,需要注意的是HtmlConverter.convertToPdf方法的第一個(gè)參數(shù)必須是FIle類型,之前模板引擎后的返回值都是String,因此需要做代碼改造即可。
這里需要說(shuō)明一個(gè)情況,如果項(xiàng)目中不引入字體文件,那么生成的pdf將不會(huì)顯示文字(因?yàn)樯a(chǎn)環(huán)境的服務(wù)器不會(huì)有任何字體文件,而本地運(yùn)行的話,會(huì)自動(dòng)去電腦中的字體文件庫(kù)中去尋找字體文件),因此,如果是需要發(fā)布的項(xiàng)目,務(wù)必將字體文件放到項(xiàng)目中,然后進(jìn)行使用。
總結(jié)
以上是生活随笔為你收集整理的【itext学习之路】--6.将html转成pdf(解决中文不显示)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。