iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。iText5是目前比较主流使用的因为免费,iText7是更好但收费的,所以这里我们还是乖乖使用5吧!!
项目要使用iText,必须引入jar包。才能使用,maven依赖如下:
com.itextpdf
itextpdf
5.5.11
com.itextpdf.tool
xmlworker
5.5.11
org.xhtmlrenderer
flying-saucer-pdf
9.1.6
其中
(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 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(DEST));
// step 3
document.open();
// step 4
XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontImp.register(FONT);
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new FileInputStream(HTML), null, Charset.forName("UTF-8"), fontImp);
// step 5
document.close();
}
}
template.html
Title
hello world!
你好,祖克
效果:
好,然后我们再来加上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 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
// step 3
document.open();
// step 4
XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontImp.register(FONT);
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new ByteArrayInputStream(content.getBytes()), null, Charset.forName("UTF-8"), fontImp);
// step 5
document.close();
}
/**
* freemarker渲染html
*/
public static String freeMarkerRender(Map 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 data = new HashMap();
data.put("name","路飛.祖克");
String content = JavaToPdfHtmlFreeMarker.freeMarkerRender(data,HTML);
JavaToPdfHtmlFreeMarker.createPdf(content,DEST);
}
}
templateF.html
Title
hello world!
你好,${name}
效果
加入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 org.apache.commons.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 data = new HashMap();
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 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生成pdf
render.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
Title
你好,${name}222
效果,加上ccs3,就可以有分页的效果了
是不是很棒
PS:上次有同学分页有些东西会被隔开怎么办
CCS可以幫到你page-break-inside:avoid;這個是可以避免分頁的
測試template
Title
你好,${name}222
Month
Savings
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
January
$100
效果