Apache FOP 使用笔记-1

版本

apache FOP 2.9 

JDK 1.8 (1.8以上就可以)

目录

1.xsl文件

2.java xsl+xml-> fo方法 

3.fo文件

4.java fo-> pdf

5.config文件 中文导出


中文资料不多,很多也没有说清楚,所以这里写一个文档来记录使用过程。

官网网址,内容是英文的,同时在w3school与菜鸟上都有一些文档,但是都不全面

Apache(tm) FOP - a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter.

官网上下载的压缩包有示例代码,但是其中包含的jar包内容不全,缺少大量的依赖,比如

MimeConstants.MIME_PDF

就缺失,会导致无法导出PDF。

首先其中会有xsl/xslt,xml,fo,pdf的概念,如果使用Java开发流程应该是xsl/xslt+xml-> fo -> PDF(想要使用xsl/xslt导出PDF失败了,没有找到成功运行的代码),在cmd中可以直接xsl+xml生成PDF。

在xsl/xslt中,是一些结构化的标签,可以同时使用xsl与fo两种标签。生成fo文件后,内容已经固定了。xsl可以从xml或者外部数据源获取数据,可生成表格列表之类的数据结构,输出到fo文件后,就不能再动态的获取数据了,但是可以引用图片之类的信息。

1.xsl文件

生成结构类似于前端的div盒子模型,同样有margin, padding,border的数据,但是没找到让两个元素在水平层面上平级显示的方法,关于宽度等设置也遇到了很多问题,现在仍在解决中,图片说明了位置组成,但是实际使用中,通过background-color属性着色后,发现覆盖顺序与图片不同,(左右两侧是最高优先度,上下第二优先度)。推测可能跟声明顺序有关,并且几个区域体积碰撞也有问题,碰到过body内容被end覆盖,需要通过margin控制块的索引以保证不会互相覆盖,margin可以用百分比进行尺寸控制。

布局主要使用标签按顺序是

<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo">

        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

                <fo:layout-master-set>

                        <fo:simple-page-master>

                                <fo:region-body>......

                <fo:page-sequence>

                        <fo:static-content>

                                <fo:block>

                        <fo:flow>

                                 <fo:block>

                                        <fo:inline>

大概顺序就是这样的,其中我理解的是layout-master-set 声明的是页面与主体,page-sequence 声明的是会顺序拼接内容,根据name的名称将内容填装到body,start,end,before,after中,使用过程中同时存在多个会报错,不确定是否是写法有问题。

static-content 声明是静态块,应该无法在静态块中进行动态的数据提取。

block类似于html的div标签,是一种块状标签,width无法生效,没有找到将两个块平行布置的方法。

2.java xsl+xml-> fo方法 

代码运行后会将xml+xsl生成of文件

//将 xml,xsl,fo文件路径都声明成file
public void convertXML2FO(File xml, File xslt, File fo)
                throws IOException, TransformerException {

        //Setup output
        OutputStream out = new java.io.FileOutputStream(fo);
        try {
            //Setup XSLT
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(new StreamSource(xslt));

            //Setup input for XSLT transformation
            Source src = new StreamSource(xml);

            //Resulting SAX events (the generated FO) must be piped through to FOP
            Result res = new StreamResult(out);

            //Start XSLT transformation and FOP processing
            transformer.transform(src, res);
        } finally {
            out.close();
        }
    }

3.fo文件

fo文件于xsl文件相比,少了xsl相关的标签,以<fo:root>为根结点,内容就是动态拼接完成的内容。

4.java fo-> pdf

生成PDF,需要配置文件等信息,三个文件地址分别对应config,pdf,fo文件地址。

FopFactory fopFactory = FopFactory.newInstance(new File(""));

        // Step 2: Set up output stream.
        // Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams).
        OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("")));
        FONode node ;
        try {
            // Step 3: Construct fop with desired output format
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
            //MIME_PDF

            // Step 4: Setup JAXP using identity transformer
            TransformerFactory factory = TransformerFactory.newInstance();


            // Step 5: Setup input and output for XSLT transformation
            // Setup input stream
            Transformer transformer = factory.newTransformer(); // identity transformer
            Source src = new StreamSource(new File(""));

            // 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);

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

5.config文件 中文导出

这部分放到4之前也可以,不需要有什么大的改动,但是fop不支持直接导出中文。所以需要一些设定,统一放在这里。

首先需要在xsl或者fo文件中声明字符集 font-family="SourceHanSansTC",一般是放在block或者其他直接包文字的标签上。

其次需要在config文件中<font>标签中,声明字符集文件(参考:https://www.cnblogs.com/hiyue95hyf/p/16799475.html),在2.9中不需要配置xml文件,在网上或者自己生成一个ttf文件即可,配置中的地址是与config文件平级,不平级,需要自行调整结构。

	<font embed-url="SourceHanSansTC-Normal.ttf" sub-font="SourceHanSansTC">
    	<font-triplet name="SourceHanSansTC" style="normal" weight="normal"/>
    	<font-triplet name="SourceHanSansTC" style="normal" weight="bold"/>
    	<font-triplet name="SourceHanSansTC" style="italic" weight="normal"/>
    	<font-triplet name="SourceHanSansTC" style="italic" weight="bold"/>
	</font>

其中sub-font后的参数要跟font-family后的数据相同。博客的说法是要将<auto-detect/>  注释掉,直接注释掉没测试过,推测无所谓,因为是顺序执行,只要之前的拦截住就可以。

  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值