1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 使用IText5+Freemarker生成PDF(模板可以使用CCS3分页效果)

使用IText5+Freemarker生成PDF(模板可以使用CCS3分页效果)

时间:2021-11-06 15:10:29

相关推荐

使用IText5+Freemarker生成PDF(模板可以使用CCS3分页效果)

iText介绍

iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。iText5是目前比较主流使用的因为免费,iText7是更好但收费的,所以这里我们还是乖乖使用5吧!!

项目要使用iText,必须引入jar包。才能使用,maven依赖如下:

<!-- itextpdf,导出pdf核心架包 --><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.11</version></dependency><!-- itextpdf工具包,用来解析html生成pdf --><dependency><groupId>com.itextpdf.tool</groupId><artifactId>xmlworker</artifactId><version>5.5.11</version></dependency><!-- flying saucer,支持对CSS高级特性的解析 --><dependency><groupId>org.xhtmlrenderer</groupId><artifactId>flying-saucer-pdf</artifactId><version>9.1.6</version></dependency>

其中

(1)com.itextpdf是必须的。

(2)com.itextpdf.tool是为了Freemarker的模板。

(3)org.xhtmlrenderer是为模板可以使用css3。

IText如果使用的字体是需要我们配置的,这个方式很好,我们可以引用主流或者自己喜欢的字体

网上都可以下载找到的,如果懒可以去这里下载【字体】

然后我们先来热热身

建立一个简单的pdf

