zoukankan      html  css  js  c++  java
  • 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都会遇到汉字问题,后面再去研究。

  • 相关阅读:
    Vue路由机制
    谷歌浏览器打不开应用商店的解决方法
    Vue报错——Component template should contain exactly one root element. If you are using vif on multiple elements, use velseif to chain them instead.
    Vue.js学习之——安装
    Vue使用axios无法读取data的解决办法
    关于localstorage存储JSON对象的问题
    2013年整体计划
    个人喜欢的警语收集
    Linux防火墙的关闭和开启
    Flex修改title 转载
  • 原文地址:https://www.cnblogs.com/wusong/p/2392237.html
Copyright © 2011-2022 走看看