Pdf 解决方案——fop

一,概览

先对比一下itext和fop,以下摘抄自Read  Sean大大(汗一个,转到该链接,我才发现博客园还有子站,虽然贴不如主站多,但是有当年主站群英会萃,琳琅满目的感觉)

[iText] (link)

iText我想大概不少人都有所耳闻,JasperReports默认的PDF支持就来自这个软件包,它处理速度快,支持很多PDF"高级"特性,如:Annotations、AcroForms、数字签名、加密等,支持对已有PDF的处理,通过iTextAsian.jar和iTextAsianCmaps.jar,它对中文的支持也不错。缺点是较为依赖Java代码,需要学习不少的专有API,当输入/输出格式有变化时,需要修改代码(除非手工写一些wrapper),不够灵活。

[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。具体代码:

有意思的评论:

从对Java友好这个角度,iText确实不错,但正因为这个特点,脱离了手写的Java代码,操作起来也就不是那么方便了。不像FOP,虽然不是100%标准实现,但思路还是清晰的,基本按照XSL-FO定义就能够做出比较漂亮的排版,不需要写任何Java代码。文中的例子只是示意,其实FOP通过命令行就能玩转,就算通过Java代码去调用,这段Java也是写一次就好,不管你格式多复杂。

对于项目预算有限,或者由于其他原因不能或不希望采用商业解决方案的情况,iText和FOP都是不错的选择,看具体项目/工程需要吧。对于纯输出,以我实际使用看,FOP效果已经很好了,大不了多写点XML,多画点<fo:table/>,死不了。

牵涉到的名词以及它们的关系如图:

其中的xlst其实是xlst扩展出来的XSL-FO,请联想用xlst格式化xml输出xml或html的场景来便于理解它的功用。看w3school的解释:

什么是 XSL-FO?

  • XSL-FO 是用于格式化 XML 数据的语言
  • XSL-FO 指可扩展样式表语言格式化对象(Extensible Stylesheet Language Formatting Objects)
  • XSL-FO 是一个 W3C 推荐标准
  • XSL-FO 目前通常被称为 XSL

XSL-FO 和格式化有关

XSL-FO 是一种基于 XML 的标记语言,用于描述向屏幕、纸或者其他媒介输出 XML 数据的格式化(信息)。

XSL-FO 目前通常被称为 XSL

为什么会存在这样的混淆呢?XSL-FO 和 XSL 是一回事吗?

可以这么说,不过我们需要向您作一个解释:

样式化(Styling)是关于转换信息格式化信息两方面的信息。在万维网联盟编写他们的首个 XSL 工作草案的时候,这个草案包括了有关转换和格式化 XML 文档的语言语法。

后来,XSL 工作组把这个原始的草案分为独立的标准:

  • XSLT,用于转换 XML 文档的语言
  • XSL 和 XSL-FO,用于格式化 XML 文档的语言
  • XPath,是通过元素和属性在 XML 文档中进行导航的语言

整个流程大概是先准备格式说明文件和数据文件(1),然后2,3,4步 从xml和xls得到扩展名为.fo或fob的xls-fo文档(红五),这三个步骤的序列化有很多语言由其处理xml的库或方法都能做到,基本就是调用一个方法,javascript和java早于.net,.net到了2.0版本才有了XslCompiledTransform和Transform方法类。第六步FOP,从xls-fo文档生成pdf文档,需要特殊类库支持。所就职的公司遗留下来的系统1-5步都在asp.net上,到了第六步post fo文档到java web service 去生成pdf.

所以fop解决方案需要两方面知识1,XSL-FO标记语言2,fop类库知识。类库就那几个方法,容易学习,xls-fo标记语言需要更多时间去记,去调试,其实也就如同html标记一样易学难用(布局,美观)。w3school有Xls-fo很好的学习资料,不多说。接着讨论FOP库。

二,FOP库

 java

java平台的同学总是很幸福的站在巨人的肩膀上。Apache™ FOP,成熟的fop库,成熟的实例-PDF Generation using XSLFO and FOP。先看第二个实例再看Apache fop可能会理解的更快,so easy的感觉。

.net

.net下有个库叫nfop,就包含一个dll,叫做ApacheFop.Net.dll。把Apache FOP 搬到了.net。有源码下载,非常奇葩 。从这个库,我了解到了原来在.net里,还可以用java的各种类库(添加vjslib引用后,从此世界更广大)。让我们来看一个demo

using System;

using System.Collections.Generic;

using System.Text;

using System.Xml;

using System.Xml.Xsl;

using System.IO;

using System.Net;

using System.Xml.XPath;

using org.apache.fop;

using org.apache.fop.apps;

using org.apache.fop.tools;

using org.xml.sax;

using java.io;

namespace CsharpFop

{

    class Program

    {

        static void Main(string[] args)

        {

            // Load the style sheet.

            XslCompiledTransform xslt = new XslCompiledTransform();

            xslt.Load(@"d:\books.xsl");

            // Execute the transform and output the results to a file.

            xslt.Transform(@"d:\books.xml", @"d:\books.fo");

            GeneratePDF(@"d:\books.fo", @"d:\books.pdf");

        }

        private static void GeneratePDF(string foFile, string pdfFile)

        {

           //混血儿代码

            FileInputStream streamFO = new FileInputStream(foFile);

            InputSource src = new InputSource(streamFO);

            FileOutputStream streamOut = new FileOutputStream(pdfFile);

            Driver driver = new Driver(src, streamOut);

            driver.setRenderer(1);

            driver.run();

            streamOut.close();

        }

    }

}

比较郁闷的java io stream类和.net io stream以文件为媒介转来转去。

无论是itext还是FOP,java还是.net都会遇到汉字问题,后面再去研究。

posted on 2012-03-12 18:29  arg  阅读(2580)  评论(1编辑  收藏  举报

导航