熬到半夜,终于整出来了。
第一步,引入fo-1.0.jar
<dependency> <groupId>org.apache.xmlgraphics</groupId> <artifactId>fop</artifactId> <version>1.0</version> </dependency>
第二步,编写1个测试fo,暂且叫做test01.xml
Eclipse中配置外部dtd的方法,见ws-JAX中关于dtd的那篇文章
<?xml version="1.0" encoding="UTF-8"?> <!-- 引入dtd,提供提示功能 --> <!DOCTYPE xsl-fo SYSTEM "fo.dtd"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="LetterPage"> <fo:region-body region-name="PageBody"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="LetterPage"> <fo:flow flow-name="PageBody" font-family="Microsoft YaHei" font-size="24pt"> <fo:block>Hello XSL-FO! 成功!</fo:block> </fo:flow> </fo:page-sequence> </fo:root>
第三步,引入字体,FOP默认提供的字体没得搞,不支持中文的。
以微软雅黑为例,该字体可以从windows/fonts目录中拷贝。
将fop.xconf配置放到java/main/resources目录下
并在java/main/resources目录下新建1个fonts目录
将windows/fonts目录下的需要的字体拷贝到resources/fonts目录中
打开fop.xconf文件,将微软雅黑字体配置进去
采用最简单的方法,提供1个字体目录,让fop到此目录下找需要的字体
注意:
fop配置文件中有一个相对路径的默认配置<base>.</base>
该路径指向的是项目的根目录,所以在指定字体目录时,是参考根目录写相对路径的
而不是文档中所描述的:Relative config url's will be resolved relative to the location of this file.
<renderer mime="application/pdf"> <filterList> <!-- provides compression using zlib flate (default is on) --> <value>flate</value> </filterList> <fonts> <directory>src/main/resources/fonts</directory> </fonts> <!-- This option lets you specify additional options on an XML handler --> <!--xml-handler namespace="http://www.w3.org/2000/svg"> <stroke-text>false</stroke-text> </xml-handler--> </renderer> .....
第四步,在程序中指定fop.xconf文件的位置,让fop在渲染时根据这个配置文件进行读取字体。
String path = PdfApplication.class.getClassLoader().getResource("fop.xconf").getPath(); fopFactory.setUserConfig(path);
第五步,运行程序,不出意外,将生成期待已久的PDF!
补充:
如果使用DTD校验fo,则引入其它命名空间会报错!
使用apache提供的xsd对fo进行校验,再引入thymeleaf的命名空间就不报错了。
附件中的几个文件的说明:
xconf is font character setting file
dtd is provided by RenderX
xsd is provided by apache FOP