Apache FOP 将Java对象转换为pdf文件

标签: apache fop java | 发表时间:2018-01-15 11:38 | 作者:april2017
出处:http://www.iteye.com
最近因为项目需要将对象打印特定模式的PDF,经大佬建议,选择了使用FOP,较之iText,灵活性更强,对代码依赖更少。

下面简要说明一下如何使用及demo。

1. 需求描述

    根据现有一个pdf模板,将值填入pdf中导出。其中,值从Java一个List<Map<String, Object>>获取,每个Map展示在一页pdf中,整个List生成为一个pdf文件。   

2. 需求分析

    1)生成pdf模板

    2)将每个Map循环填入pdf中,使得每个Map占用单独一页

3. 技术探测

    1)进入fop官网 https://xmlgraphics.apache.org/fop/ 学习,最快捷的方法就是将官网提供的Examples下载到本地运行,这样可以有更直观的感受,可以帮助快速get关键点。

    2)fop是一个基于xsl(制作pdf模板)来生成pdf文件的。可以插入图片,将xml,Java对象,SVG等转换为pdf格式的文件。

    3)由于xsl确定样式,所以Java代码里只需要提供要展示的值即可,将样式与代码解耦。只要值确定,无论后续pdf样式如何更改,Java代码都无需再动,便于维护。而正因为样式由xsl决定,所以FOP的可定制性非常强,推荐使用。

4. 实践

    经过分析,发现fop在将Java对象转换为pdf时,先将对象转换为了xml格式,所以本需求的完成主要聚集在以下两点:

    1) xsl学习----官网提供的examples代码里有相对简单的fop.xml文件,可以作为入门。更多的知识点需要学习fo:xsl以及xsl语法,可参考 http://www.w3school.com.cn/xslfo/index.asp、http://www.w3school.com.cn/xsl/xsl_languages.asp;模板制作好后,可参考https://xmlgraphics.apache.org/fop/quickstartguide.html下方,使用命令行 fop -xml XXX.xml -xsl XXX.xsl -pdf xxx.pdf 来测试模板是否为目标模板,此时不需要Java代码参与,更省时省力:)

    2) Java对象转xml (采用XStream)

          由于需要转换的为List<Map<String, Object>>对象,而fop模板文件中会引用map中的key,而简单的使用XStream无法满足需求(只会将key和value的值同时打印出来,而xml标签里是key/value的详细类型),需要使用XStream提供的Convertor类(从XStream的jar包里取出了MapConvertor类到本地修改),进行简要的转换,使得生成的xml标签为Map的key,而值是Map的value。

关键代码下所示:

public boolean canConvert(Class type)
	  {
	    if (this.type != null) {
	      return type.equals(this.type);
	    }
	    return (type.equals(HashMap.class)) || 
	      (type.equals(Hashtable.class)) || 
	      (type.getName().equals("java.util.LinkedHashMap")) || 
	      (type.getName().equals("java.util.concurrent.ConcurrentHashMap")) || 
	      (type.getName().equals("sun.font.AttributeMap") || 
	      (type.equals(HashedMap.class)) );
	  }
	  
	  public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context)
	  {
	    Map map = (Map)source;
	    for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();)
	    {
	      Map.Entry entry = (Map.Entry)iterator.next();
	      ExtendedHierarchicalStreamWriterHelper.startNode(writer, entry.getKey().toString(), entry.getClass());
	      
	      writeItem(entry.getValue(), context, writer);
	      
	      writer.endNode();
	    }
	  }


    3)关键点
    3.1)模板---每个Map成为一页,这里使用xsl:for-each
<fo:page-sequence master-reference="A4-portrait">
  <fo:flow flow-name="xsl-region-body">
   <fo:block>
     <xsl:for-each select="List/map">
       ...
        <!-----加上if判断,使得最后一页不生成空白页-->
        <xsl:if test="last()>position()">
         <fo:block break-before="page"/>
        </xsl:if>
     </xsl:for-each>
   </fo:block>
</fo:flow>
</fo:page-sequence>

   3.2)模板---由于要生成不定行的表格(表头一定,但表行数视具体数据而定),使用
    <fo:table-body>   
       <xsl:apply-templates select="XXX"/>
        ...
    </fo:table-body>
    <xsl:template match="XXX">
    ...
    </xsl:template>
    注意:这里的"XXX"指的是xml中的xpath(不熟悉的需要学习一下),根据这个path,才能找到惟一的标签,这样才能取出标签中的值
   





