- 浏览: 255725 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
aquarion:
非常感谢,解决了我的问题
Perspective 自定义设置扩展点 -
zheng_zhen:
好文章,进一步问您一下,请问自己实现的run/debug如何能 ...
【原创】Eclipse Launcher (Run/Debug As 菜单扩展)实现 -
salever:
mwdnjupt 写道http://www.xeclipse. ...
浅析OSGI的bundle依赖 -
mwdnjupt:
http://www.xeclipse.com/?p=1165 ...
浅析OSGI的bundle依赖 -
Tom.X:
插件化、模块化应遵循高内聚、低耦合的原则,尽量不要在各bund ...
浅析OSGI的bundle依赖
首先,技术为apache 的FOP,初级的问题我就不写了,下面记录一下遇到的问题的解决方案:
中文乱码问题
这个问题网上的解决方案非常之多,也不详细描述了,每个使用FOP的都会遇见,还是记录一下。
在fop.xconf文件中,修改pdf相关的render,添加中文字体配置
<renderer mime="application/pdf"> <filterList> <!-- provides compression using zlib flate (default is on) --> <value>flate</value> </filterList> <fonts> <font metrics-url="[%FOP_ROOT%]/simsun.xml" kerning="yes" embed-url="[%FOP_ROOT%]/fonts/simsun.ttc"> <font-triplet name="SimSun" style="normal" weight="normal"/> <font-triplet name="宋体" style="normal" weight="normal"/> </font> </fonts> </renderer>
当然你还使用其他的方式来添加字体配置,见http://xmlgraphics.apache.org/fop/0.95/configuration.html
其中的.xml文件是根据fop的字体读取类生成的,例如:
org.apache.fop.fonts.apps.TTFReader [options]
C:\myfonts\cmr10.ttf ttfcm.xm
通过 TTFReader类来直接通过代码生成也是一个选择,它提供的main方法中有详细的参数介绍说明。
更多的fop字体相关问题见http://xmlgraphics.apache.org/fop/trunk/fonts.html
很多问题,通过自己读一读官方的介绍问题就明白了。
中文粗、斜字体问题
这是最新的fop还没有解决的问题之一。
对于英文字体,都有normal、bold、italic三种对应的字体,例如上面的arial.ttf(normal)、arialb.ttf(bold),所以英文的粗体、斜体都没有问题的。
中文就有问题了,常用的宋体,一般使用都是windows的simsun(宋体)字体,这种字体没有对应的bold、italic版本,MS word实现中文粗体、斜体是自己计算的,而很可惜fop处理的pdf没有这种功能,因此,宋体的粗体、斜体就没有办法显示了。
如果想实现宋体的粗体,有两种方式实现:
1,下载宋体的粗体字体文件,然后按照处理宋体的一般字体文件一样,生成xml文件,然后在fop.xconf中配置字体,比如
<font metrics-url="[%FOP_ROOT%]/simsunb.xml" kerning="yes" embed-url="[%FOP_ROOT%]/fonts/simsunb.ttf"> <font-triplet name="SimSun" style="normal" weight="bold"/> <font-triplet name="宋体" style="normal" weight="bold"/> <font-triplet name="SimSun" style="italic" weight="bold"/> <font-triplet name="宋体" style="italic" weight="bold"/> </font>
这里的sinsunb.xml就是根据网上下载的粗宋体文件(simsunb.ttf)生成的,附件为一个可用的粗宋体文件,以及对应的xml文件。使用这些字体,生成的pdf就会有你下载的粗宋体的样式了,不过好不好看就再说了。
2,另一种方法,也就是我采用的办法,宋体的粗体其实可以用黑体代替,而fop没有自动进行这种关联,需要我们自己配置了,很简单
<font metrics-url="[%FOP_ROOT%]/simhei.xml" kerning="yes" embed-url="[%FOP_ROOT%]/fonts/simhei.ttf"> <font-triplet name="SimSun" style="normal" weight="bold"/> <font-triplet name="宋体" style="normal" weight="bold"/> <font-triplet name="SimSun" style="italic" weight="bold"/> <font-triplet name="宋体" style="italic" weight="bold"/> </font>
将粗体都交给黑体处理,效果比上一种方式好一点。
附件上传了一些处理过的宋体(simsun.xml.rar)、黑体(simhei.xml.rar)、隶书(simli.xml.rar)、楷体(simkai.xml.rar),对应的字体(ttf或ttc)文件太大,自己直接去C:/windows/fonts/目录下寻找即可。
背景图片、水印问题
有时候报告需要添加背景图片、或者水印,这时候需要修改fo文件,由于我们是直接根据html生成的,所以我们修改xsl-fo文件就行了。
我是用的xsl文件没有处理<html:body background=""/>属性,所以直接在xsl的页面配置中添加背景图片。
<fo:layout-master-set> <fo:simple-page-master master-name="first" xsl:use-attribute-sets="page"> <fo:region-body margin-top="{$page-margin-top}" margin-right="{$page-margin-right}" margin-bottom="{$page-margin-bottom}" margin-left="{$page-margin-left}" column-count="{$column-count}" column-gap="{$column-gap}" background-image="url('work/report/bg_header.jpg')" /> <xsl:choose> <xsl:when test="$writing-mode = 'tb-rl'"> <fo:region-before extent="{$page-margin-right}" precedence="true"/> <fo:region-after extent="{$page-margin-left}" precedence="true"/> <fo:region-start region-name="page-header" extent="{$page-margin-top}" writing-mode="lr-tb" display-align="before"/> <fo:region-end region-name="page-footer" extent="{$page-margin-bottom}" writing-mode="lr-tb" display-align="after"/> </xsl:when> <xsl:when test="$writing-mode = 'rl-tb'"> <fo:region-before region-name="page-header" extent="{$page-margin-top}" display-align="before"/> <fo:region-after region-name="page-footer" extent="{$page-margin-bottom}" display-align="after"/> <fo:region-start extent="{$page-margin-right}"/> <fo:region-end extent="{$page-margin-left}"/> </xsl:when> <xsl:otherwise><!-- $writing-mode = 'lr-tb' --> <fo:region-before region-name="page-header" extent="{$page-margin-top}" display-align="before"/> <fo:region-after region-name="page-footer" extent="{$page-margin-bottom}" display-align="after"/> <fo:region-start extent="{$page-margin-left}"/> <fo:region-end extent="{$page-margin-bottom}"/> </xsl:otherwise> </xsl:choose> </fo:simple-page-master> <fo:simple-page-master master-name="normal" xsl:use-attribute-sets="page"> <fo:region-body margin-top="{$page-margin-top}" margin-right="{$page-margin-right}" margin-bottom="{$page-margin-bottom}" margin-left="{$page-margin-left}" column-count="{$column-count}" column-gap="{$column-gap}" background-image="url('work/report/bg_content.jpg')" /> <xsl:choose> <xsl:when test="$writing-mode = 'tb-rl'"> <fo:region-before extent="{$page-margin-right}" precedence="true"/> <fo:region-after extent="{$page-margin-left}" precedence="true"/> <fo:region-start region-name="page-header" extent="{$page-margin-top}" writing-mode="lr-tb" display-align="before"/> <fo:region-end region-name="page-footer" extent="{$page-margin-bottom}" writing-mode="lr-tb" display-align="after"/> </xsl:when> <xsl:when test="$writing-mode = 'rl-tb'"> <fo:region-before region-name="page-header" extent="{$page-margin-top}" display-align="before"/> <fo:region-after region-name="page-footer" extent="{$page-margin-bottom}" display-align="after"/> <fo:region-start extent="{$page-margin-right}"/> <fo:region-end extent="{$page-margin-left}"/> </xsl:when> <xsl:otherwise><!-- $writing-mode = 'lr-tb' --> <fo:region-before region-name="page-header" extent="{$page-margin-top}" display-align="before"/> <fo:region-after region-name="page-footer" extent="{$page-margin-bottom}" display-align="after"/> <fo:region-start extent="{$page-margin-left}"/> <fo:region-end extent="{$page-margin-bottom}"/> </xsl:otherwise> </xsl:choose> </fo:simple-page-master> <fo:page-sequence-master master-name="standard"> <fo:repeatable-page-master-alternatives> <fo:conditional-page-master-reference master-reference="first" page-position="first" /> <fo:conditional-page-master-reference master-reference="normal"/> </fo:repeatable-page-master-alternatives> </fo:page-sequence-master> </fo:layout-master-set>
上面的代码中,在<fo:region-body>添加了background-image="url('work/report/bg_header.jpg')"属性,因此它生成的pdf就具有背景图片,当然如果你把bg_header.jpg透明度降低,就会获得水印效果了。
上面的代码还区别实现了首页和其他页的背景图片分别设置的功能,在
<fo:repeatable-page-master-alternatives> <fo:conditional-page-master-reference master-reference="first" page-position="first" /> <fo:conditional-page-master-reference master-reference="normal"/> </fo:repeatable-page-master-alternatives> </fo:page-sequence-master>
中指定page-position为first时使用first的master,而其他页使用normal的master。
页眉图片、页脚图片问题
熟悉fo的应该知道fo的页面布局,也就是layout,在定义好了layout时候,页面将分为上、下、左、右和中五个区域,上对应的就是页眉,所谓的page-header,下对应的就是页脚,所谓的page-footer,上下的距离和间距都可以在xsl文件设置。这里我们对页眉进行图片设置,
<fo:page-sequence master-reference="standard"> <fo:title> <xsl:value-of select="/html:html/html:head/html:title"/> </fo:title> <fo:static-content flow-name="page-header"> <fo:block line-height="10pt" font-size="9pt" font-family="宋体" text-align="start"> <fo:external-graphic width="6.26in" height="1in" content-height="scale-to-fit" content-width="scale-to-fit" src="work/report/header.jpg" /> </fo:block> </fo:static-content> <fo:static-content flow-name="page-footer"> <fo:block space-after.conditionality="retain" space-after="{$page-footer-margin}" xsl:use-attribute-sets="page-footer"> <xsl:if test="$page-number-print-in-footer = 'true'"> <xsl:text>- </xsl:text> <fo:page-number/> <xsl:text> -</xsl:text> </xsl:if> </fo:block> </fo:static-content> <fo:flow flow-name="xsl-region-body"> <fo:block xsl:use-attribute-sets="body"> <xsl:call-template name="process-common-attributes"/> <xsl:apply-templates/> </fo:block> </fo:flow> </fo:page-sequence>
使用刚刚定义的standard page-squence,在
<fo:static-content flow-name="page-header">
中添加
<fo:block line-height="10pt" font-size="9pt" font-family="宋体" text-align="start"> <fo:external-graphic width="6.26in" height="1in" content-height="scale-to-fit" content-width="scale-to-fit" src="work/report/header.jpg" /> </fo:block>
以获得页眉效果,这里也可以同时再添加文字,具体效果自己摸索了。
复制、打印、编辑权限问题
这个就比较容易了,通过fop user agent进行设置就行了。
FOUserAgent userAgent = fopFactory.newFOUserAgent(); useragent.getRendererOptions().put("encryption-params", new PDFEncryptionParams( null, "password", false, false, true, true)); Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent);
具体效果为:
1. userPassword: String, may be null
2. ownerPassword: String, may be null
3. allowPrint: true if printing is allowed
4. allowCopyContent: true if copying content is allowed
5. allowEditContent: true if editing content is allowed
6. allowEditAnnotations: true if editing annotations is allowed
更多参考http://xmlgraphics.apache.org/fop/trunk/pdfencryption.html
PS:加密以后,<a href=""></a>中定义的链接将不可用,转换时会自动生成一个与本地路径关联的地址,不知道是不是fop的bug,注释了加密代码后又都完全正常。
pdf生成失败检测
官方给出的例子中,无法得知pdf是否生成成功,失败了仅仅打出一些错误日志,这对于程序员来说是不够的,如果检测失败也是一个问题。下面的代码提供了这种功能,但是不太好
Result res = new SAXResult(fop.getDefaultHandler()); // Start XSLT transformation and FOP processing transformer.transform(src, res); FormattingResults result = fop.getResults(); if (result.getPageSequences() == null) { log.error("Convert to pdf failed"); out.close(); result = null; fop = null; return false; } result = null; fop = null; out.close();
htmld到pdf的过程比较坎坷,还会遇到很多不可预见的问题,比如html中的char set设置,可能需要很多类似
<!ENTITY tilde "~"> <!ENTITY florin "ƒ"> <!ENTITY elip "…"> <!ENTITY dag "†">
声明,还会遇到pdf中莫名其妙的乱码,比如黑体中的空格,这些都需要自己慢慢调试程序和标准化html。
附件还包含一个可用的fop.xconf文件、html测试文件以及xhtml2fo.xsl 转换文件。
PS:xhtml2fo.xsl文件为根据网上的原始文件修改和完善的,可能功能还不太完整,但是处理基本的html已经足够了。
20110126 更新
xhtml2fo.xsl无法显示<span></span>中的内容,原因为xsl中处理相关元素的代码有问题,更新一下:(替换相关内容)
<xsl:template match="html:span"> <fo:inline> <xsl:attribute name="role"> <xsl:value-of select="concat('html:', local-name())"/> </xsl:attribute> <!-- 处理span 内的文字 --> <xsl:apply-templates/> </fo:inline> </xsl:template>
- SimSunB.rar (2 MB)
- 下载次数: 28
- SimSunB.xml.rar (23.4 KB)
- 下载次数: 17
- simhei.xml.rar (2.3 KB)
- 下载次数: 14
- simsun.xml.rar (2.5 KB)
- 下载次数: 13
- SimLi.xml.rar (1.8 KB)
- 下载次数: 14
- SimKai.xml.rar (43.9 KB)
- 下载次数: 10
- fop_template.xconf_需要替换路劲信息_.rar (3.7 KB)
- 下载次数: 17
- test.html.rar (909 Bytes)
- 下载次数: 20
- xhtml2fo.xsl.rar (6.9 KB)
- 下载次数: 20
评论
这个不太清楚,我没有试过呢,你去fop的官网看看
This filter is not recommended as it doubles the data size -->
<value>ascii-hex</value>
导致体积增大了很多。
楼主的文章写得很好,多谢了。
PDF有没有API对内容进行压缩呀?
多谢了!!!
我觉得不是字体的原因吧,是不是你添加了很多图片导致pdf太大?
FOP好像没有专门进行pdf压缩的api,不过你可以看看其他的pdf java api,比如pdf box
PDF有没有API对内容进行压缩呀?
多谢了!!!
发表评论
-
Java 技能树
2016-07-25 18:58 818java技能树 -
Java看书笔记
2014-08-07 17:15 729这一篇专用于一些日常的Java读书笔记 先写一点关 ... -
XStream和Jackson的使用优化
2012-12-17 11:09 0marker一下,需要研究一下这2种lib的使用方式。 -
ArrayList与LinkedList的简单比较
2012-07-27 11:07 1560本文同步发表在http://www.xeclipse.com/ ... -
java.lang.System类浅析
2012-07-25 09:58 1922本文同步发表在 http://www.xeclipse.com ... -
Linux/Unix下JFreeChart的NoClassDefFoundError问题
2012-07-04 14:51 1678最近遇到这样一个问题,使用JFreechart 1.0.13开 ... -
【转】常见的开源协议
2011-08-12 15:47 519Mozilla Public License ... -
【转】JDK发布版本时间以及代号
2011-06-20 14:02 1590已发行的版本: 版本号 名称 中文名 发布日期 ... -
最近的apache学习计划
2011-06-09 11:58 1242最近可能会要做一些apache相关的学习和开发工作,有一些pr ... -
Object类wait,notify,notifyAll的使用
2011-05-06 11:02 1475这三个方法是java的基础类Object中定义的。 w ... -
Java nio 整理整理
2011-02-25 17:17 1113看了看Java的nio类库,整理一下思路。 1,Buf ... -
Java 内存的那些事
2011-02-22 10:38 5025虽然Java屏蔽了一下内存 ... -
一些有用的Web Service 地址
2011-02-11 11:11 2221这里记录一下比较有用的Web Service 地址,可能会有用 ... -
【转】如何在java程序中设置文件为“隐藏”属性
2010-10-19 10:55 1636引自http://linshiquan.iteye.com/b ... -
【转】字符,字节和编码
2010-10-18 10:09 1218引言 “字符与编码” ... -
Effective Java 第2版 笔记
2010-08-18 15:45 1880Item 1;Consider static factoriy ... -
Java, 那些美妙的书籍
2010-08-10 15:39 7223整理一下最近看过或者比较有兴趣的Java书籍,以供大家参考 ... -
Object的equals()重写
2010-08-10 14:49 1576JDK1.6 API写道 public boolean e ... -
Object的equals()与hashCode()的关系
2010-08-10 14:37 0笔者在以前Java项目中使用findbugs工具时,经常遇到一 ... -
学习JVM 之 class文件校验器
2010-07-21 11:29 1984JVM中的class文件校 ...
相关推荐
在Java后台生成PDF之前,我们往往需要先设计好数据页面的布局。这时,Freemarker模板引擎就派上了用场。Freemarker是一个基于模板的通用模板语言,它与Java紧密集成,主要用于生成HTML、XML或其他文本格式的文档。...
在Java编程中,我们可以利用IO流和字符串处理来实现简单的代码生成器,就像这个`CodeUtil`类所示。 `CodeUtil`类是一个静态工具类,用于生成HTML文件。它的主要功能是创建一个包含基本HTML结构、脚本和表格的文件。...
在Java中,开发人员可以利用多种库来读取、写入、编辑和转换PDF文档。 1. **Freetype-2.4.6**: Freetype是一个开源的字体渲染库,它允许程序动态地渲染字体。在处理PDF时,可能需要Freetype来正确显示和操作文档中...
iText不仅支持生成PDF和rtf格式的文档,还具备将XML和HTML文件转化为PDF的功能,大大扩展了其在各种应用场景中的实用性。 在使用iText时,首先需要引入相应的库文件,如压缩包中的`itextpdf-5.5.1.jar`,这是iText...
传统的纸质问卷调查存在诸多不便,如分发和回收困难、数据整理复杂等问题。而基于PDF表单的调查问卷系统能够有效解决这些问题,提升调研的效率和安全性。 #### 二、系统概述 该系统主要利用PDF表单的强大功能和JSP...
总结来说,JSP脚本元素调用Java代码是实现动态网页的关键,但为了提高开发效率和代码质量,应当尽量将业务逻辑移出JSP,采用MVC架构,利用独立的Java类和测试,同时善用EL和自定义标签以降低代码复杂度。这样的做法...
综上所述,Java Web开发人员应时刻关注这些安全问题,采取有效的预防措施,确保系统在提供服务的同时,能抵御各种潜在的攻击。通过过滤器和其他安全库,可以显著提高应用程序的安全性,防止数据泄露或系统受损。在...
在Freemarker中,我们可以利用Java代码将图片数据嵌入到模板中,比如从数据库获取图片的Base64编码,然后在Word文档中展示。这在生成报告时非常有用,例如根据用户数据生成个性化的图表或照片。 接下来,我们讨论...
为了解决这一问题,我们可以利用编程语言,如Java,来生成PDF格式的维基百科文章集合。本文将深入探讨如何利用Java技术实现这一目标。 首先,我们需要理解Java中的PDF处理库。iText是Java中广泛使用的PDF库,它提供...
报告生成器是ANSYS软件中的一个实用工具,用于在分析过程中收集图像和数据,并将它们组织成HTML格式的报告。...通过这些详细步骤和功能,报告生成器成为了一个强大的工具,帮助用户有效地整理和展示ANSYS分析结果。
Java提供了多种库来支持这种功能,例如Apache POI用于处理Microsoft Office格式(如Excel),iText或Flying Saucer用于生成PDF,以及JasperReports和BIRT这样的报表工具。 在给定的文件名中,`...
本书是第II卷,以开发人员在项目开发中经常遇到的问题和必须掌握的技术为中心,介绍了应用Java进行桌面程序开发各个方面的知识和技巧,主要包括Java语法与面向对象技术、Java高级应用、窗体与控件应用、文件操作...
本项目利用Java技术栈,结合Apache POI、iText和Jsoup库,实现了在Windows和Linux系统上将Word、Excel文档转换为PDF的功能。 首先,Apache POI是Java平台上的一个开源库,主要用于处理Microsoft Office格式的文件,...
它可以根据程序本身的结构,将批注经过处理重新整理成为一个纯粹的参考手册,对于后面利用您的程序代码的人而言将会减少许多的负担。 Doxygen 的使用可分为两大部分。首先是特定格式的批注撰写,第二便是利用 ...
JavaServer Faces(JSF)是一种基于Java的Web应用程序开发框架,它简化了用户界面组件的创建和管理,提高了开发效率。JSF的核心特性包括: 1. **标准和可扩展的用户界面组件**:JSF提供了一系列预定义的UI组件,如...
FusionCharts 是一款强大的图表组件,它利用Flash技术展示数据驱动的动态图表,适用于各种网页脚本语言环境,如HTML、JSP等。该组件的核心特点是通过XML作为数据接口,将数据转化为直观、交互式的图表。下面将详细...
1. Servlet可以与各种资源(如数据库、文件系统等)交互,生成动态内容并返回给客户端。 2. Servlet有权限控制,可以限制外部用户的访问。 3. 它可以从本地或远程存储激活。 4. 通过Servlet Tag技术,Servlet能在...