<!-- Feedsky FEED发布代码开始 -->
欢迎点击此处订阅本Blog
<!-- FEED自动发现标记开始 --> <link title="RSS 2.0" type="application/rss+xml" href="http://feed.feedsky.com/softwave" rel="alternate"> <!-- FEED自动发现标记结束 -->
<!--Google 468*60横幅广告开始--><script type="text/javascript"><!-- google_ad_client = "pub-7343546549496470"; google_ad_width = 468; google_ad_height = 60; google_ad_format = "468x60_as"; google_ad_type = "image"; //2007-07-26: CSDN google_ad_channel = "6063905817"; google_color_border = "6699CC"; google_color_bg = "E6E6E6"; google_color_link = "FFFFFF"; google_color_text = "333333"; google_color_url = "AECCEB"; google_ui_features = "rc:6"; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script><!--Google 468*60横幅广告结束-->
本文转自
http://www.blogjava.net/sean/archive/2008/10/05/232577.html
由于工作需要,今天简单的看了一下Java生成PDF的相关资料。综合看下来,除了使用报表平台和OOo的附带工具,目前使用较为普遍的有两个途径:iText和Apache的FOP。从实际出发,我们分别看看两者处理带有中文的PDF的具体用法吧。
[iText]
(
link
)
iText 我想大概不少人都有所耳闻,JasperReports默认的PDF支持就来自这个软件包,它处理速度快,支持很多PDF"高级"特性, 如:Annotations、AcroForms、数字签名、加密等,支持对已有PDF的处理,通过iTextAsian.jar和 iTextAsianCmaps.jar,它对中文的支持也不错。缺点是较为依赖Java代码,需要学习不少的专有API,当输入/输出格式有变化时,需 要修改代码(除非手工写一些wrapper),不够灵活。目前的版本是2.1.3。具体代码:
Formatter.java
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
1
import
java.io.FileOutputStream;
2
3
import
com.lowagie.text.Document;
4
import
com.lowagie.text.Font;
5
import
com.lowagie.text.PageSize;
6
import
com.lowagie.text.Paragraph;
7
import
com.lowagie.text.pdf.BaseFont;
8
import
com.lowagie.text.pdf.PdfWriter;
9
10
public
class
Formatter{
11
12
public
static
void
main(String[]args)
throws
Exception{
13
Documentdocument
=
new
Document(PageSize.A4);
14
try
{
15
System.out.print(
"
GeneratingPDF
"
);
16
PdfWriter.getInstance(document,
new
FileOutputStream(
"
test.pdf
"
));
17
document.open();
18
//
iText自带的中文字体
19
BaseFontbf1
=
BaseFont.createFont(
"
STSong-Light
"
,
"
UniGB-UCS2-H
"
,BaseFont.NOT_EMBEDDED);
20
//
自定义字体
21
BaseFontbf2
=
BaseFont.createFont(
"
wqy-zenhei.ttf
"
,BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
22
Fontfont
=
new
Font(bf2,
12
,Font.NORMAL);
23
Paragraphp
=
new
Paragraph(
"
测试abc中文123
"
,font);
24
document.add(p);
25
System.out.println(
"
Done.
"
);
26
}
finally
{
27
document.close();
28
}
29
}
30
31
}
效果:
中文支持有默认的STSong-Light等字体,但为了优化输出效果,这里使用了文泉驿正黑字体。如果不指定中文字体,默认情况下中文字符不会显示。
[FOP]
(
link
)
FOP 出自Apache,在各大Java网站、论坛出现相对较低,我也是从DocBook这条线摸进来的,DocBook主要提供了一个现成的、符合一般技术书 籍要求的数据结构,而展现效果(如PDF),则是通过预定义好的XSL-FO来实现的。XSL-FO是W3C的标准,正式的名称是XSL,是XSL相关的 三大组件/语言中的一个,另外两个是XSLT和XPath。Apache的FOP是处理FO的众多proecessor之一,相比iText,支持的输出 格式更多,对W3C相关标准支持度高,格式定义可以完全脱离具体的Java代码,十分灵活,且控制力很强。缺点是大数据量时性能较差,默认中文支持不好。 目前的版本是0.95。具体代码:
test.xml
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
1
<?
xmlversion="1.0"encoding="UTF-8"
?>
2
<
source
>
3
<
title
>
4
FOPSample
5
</
title
>
6
<
paragraph
>
7
测试abc中文123
8
</
paragraph
>
9
</
source
>
test.xsl
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
1
<?
xmlversion="1.0"encoding="UTF-8"
?>
2
<
xsl:transform
version
="1.0"
3
xmlns:xsl
="http://www.w3.org/1999/XSL/Transform"
4
xmlns:fo
="http://www.w3.org/1999/XSL/Format"
>
5
6
<
xsl:template
match
="/"
>
7
<
fo:root
>
8
<
fo:layout-master-set
>
9
<
fo:simple-page-master
master-name
="A4-portrait"
10
page-height
="29.7cm"
page-width
="21.0cm"
margin
="2cm"
>
11
<
fo:region-body
/>
12
</
fo:simple-page-master
>
13
</
fo:layout-master-set
>
14
<
fo:page-sequence
master-reference
="A4-portrait"
>
15
<
fo:flow
flow-name
="xsl-region-body"
>
16
<
fo:block
font-family
="WenQuanYiZenHei"
font-size
="24pt"
>
17
<
xsl:value-of
select
="source/title"
/>
18
</
fo:block
>
19
<
fo:block
font-family
="WenQuanYiZenHei"
text-indent
="1cm"
>
20
<
xsl:value-of
select
="source/paragraph"
/>
21
</
fo:block
>
22
</
fo:flow
>
23
</
fo:page-sequence
>
24
</
fo:root
>
25
</
xsl:template
>
26
27
</
xsl:transform
>
fop-config.xml
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
1
<?
xmlversion="1.0"
?>
2
<
fop
version
="1.0"
>
3
<
base
>
.
</
base
>
4
<
source-resolution
>
72
</
source-resolution
>
5
<
target-resolution
>
72
</
target-resolution
>
6
<
default-page-settings
height
="29.7cm"
width
="21.0cm"
/>
7
<
renderers
>
8
<
renderer
mime
="application/pdf"
>
9
<
filterList
>
10
<
value
>
flate
</
value
>
11
</
filterList
>
12
<
fonts
>
13
<
directory
>
.
</
directory
>
14
<
auto-detect
/>
15
</
fonts
>
16
</
renderer
>
17
</
renderers
>
18
</
fop
>
Formatter.java
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
1
import
java.io.File;
2
import
java.io.FileOutputStream;
3
import
java.io.OutputStream;
4
5
import
javax.xml.transform.Result;
6
import
javax.xml.transform.Source;
7
import
javax.xml.transform.Transformer;
8
import
javax.xml.transform.TransformerFactory;
9
import
javax.xml.transform.sax.SAXResult;
10
import
javax.xml.transform.stream.StreamSource;
11
12
import
org.apache.fop.apps.FOUserAgent;
13
import
org.apache.fop.apps.Fop;
14
import
org.apache.fop.apps.FopFactory;
15
import
org.apache.fop.apps.MimeConstants;
16
17
public
class
Formatter{
18
19
public
static
void
main(String[]args)
throws
Exception{
20
Filesource
=
new
File(
"
test.xml
"
);
21
Filespecs
=
new
File(
"
test.xsl
"
);
22
Filetarget
=
new
File(
"
test.pdf
"
);
23
FopFactoryfopFactory
=
FopFactory.newInstance();
24
fopFactory.setUserConfig(
"
fop-config.xml
"
);
//
读取自定义配置
25
FOUserAgentfoUserAgent
=
fopFactory.newFOUserAgent();
26
OutputStreamout
=
new
FileOutputStream(target);
27
out
=
new
java.io.BufferedOutputStream(out);
28
try
{
29
System.out.print(
"
GeneratingPDF
"
);
30
Fopfop
=
fopFactory.newFop(MimeConstants.MIME_PDF,foUserAgent,out);
31
TransformerFactoryfactory
=
TransformerFactory.newInstance();
32
Transformertransformer
=
factory.newTransformer(
new
StreamSource(specs));
33
Sourcesrc
=
new
StreamSource(source);
34
Resultres
=
new
SAXResult(fop.getDefaultHandler());
35
transformer.transform(src,res);
36
System.out.println(
"
Done.
"
);
37
}
finally
{
38
out.close();
39
}
40
}
41
42
}
效果:
FOP 的中文支持(其实是自定义字体支持),在0.94版本之前,十分有限,对每一个需要使用的TrueType字体,都需要生成一个metrics文件,在 0.94和之后的版本,则没有这个要求,且可以自动扫描系统字体和指定文件夹中的TTF字体。如果不配置中文字体,默认情况下,中文字符在PDF中将被处 理成"#"。
上面的示例代码虽然简单,但展示了FOP真正强大的地方,那就是控制力。这里篇幅有限,不可能全部特性都一一涉及,这个简单 的例子至少可以让我们看到从原始的XML格式的数据,通过XSLT按照自定义的规则转换成XSL-FO,最后输出到PDF的过程,每一步都可以在Java 代码之外进行严格控制。
以上是我对iText和FOP一些基本特点和用法的整理,它们各有特点,大家可以根据各自需要继续深入研究,FOP和iText相结合也未尝不可。希望能够帮助到有需要的朋友。
<!--新Google 468*60横幅广告开始--><script type="text/javascript"><!-- google_ad_client = "pub-7343546549496470"; /* 468x60, 创建于 08-8-6 */ google_ad_slot = "7368701459"; google_ad_width = 468; google_ad_height = 60; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script><!--新Google 468*60横幅广告结束-->
<!--新Google 468x15 横链接单元开始--><script type="text/javascript"><!-- google_ad_client = "pub-7343546549496470"; /* 468x15 横链接单元 */ google_ad_slot = "5785741422"; google_ad_width = 468; google_ad_height = 15; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script><!--新Google 468x15 横链接单元结束-->
<!-- Google Reader shared发布代码开始 --><script type="text/javascript" src="http://www.google.com/reader/ui/publisher.js"></script><script type="text/javascript" src="http://www.google.com/reader/public/javascript/user/00697638153916680411/state/com.google/broadcast?n=5&callback=GRC_p(%7Bc%3A%22green%22%2Ct%3A%22%5Cu8FD9%5Cu4E9B%5Cu6587%5Cu7AE0%5Cu4E5F%5Cu503C%5Cu5F97%5Cu4E00%5Cu770B%22%2Cs%3A%22false%22%7D)%3Bnew%20GRC"></script><!-- Google Reader shared发布代码结束 -->
Java动态生成PDF的两个开源工具-iText与FOP