已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [apache fop java] 推荐:

Apache FOP 将Java对象转换为pdf文件

- - 开源软件 - ITeye博客
最近因为项目需要将对象打印特定模式的PDF,经大佬建议,选择了使用FOP,较之iText,灵活性更强,对代码依赖更少. 下面简要说明一下如何使用及demo.     根据现有一个pdf模板,将值填入pdf中导出. 其中,值从Java一个List>获取,每个Map展示在一页pdf中,整个List生成为一个pdf文件.

Apache Thrift - java开发详解

- - 编程语言 - ITeye博客
2、编写IDL文件 Hello.thrift. 4、编写实现类、实现Hello.Iface:. 5、编写服务端,发布(阻塞式IO + 多线程处理)服务.      * 阻塞式、多线程处理 .             //设置传输通道,普通通道  .             //使用高密度二进制协议  .

Apache Thrift入门2-Java代码实现例子

- - J2EE企业应用 顾问/咨询- H.E.'s Blog
  在上一篇文章中提到了Thrift的架构、传输协议( Ref),本篇文章将对Thrift的入门实例进行介绍. 分为如下5个部分: 运行环境、安装/配置、脚本文件、创建代码、运行程序. 二、安装/配置 (清单2).     1.下载thrift源文件.     2.编译thrift源文件.         1)解压 thrift-0.5.0.tar.gz.

文章: Apache Crunch:用于简化MapReduce编程的Java库

- - InfoQ cn
Apache Crunch(孵化器项目)是基于Google的 FlumeJava库编写的Java库,用于创建MapReduce流水线. 与其他用来创建MapReduce作业的高层工具(如Apache Hive、Apache Pig和Cascading等)类似,Crunch提供了用于实现如连接数据、执行聚合和排序记录等常见任务的模式库.

Apache Shiro 介绍

- - CSDN博客推荐文章
什么是Apache Shiro?. Apache shiro 是一个强大而灵活的开源安全框架,可清晰地处理身份认证、授权、会话(session)和加密. Apache Shiro最主要的初衷是为了易用和易理解,处理安全问题可能非常复杂甚至非常痛苦,但并非一定要如此. 一个框架应该尽可能地将复杂的问题隐藏起来,提供清晰直观的API使开发者可以很轻松地开发自己的程序安全代码.

Apache Derby Papers

- -
Derby Type System (Note: if your browser shows HTML source for this page instead of displaying it, save the file locally with . It will prompt you to click on "Grant license to ASF for inclusion in ASF works", and this is the permission we need in place to host your contribution on the Derby web site..

Apache防止攻击

- - 小彰
为了防止恶意用户对Apache进行攻击,我们需要安装mod_security这个安全模块. mod_security 1.9.x模块的下载与安装. 下载地址: http://www.modsecurity.org/download/index.html. 建议使用1.9.x,因为2.x的配置指令与1.x完全不同,解压后进入解压目录,执行:.

Apache OpenOffice 3.4发布

- - Solidot
Apache OpenOffice的第一个版本v3.4正式发布. 主要新特性包括:改进ODF支持,包括ODF 1.2加密选项和新电子表格功能;改进Calc组件的数据透视表(Pivot Table)支持;原生支持SVG,增强图形如线帽和剪切变形;简体和繁体中文等原生语言支持;改进性能等. 在甲骨文将OpenOffice.org捐给Apache软件基金会后,OOo的命运曾存在许多争议.

Apache PDFBox 1.8.0 发布

- - 开源中国社区最新新闻
Apache PDFBox 1.8.0 发布了,该版本除了修复大量 bug 之外,还包含如下新特性:. PDFBox是Java实现的PDF文档协作类库,提供PDF文档的创建、处理以及文档内容提取功能,也包含了一些命令行实用工具. PDF 文档加密与解密. 与 Lucene搜索引擎的集成. 填充PDF/XFDF表单数据.

Apache Log4j 2.0介绍

- - CSDN博客推荐文章
Apache Log4j 2.0介绍. 作者:chszs,转载需注明. 作者博客主页:http://blog.csdn.net/chszs. Apache Log4j是著名的Java日志框架之一,在早些年应用最广. 但近两年来,随着SLF4J和LogBack的兴起,很多流行的开源框架在日志模块方面逐步转移到SLF4J+LogBack上,Log4j日渐衰落.