import com.itextpdf.text.Document;import com.itextpdf.text.DocumentException;import com.itextpdf.text.pdf.PdfWriter;import com.itextpdf.tool.xml.XMLWorkerFontProvider;import com.itextpdf.tool.xml.XMLWorkerHelper;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.charset.Charset;public class JavaToPdfHtml {private static final String DEST = "D:/pdf/template.pdf";//输出地址private static final String HTML = "D:/pdf/template.html";private static final String FONT = "D:/pdf/simhei.ttf";public static void main(String[] args) throws IOException, DocumentException {// step 1Document document = new Document();// step 2PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(DEST));// step 3document.open();// step 4XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);fontImp.register(FONT);XMLWorkerHelper.getInstance().parseXHtml(writer, document,new FileInputStream(HTML), null, Charset.forName("UTF-8"), fontImp);// step 5document.close();}}

template.html

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><title>Title</title><style>body {font-family: SimHei;}.red {color: red;}</style></head><body><div class="red">hello world!</div><div class="red">你好,祖克</div></body></html>

效果:

好,然后我们再来加上Freemarker

package com.jy.pdf;import com.itextpdf.text.Document;import com.itextpdf.text.DocumentException;import com.itextpdf.text.pdf.PdfWriter;import com.itextpdf.tool.xml.XMLWorkerFontProvider;import com.itextpdf.tool.xml.XMLWorkerHelper;import freemarker.template.Configuration;import freemarker.template.Template;import java.io.ByteArrayInputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.StringWriter;import java.io.Writer;import java.nio.charset.Charset;import java.util.HashMap;import java.util.Map;public class JavaToPdfHtmlFreeMarker {private static final String DEST = "D:/pdf/templateF.pdf";private static final String FTL = "D:/pdf/";private static final String HTML = "templateF.html";private static final String FONT = "D:/pdf/simhei.ttf";private static Configuration freemarkerCfg = null;static {freemarkerCfg =new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);//freemarker的模板目录try {//freemarkerCfg.freemarkerCfg.setDirectoryForTemplateLoading(new File(FTL));} catch (Exception e) {e.printStackTrace();}}public static void createPdf(String content,String dest) throws IOException, DocumentException {// step 1Document document = new Document();// step 2PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));// step 3document.open();// step 4XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);fontImp.register(FONT);XMLWorkerHelper.getInstance().parseXHtml(writer, document,new ByteArrayInputStream(content.getBytes()), null, Charset.forName("UTF-8"), fontImp);// step 5document.close();}/*** freemarker渲染html*/public static String freeMarkerRender(Map<String, Object> data, String htmlTmp) {Writer out = new StringWriter();try {// 获取模板,并设置编码方式Template template = freemarkerCfg.getTemplate(htmlTmp);template.setEncoding("UTF-8");// 合并数据模型与模板template.process(data, out); //将合并后的数据和模板写入到流中,这里使用的字符流out.flush();return out.toString();} catch (Exception e) {e.printStackTrace();} finally {try {out.close();} catch (IOException ex) {ex.printStackTrace();}}return null;}public static void main(String[] args) throws IOException, DocumentException {Map<String,Object> data = new HashMap();data.put("name","路飛.祖克");String content = JavaToPdfHtmlFreeMarker.freeMarkerRender(data,HTML);JavaToPdfHtmlFreeMarker.createPdf(content,DEST);}}

templateF.html

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><title>Title</title><style>body {font-family: SimHei;}.red {color: red;}</style></head><body><div class="red">hello world!</div><div class="red">你好,${name}</div></body></html>

效果

加入ccs3,图片使用64位即可

package com.jy.pdf;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.StringWriter;import java.io.Writer;import java.util.HashMap;import java.util.Map;import mons.codec.binary.Base64;import org.xhtmlrenderer.pdf.ITextFontResolver;import org.xhtmlrenderer.pdf.ITextRenderer;import com.itextpdf.text.DocumentException;import com.itextpdf.text.pdf.BaseFont;import freemarker.template.Configuration;import freemarker.template.Template;public class JavaToPdfHtmlFreeMarkerCss {private static final String DEST = "D:/pdf/templateFCss.pdf";private static final String FTL = "D:/pdf/";private static final String HTML = "templateFCss.html";private static final String FONT = "D:/pdf//simhei.ttf";private static final String FONT_C = "D:/pdf//calibri.ttf";private static final String FONT_S = "D:/pdf//simsun.ttc";private static final String LOGO_PATH = "D:/pdf/logo.jpg";private static Configuration freemarkerCfg = null;static {freemarkerCfg =new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);//freemarker的模板目录try {freemarkerCfg.setDirectoryForTemplateLoading(new File(FTL));} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException, DocumentException, com.lowagie.text.DocumentException {Map<String,Object> data = new HashMap<String,Object>();data.put("name","路奇.D.艾尼路 儸傑");File file=new File(LOGO_PATH);data.put("fileType","image/jpeg");data.put("file64Str",fileToBase64Str(file));String content =freeMarkerRender(data,HTML);//System.out.println(content);createPdf(content,DEST);}/*** freemarker渲染html*/public static String freeMarkerRender(Map<String, Object> data, String htmlTmp) {Writer out = new StringWriter();try {// 获取模板,并设置编码方式Template template = freemarkerCfg.getTemplate(htmlTmp);template.setEncoding("UTF-8");// 合并数据模型与模板template.process(data, out); //将合并后的数据和模板写入到流中,这里使用的字符流out.flush();return out.toString();} catch (Exception e) {e.printStackTrace();} finally {try {out.close();} catch (IOException ex) {ex.printStackTrace();}}return null;}public static void createPdf(String content,String dest) throws IOException, DocumentException, com.lowagie.text.DocumentException {ITextRenderer render = new ITextRenderer();//设置字体ITextFontResolver fontResolver = render.getFontResolver();fontResolver.addFont(FONT_S, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);fontResolver.addFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);fontResolver.addFont(FONT_C, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);// 解析html生成pdfrender.setDocumentFromString(content);render.layout();render.createPDF(new FileOutputStream(dest));render.finishPDF();}/*** File to 64bit Str* * @param file* @return*/public static String fileToBase64Str(File file) {byte[] data = null;InputStream inputStream = null;if (file != null) {try {inputStream = new FileInputStream(file);data = new byte[inputStream.available()];inputStream.read(data);} catch (Exception e) {e.printStackTrace();} finally {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}return Base64.encodeBase64String(data);}return null;}}

templateFCss.html

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"/><title>Title</title><style>body{font-family:SimHei;}.color{color: green;}.pos{position:absolute;left:200px;top:5px;width: 200px;font-size: 10px;}@media print {div.header-right {display: block;position: running(header-right);}}@page {size: 8.5in 11in;@top-right {content: element(header-right)};/*@bottom-center {content : "Page " counter(page) " of " counter(pages);}; */@bottom-center {content: element(footer)}}#footer {position: running(footer);}#pages:before {content: counter(page);}#pages:after {content: counter(pages);}</style></head><body><div id="footer"><div style="text-align: center; width: 100%;font-size: 15px;">Page <span id="pages"> of </span></div></div><div class="page"><div class="color">你好,${name}222</div><img src="data:${fileType};base64,${file64Str}" width="600px" /></div></body></html>

效果,加上ccs3,就可以有分页的效果了

是不是很棒

PS:上次有同学分页有些东西会被隔开怎么办

CCS可以幫到你page-break-inside:avoid;這個是可以避免分頁的

測試template

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"/><title>Title</title><style>body{font-family:SimHei;}.color{color: green;}.pos{position:absolute;left:200px;top:5px;width: 200px;font-size: 10px;}@media print {div.header-right {display: block;position: running(header-right);}img{page-break-inside:avoid;}table{page-break-inside:avoid;}}@page {size: 8.5in 11in;@top-right {content: element(header-right)};/*@bottom-center {content : "Page " counter(page) " of " counter(pages);}; */@bottom-center {content: element(footer)}}#footer {position: running(footer);}#pages:before {content: counter(page);}#pages:after {content: counter(pages);}</style></head><body><div id="footer"><div style="text-align: center; width: 100%;font-size: 15px;">Page <span id="pages"> of </span></div></div><div class="page"><div class="color">你好,${name}222</div><img src="data:${fileType};base64,${file64Str}" width="600px" /><table border="1"><tr><th>Month</th><th>Savings</th></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr><tr><td>January</td><td>$100</td></tr></table></div></body></html>

效果

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。