JavaiText+FreeMarker⽣成PDF(HTML转PDF)
1.背景
在某些业务场景中,需要提供相关的电⼦凭证,⽐如⽹银/⽀付宝中转账的电⼦回单,签约的电⼦合同等。⽅便⽤户查看,下载,打印。⽬前常⽤的解决⽅案是,把相关数据信息,⽣成对应的pdf⽂件返回给⽤户。
本⽂源码:
2.iText
iText是著名的开放源码的站点sourceforge⼀个项⽬,是⽤于⽣成PDF⽂档的⼀个java类库。通过iText不仅可以⽣成PDF或rtf的⽂档,⽽且可以将XML、Html⽂件转化为PDF⽂件。
iText 官⽹:
iText 开发⽂档:
iText⽬前有两套版本iText5和iText7。iText5应该是⽹上⽤的⽐较多的⼀个版本。iText5因为是很多开发者参与贡献代码,因此在⼀些规范和设计上存在不合理的地⽅。iText7是后来官⽅针对iText5的重构,两个版本差别还是挺⼤的。不过在实际使⽤中,⼀般⽤到的都⽐较简单,所以不⽤特别拘泥于使⽤哪个版本。⽐如我们在中搜索iText,出来的都是iText5的依赖。
来个最简单的例⼦:
添加依赖:
<!-- mvnrepository/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
测试代码:JavaToPdf
package st;
import Document;
import DocumentException;
import Paragraph;
import pdf.PdfWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
* Created by lujianing on 2017/5/7.
*/
public class JavaToPdf {
private static final String DEST = "target/HelloWorld.pdf";
public static void main(String[] args) throws FileNotFoundException, DocumentException {
Document document = new Document();
PdfWriter writer = Instance(document, new FileOutputStream(DEST));
document.open();
document.add(new Paragraph("hello world"));
document.close();
writer.close();
}
}
运⾏结果:
3.iText-中⽂⽀持
iText默认是不⽀持中⽂的,因此需要添加对应的中⽂字体,⽐如⿊体f
可参考⽂档:
测试代码:JavaToPdfCN
package st;
import Document;
import DocumentException;
import Font;
import FontFactory;
import Paragraph;
import pdf.BaseFont;
import pdf.PdfWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
* Created by lujianing on 2017/5/7.
*/
public class JavaToPdfCN {
private static final String DEST = "target/HelloWorld_CN.pdf";
private static final String FONT = "f";
public static void main(String[] args) throws FileNotFoundException, DocumentException {
Document document = new Document();
PdfWriter writer = Instance(document, new FileOutputStream(DEST));
document.open();
Font f1 = Font(FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);        document.add(new Paragraph("hello world,我是鲁家宁", f1));
document.close();
writer.close();
}
}
输出结果:
java修改html文件4.iText-Html渲染
在⼀些⽐较复杂的pdf布局中,我们可以通过html去⽣成pdf
可参考⽂档:
添加依赖:
<!-- mvnrepository/artifact/l/xmlworker -->
<dependency>
<groupId>l</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
添加模板: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">
你好,鲁家宁
</div>
</body>
</html>
测试代码:JavaToPdfHtml
package st;
import Document;
import DocumentException;
import pdf.PdfWriter;
import l.xml.XMLWorkerFontProvider;
import l.xml.XMLWorkerHelper;
import st.util.PathUtil;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
/**
* Created by lujianing on 2017/5/7.
*/
public class JavaToPdfHtml {
private static final String DEST = "target/HelloWorld_CN_HTML.pdf";
private static final String HTML = CurrentPath()+"/template.html";
private static final String FONT = "f";
public static void main(String[] args) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = Instance(document, new FileOutputStream(DEST));
/
/ step 3
document.open();
// step 4
XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);        ister(FONT);
new FileInputStream(HTML), null, Charset.forName("UTF-8"), fontImp);
// step 5
document.close();
}
}
输出结果:
需要注意:
1.html中必须使⽤标准的语法,标签⼀定需要闭合
2.html中如果有中⽂,需要在样式中添加对应字体的样式
5.iText-Html-Freemarker渲染
在实际使⽤中,html内容都是动态渲染的,因此我们需要加⼊模板引擎⽀持,可以使⽤FreeMarker/Velocity,这⾥使⽤FreeMarker举例添加FreeMarke依赖:
<!-- mvnrepository/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.19</version>
</dependency>
添加模板:template_freemarker.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
<style>
body{
font-family:SimHei;
}
.
blue{
color: blue;
}
</style>
</head>
<body>
<div class="blue">
你好,${name}
</div>
</body>
</html>
测试代码:JavaToPdfHtmlFreeMarker
package st;
import Document;
import DocumentException;
import pdf.PdfWriter;
import l.xml.XMLWorkerFontProvider;
import l.xml.XMLWorkerHelper;
import st.util.PathUtil;
plate.Configuration;
plate.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;
/**
* Created by lujianing on 2017/5/7.
*/
public class JavaToPdfHtmlFreeMarker {
private static final String DEST = "target/HelloWorld_CN_HTML_FREEMARKER.pdf";
private static final String HTML = "template_freemarker.html";
private static final String FONT = "f";
private static Configuration freemarkerCfg = null;
static {
freemarkerCfg =new Configuration();
//freemarker的模板⽬录
try {
freemarkerCfg.setDirectoryForTemplateLoading(new CurrentPath()));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException, DocumentException {
Map<String,Object> data = new HashMap();
data.put("name","鲁家宁");
String content = JavaToPdfHtmlFreeMarker.freeMarkerRender(data,HTML);
}
public static void createPdf(String content,String dest) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = Instance(document, new FileOutputStream(dest));
// step 3
document.open();
// step 4
XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);        ister(FONT);
new Bytes()), null, Charset.forName("UTF-8"), fontImp);
// step 5
document.close();
}
/**
* freemarker渲染html
*/
public static String freeMarkerRender(Map<String, Object> data, String htmlTmp) {
Writer out = new StringWriter();
try {
// 获取模板,并设置编码⽅式
Template template = Template(htmlTmp);
template.setEncoding("UTF-8");
/
/ 合并数据模型与模板
template.process(data, out); //将合并后的数据和模板写⼊到流中,这⾥使⽤的字符流
out.flush();
String();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return null;
}
}
输出结果:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。