fop初步

1.简介
FOP可以用来将xml转换成pdf。
当然他还支持输出成其他格式,输出支持的格式有PDF, PS, PCL, AFP, XML (area tree representation), Print, AWT, PNG, RTF, TXT。
输入的格式是XSL-FO,可以是单独的一个fo文件,或者采用xml+xslt结合的方式。

2.下载
先去[url=http://xmlgraphics.apache.org/fop/]官网[/url]下载包fop-1.1-bin.zip,目前最新版是1.1。
然后解压,可以看到根目录下有一个fop.bat,等下命令行执行要用到它。
lib目录是依赖的一些jar包。

3.第一个例子
3.1 写一个xml,等下我们要将这个xml用FOP转成pdf
name.xml


Frank
中文你好



3.2 写样式表(XSL-FO),此样式表定义生成的pdf的格式
name2fo.xsl


xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">




page-height="29.7cm" page-width="21.0cm" margin="2cm">






Hello, !


Hello, !








将name.xml和name2fo.xsl都放到和fop.bat同一级目录下

3.3 运行命令

D:\fop-1.1>fop -xml name.xml -xsl name2fo.xsl -pdf name.pdf

Jul 1, 2014 3:49:08 PM org.apache.fop.events.LoggingEventListener processEvent
WARNING: Font "Microsoft YaHei,normal,400" not found. Substituting with "any,normal,400".
Jul 1, 2014 3:49:08 PM org.apache.fop.events.LoggingEventListener processEvent
WARNING: Glyph "?" (0x4e2d) not available in font "Times-Roman".
Jul 1, 2014 3:49:08 PM org.apache.fop.events.LoggingEventListener processEvent
INFO: Rendered page #1.


可以看到提示找不到中文字体(Microsoft YaHei)

3.4 解决字体问题
3.4.1 将配置文件conf/fop.xconf拷贝一份出来到根目录,然后修改











3.4.2 重新执行命令,注意加入-c参数,指定我们修改后的配置文件。

fop -c fop.xconf -xml name.xml -xsl name2fo.xsl -pdf name.pdf

第一次执行比较慢,会去加载操作系统的字体。第二次就快了(缓存到哪里了不清楚)。

执行结果如图所示
[img]http://dl2.iteye.com/upload/attachment/0098/6714/cf1ace12-dbce-3bcc-9ab6-47743765d95b.png[/img]

4. 体会一下和itext的区别
优点:可以看到使用fop生成pdf,不需要编写java代码,执行命令行就行了。而且做到了内容和样式分离。
缺点:需要学习XSL-FO来编写样式表

5. 调用java api
如果硬要用java api的方式来调用,也是可以的。
可以参见官方文档[url]http://xmlgraphics.apache.org/fop/1.1/embedding.html[/url]

2014/09/25更新
官方文档有些错误,以下是我费劲九牛二虎之力试验出来的一种方法
maven的pom文件,官方居然将dependency都搞错,只能用以下的workaround




org.apache.xmlgraphics
fop
1.1


org.apache.avalon.framework
avalon-framework-api


org.apache.avalon.framework
avalon-framework-impl





avalon-framework
avalon-framework-api
4.2.0


avalon-framework
avalon-framework-impl
4.2.0



然后是试验成功的代码,是从stackoverflow搞来的。官方文档怎么不靠谱啊?

package org.xpen.hello.pdf;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;

public class FopTest {

public static void main(String[] args) throws Exception {

// Step 1: Construct a FopFactory
FopFactory fopFactory = FopFactory.newInstance();
fopFactory.setUserConfig(new File("src/test/resources/pdf/fop/fop.xconf"));

// Step 2: Set up output stream.
OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("target/abc.pdf")));

// Step 3: Construct fop with desired output format
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);

// Step 4: Setup JAXP using identity transformer
TransformerFactory factory = TransformerFactory.newInstance();
Source xslt = new StreamSource(new File("src/test/resources/pdf/fop/name2fo.xsl"));
Transformer transformer = factory.newTransformer(xslt);

// Step 5: Setup input and output for XSLT transformation
// Setup input stream
Source src = new StreamSource(new File("src/test/resources/pdf/fop/name.xml"));

// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());

// Step 6: Start XSLT transformation and FOP processing
transformer.transform(src, res);

// Clean-up
out.close();
}

}



6. 使用ant task
也可以直接在ant中调用task















上述代码将查找目录下所有fo文件,将他们全部转为pdf。

7. 参考资料
[url=http://hi.baidu.com/evekcin/item/647023ad11e5e0f014329b02]CSS中文字体列表[/url]

你可能感兴趣的:(PDF)