/Java /Flying-Saucer使用HTML或者FTL(Freemarker模板)生成PDFcss
飛翔的拖鞋uphtml
Javajava
下載地址:http://pan.baidu.com/s/1i3pJ2PBide
PDF導出工具備itext,可是itext對中文支持很差,還有樣式CSS支持也很差,使用IReport比較複雜,上手不太容易,怎麼辦?工具
幸虧有Flying-Saucer這個項目,幫助咱們解決了以上問題!Flying-Saucer最重要的是很方便,不須要使用IReport的複雜操做,只會寫html就可以作PDF導出的模板。字體
使用freemarker的思路this
一、編寫ftl模板spa
二、使用freemarker生成htmlcode
三、根據生成的html在生成PDF
來一張圖片,不然無圖無真相
項目依賴
<
properties
>
<
servlet
>3.1.0</
servlet
>
<
freemarker
>2.3.22</
freemarker
>
<
flying-saucer
>9.0.3</
flying-saucer
>
</
properties
>
<
dependencies
>
<
dependency
>
<
groupId
>javax.servlet</
groupId
>
<
artifactId
>javax.servlet-api</
artifactId
>
<
version
>${servlet}</
version
>
<
scope
>provided</
scope
>
</
dependency
>
<
dependency
>
<
groupId
>org.freemarker</
groupId
>
<
artifactId
>freemarker</
artifactId
>
<
version
>${freemarker}</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.xhtmlrenderer</
groupId
>
<
artifactId
>flying-saucer-pdf</
artifactId
>
<
version
>${flying-saucer}</
version
>
</
dependency
>
</
dependencies
>
|
依賴關係圖
項目結構圖
主要的操做類
PdfUtils
package
org.xdemo.example.pdf;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.OutputStream;
import
java.util.HashMap;
import
java.util.Map;
import
javax.servlet.http.HttpServletResponse;
import
org.xhtmlrenderer.pdf.ITextRenderer;
import
com.lowagie.text.DocumentException;
import
freemarker.core.ParseException;
import
freemarker.template.MalformedTemplateNameException;
import
freemarker.template.TemplateException;
import
freemarker.template.TemplateNotFoundException;
/**
* PDF生成工具類
* @author Goofy <a href="http://www.xdemo.org">http://www.xdemo.org</a>
*
*/
public
class
PdfUtils {
public
static
void
main(String[] args) {
try
{
Map<Object, Object> o=
new
HashMap<Object, Object>();
o.put(
"name"
,
"http://www.xdemo.org/"
);
String path=PdfHelper.getPath();
generateToFile(path,
"resources/tpl.ftl"
,path+
"resources/"
, o,
"D:\\xdemo.pdf"
);
}
catch
(Exception e) {
e.printStackTrace();
}
}
/**
* 生成PDF到文件
* @param ftlPath 模板文件路徑(不含文件名)
* @param ftlName 模板文件嗎(不含路徑)
* @param imageDiskPath 圖片的磁盤路徑
* @param data 數據
* @param outputFile 目標文件(全路徑名稱)
* @throws Exception
*/
public
static
void
generateToFile(String ftlPath,String ftlName,String imageDiskPath,Object data,String outputFile)
throws
Exception {
String html=PdfHelper.getPdfContent(ftlPath, ftlName, data);
OutputStream out =
null
;
ITextRenderer render =
null
;
out =
new
FileOutputStream(outputFile);
render = PdfHelper.getRender();
render.setDocumentFromString(html);
if
(imageDiskPath!=
null
&&!imageDiskPath.equals(
""
)){
//html中若是有圖片,圖片的路徑則使用這裏設置的路徑的相對路徑,這個是做爲根路徑
render.getSharedContext().setBaseURL(
"file:/"
+imageDiskPath);
}
render.layout();
render.createPDF(out);
render.finishPDF();
render =
null
;
out.close();
}
/**
* 生成PDF到輸出流中(ServletOutputStream用於下載PDF)
* @param ftlPath ftl模板文件的路徑(不含文件名)
* @param ftlName ftl模板文件的名稱(不含路徑)
* @param imageDiskPath 若是PDF中要求圖片,那麼須要傳入圖片所在位置的磁盤路徑
* @param data 輸入到FTL中的數據
* @param response HttpServletResponse
* @return
* @throws TemplateNotFoundException
* @throws MalformedTemplateNameException
* @throws ParseException
* @throws IOException
* @throws TemplateException
* @throws DocumentException
*/
public
static
OutputStream generateToServletOutputStream(String ftlPath,String ftlName,String imageDiskPath,Object data,HttpServletResponse response)
throws
TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException, DocumentException{
String html=PdfHelper.getPdfContent(ftlPath, ftlName, data);
OutputStream out =
null
;
ITextRenderer render =
null
;
out = response.getOutputStream();
render = PdfHelper.getRender();
render.setDocumentFromString(html);
if
(imageDiskPath!=
null
&&!imageDiskPath.equals(
""
)){
//html中若是有圖片,圖片的路徑則使用這裏設置的路徑的相對路徑,這個是做爲根路徑
render.getSharedContext().setBaseURL(
"file:/"
+imageDiskPath);
}
render.layout();
render.createPDF(out);
render.finishPDF();
render =
null
;
return
out;
}
}
|
輔助類
package
org.xdemo.example.pdf;
import
java.io.File;
import
java.io.IOException;
import
java.io.StringWriter;
import
java.util.Locale;
import
org.xhtmlrenderer.pdf.ITextRenderer;
import
com.lowagie.text.DocumentException;
import
com.lowagie.text.pdf.BaseFont;
import
freemarker.core.ParseException;
import
freemarker.template.Configuration;
import
freemarker.template.MalformedTemplateNameException;
import
freemarker.template.Template;
import
freemarker.template.TemplateException;
import
freemarker.template.TemplateNotFoundException;
/**
* PDF生成輔助類
* @author Goofy <a href="http://www.xdemo.org">http://www.xdemo.org</a>
*
*/
@SuppressWarnings
(
"deprecation"
)
public
class
PdfHelper {
public
static
ITextRenderer getRender()
throws
DocumentException, IOException {
ITextRenderer render =
new
ITextRenderer();
String path = getPath();
//添加字體,以支持中文
render.getFontResolver().addFont(path +
"resources/ARIALUNI.TTF"
, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
render.getFontResolver().addFont(path +
"resources/SIMSUN.TTC"
, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
return
render;
}
//獲取要寫入PDF的內容
public
static
String getPdfContent(String ftlPath, String ftlName, Object o)
throws
TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
return
useTemplate(ftlPath, ftlName, o);
}
//使用freemarker獲得html內容
public
static
String useTemplate(String ftlPath, String ftlName, Object o)
throws
TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
String html =
null
;
Template tpl = getFreemarkerConfig(ftlPath).getTemplate(ftlName);
tpl.setEncoding(
"UTF-8"
);
StringWriter writer =
new
StringWriter();
tpl.process(o, writer);
writer.flush();
html = writer.toString();
return
html;
}
/**
* 獲取Freemarker配置
* @param templatePath
* @return
* @throws IOException
*/
private
static
Configuration getFreemarkerConfig(String templatePath)
throws
IOException {
Configuration config =
new
Configuration();
config.setDirectoryForTemplateLoading(
new
File(templatePath));
config.setEncoding(Locale.CHINA,
"utf-8"
);
return
config;
}
/**
* 獲取類路徑
* @return
*/
public
static
String getPath(){
return
PdfHelper.
class
.getResource(
""
).getPath().substring(
1
);
}
}
|
模板文件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
>
<
title
></
title
>
<
style
type
=
"text/css"
>
body {
margin-left: 45px;
margin-right: 45px;
font-family: Arial Unicode MS;
font-size: 10px;
}
table {
margin: auto;
width: 100%;
border-collapse: collapse;
border: 1px solid #444444;
}
th,td {
border: 1px solid #444444;
font-size: 10px;
margin-left: 5px;
}
.mcContent {
line-height: 180%;
padding: 20px;
}
.logo {
text-align: center;
}
.title {
text-align: center;
font-weight: bold;
font-size: 20px;
}
.notes {
font-weight: normal;
margin-left: 5px;
margin-right: 5px;
line-height: 18px;
}
.text_content {
margin-left: 5px;
margin-right: 5px;
line-height: 18px;
}
.sum_insured_first_row {
width: 20%;
}
.sum_insured_span {
font-size: 10px;
}
.special_agreements_div {
page-break-before: always;
font-size: 14px;
margin-top: 20px;
}
.special_agreements_div .special_agreements {
font-size: 18px;
font-weight: bold;
}
.title_right {
width: 100%;
margin: 0 auto;
}
.title_right p {
text-align: left;
margin: 0;
margin-left: 50%;
padding: 0;
}
@page {
size: 8.5in 11in;
@
bottom-center
{
content
:
"page "
counter(
page
)
" of "
counter(
pages
);
}
.signature {
margin: 0 auto;
clear: both;
font-size: 16px;
font-weight: bold;
}
.signature_table {
/* font-size: 16px; */
font-weight: bold;
}
</
style
>
</
head
>
<
body
>
做者:<
a
href
=
"http://www.xdemo.org/"
>http://www.xdemo.org/</
a
>
<
div
>
<
p
>你好:${name}</
p
>
<
div
class
=
"logo"
>
<!--這裏的圖片使用相對與ITextRenderer.getSharedContext().setBaseURL("file:/"+imageDiskPath);的路徑-->
圖片支持<
img
src
=
"logo1.png"
/>
</
div
>
<
div
>
<
p
>Hello PDF: 中文支持</
p
>
<
div
style
=
"border:1px solid red;color:red;"
>
樣式支持,紅邊框,紅字
</
div
>
<
div
style
=
"border:10px solid blue;color:blue;"
>
樣式支持,藍色10像素的邊框,藍字
</
div
>
<
hr
/>
<
table
>
<
tr
style
=
"background:gray;"
>
<
th
>A</
th
>
<
th
>B</
th
>
<
th
>C</
th
>
<
th
>D</
th
>
</
tr
>
<
tr
>
<
td
>100</
td
>
<
td
>29</
td
>
<
td
>32</
td
>
<
td
>43</
td
>
</
tr
>
<
tr
>
<
td
>100</
td
>
<
td
>29</
td
>
<
td
>32</
td
>
<
td
>43</
td
>
</
tr
>
<
tr
>
<
td
>100</
td
>
<
td
>29</
td
>
<
td
>32</
td
>
<
td
>43</
td
>
</
tr
>
<
tr
>
<
td
>100</
td
>
<
td
>29</
td
>
<
td
>32</
td
>
<
td
>43</
td
>
</
tr
>
<
tr
>
<
td
>100</
td
>
<
td
>29</
td
>
<
td
>32</
td
>
<
td
>43</
td
>
</
tr
>
</
table
>
</
div
>
</
div
>
</
body
>
</
html
>
|
注意
本 工具類提供了兩種字體支持中文,因此定義樣式的時候字體只能用:simsun或者arial unicode MS,不然中文顯示不出來,如需其餘字體另行添加),另外請注意圖片的路徑問題,html中z若是有圖片,圖片的路徑則使用這裏設置的路徑的相對路徑,這 個是做爲根路徑,如
<
div
class
=
"logo"
>
<!--這裏的圖片使用相對與ITextRenderer.getSharedContext().setBaseURL("file:/"+imageDiskPath);的路徑-->
圖片支持<
img
src
=
"logo1.png"
/>
</
div
>
|
若是須要PDF的下載,能夠經過generateToServletOutputStream這個方法來獲取PDF的輸出流,而後經過response寫到客戶端去
轉載請註明來源: http://www.xdemo.org/flying-saucer-html-freemarker-pdf/