1,需求:
接到一个需要说要把一个HTML页面生成PDF文档提供用的下载。接到这个需求我首页想到两问题。一个我们使用的插件首先要支持把HTML生成PDF。还要支持对HTML中的CSS能够做出解析。
2,ITEXT 简单介绍
在搜索的过程中找到了Itext 主页是: http://itextpdf.com/
仔细的浏览了一下网站发现 当前的版本中可以支持 1,可以进行块的创建;2,表格的使用3,设置页面的事件4,字体的设置,5,图片的设置(包含水印)6,HTML转化成PDF(支持css,javascript)7,表单创建,8,PDF之间的操作 等 。详细的内容可以查看网站的说明。
3,ITEXT入门
既然符合我们的要求那就写个例子看看:(下面是官网的一个简单例子可以)
table_css.html
<
html
>
<
head
>
<
style
>
table,
td
{
border
:
1px solid green
;
border-spacing
:
0px
;
padding
:
0px
;
}
</
style
>
</
head
>
<
body
>
<
table
class
=
'test'
>
<
tr
>
<
th
>
Firstname
</
th
>
<
th
>
Lastname
</
th
>
<
th
>
Savings
</
th
>
</
tr
>
<
tr
>
<
td
>
Peter
</
td
>
<
td
>
Griffin
</
td
>
<
td
>
$100
</
td
>
</
tr
>
<
tr
>
<
td
>
Lois
</
td
>
<
td
>
Griffin
</
td
>
<
td
>
$150
</
td
>
</
tr
>
<
tr
>
<
td
>
Joe
</
td
>
<
td
>
Swanson
</
td
>
<
td
>
$300
</
td
>
</
tr
>
<
tr
>
<
td
>
Cleveland
</
td
>
<
td
>
Brown
</
td
>
<
td
>
$250
</
td
>
</
tr
>
</
table
>
</
body
>
</
html
>
import
com.itextpdf.text.Document;
import
com.itextpdf.text.DocumentException;
import
com.itextpdf.text.pdf.PdfWriter;
import
com.itextpdf.tool.xml.XMLWorkerHelper;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileOutputStream;
import
java.io.IOException;
/**
*
*
@author
iText
*/
public
class
ParseHtmlTable {
public
static
final
String
DEST
=
"results/xmlworker/html_table.pdf"
;
public
static
final
String
HTML
=
"xml/table_css.html"
;
public
static
void
main(String[]
args
)
throws
IOException, DocumentException {
File
file
=
new
File(
DEST
);
file
.getParentFile().mkdirs();
new
ParseHtmlTable5 ().createPdf(
DEST
);
}
/**
* Creates a PDF with the words "Hello World"
*
@param
file
*
@throws
IOException
*
@throws
DocumentException
*/
public
void
createPdf(String
file
)
throws
IOException, DocumentException {
// step 1
Document
document
=
new
Document();
// step 2
PdfWriter
writer
= PdfWriter. getInstance(
document
,
new
FileOutputStream(
file
));
// step 3
document
.open();
// step 4
XMLWorkerHelper. getInstance().parseXHtml(
writer
,
document
,
new
FileInputStream(
HTML
));
// step 5
document
.close();
}
}
4,使用ITEXT出现的中文问题,和解决方案
在使用的过程会发现一个问题:在HTML中含有中文,生成PDF的时间就看不到。生成的PDF中只能显示了英文和数字的部分数据。这个在ITEXT中搜索好像也没有找到比较好的例子。
解决方案一:(这是一个官网的例子有中的处理)
import com.itextpdf.text.Document;import com.itextpdf.text.DocumentException;import com.itextpdf.text.pdf.PdfWriter;import com.itextpdf.tool.xml.XMLWorkerHelper;
import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.charset.Charset;
public class D07_ParseHtmlAsian {
public static final String HTML = "resources/xml/hero.html";
public static final String DEST = "results/xmlworker/hero.pdf";
/**
* Creates a PDF with the words "Hello World"
* @param file
* @throws IOException
* @throws DocumentException
*/
public void createPdf(String file) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
// step 3
document.open();
// step 4
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new FileInputStream(HTML), Charset.forName("UTF-8"));
// step 5
document.close();
}
/**
* Main method
*/
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new D07_ParseHtmlAsian().createPdf(DEST);
}}
hero.html
<p><span style="font-size:12.0pt; font-family:MS Mincho">長空
</span>
<span style="font-size:12.0pt; font-family:Times New Roman,serif">(Broken Sword),
</span>
<span style="font-size:12.0pt; font-family:MS Mincho">秦王殘劍
</span>
<span style="font-size:12.0pt; font-family:Times New Roman,serif">(Flying Snow),
</span>
<span style="font-size:12.0pt; font-family:MS Mincho">飛雪
</span>
<span style="font-size:12.0pt; font-family:Times New Roman,serif">(Moon),
</span>
<span style="font-size:12.0pt; font-family:MS Mincho">如月
</span>
<span style="font-size:12.0pt; font-family:Times New Roman,serif">(the King), and
</span>
<span style="font-size:12.0pt; font-family:MS Mincho">秦王
</span>
<span style="font-size:12.0pt; font-family:Times New Roman,serif">(Sky).
</span></p>
解决方案二:
http://www.iteye.com/topic/509417 来自
使用
flying sauser
这开源项目是专门对HTMLT和CSS的解析,并且能够良好的支持中文。
下面的例子代码就可以看出。实现的简单。
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.ArrayList;
import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.html.simpleparser.HTMLWorker;
import com.lowagie.text.html.simpleparser.StyleSheet;
import com.lowagie.text.pdf.PdfWriter;
public class MainClass {
public static void main(String[] args) throws Exception {
Document document = new Document();
StyleSheet st = new StyleSheet();
st.loadTagStyle("body", "leading", "16,0");
PdfWriter.getInstance(document, new FileOutputStream("html2.pdf"));
document.open();
ArrayList p = HTMLWorker.parseToList(new FileReader("example.html"), st);
for (int k = 0; k < p.size(); ++k)
document.add((Element) p.get(k));
document.close();
}
}
5,总结:
这两种方案中各有优缺点,
方案一,这个方面的资源比较少,并且要严格遵守ITEXT支持的CSS写法才能很好的支持。需要花较多的时间去学习。
方案二,flying sauser 是以ITEXT2.0的版本进行开发的现在已经不做更新。优点就是实现简单。 https://github.com/flyingsaucerproject/flyingsaucer 这个是它的源码有兴趣可以好好研究一下。
使用注意要点:
1,CSS样式的设置不支持 boder:1px 2px 1px 3px 类似这种写法。
2,表格不支持 thead标签
3,颜色的使用 rgb 表示
4,标签要成对才会减少报错。