Prawn:使用 Ruby 生成 PDF 更简捷

  • Sebastien Auvray
  • 赵斯思

2008 年 8 月 18 日

话题:RubyRuby on Rails社区语言 & 开发文化 & 方法

Ruby 生成 PDF 的方法已经有很多了。出于对已有的解决方案的不满,Gregory Brown 决定自己设计更快的库——使用 DSL 方法生成 PDF。大家认为Prawn应该是比其他任何 Ruby 的 PDF 程序库都要快的库。

安装了 Prawn 后你就可以使用使用 DSL 式的方法生成一个简单的 PDF(例子来自于一个 Prawn 的样例程序):



Prawn::Document.generate("image.pdf", :page_layout => :landscape) do

text 'Welcome in Prawn!', :at => [50,525]

pigs = "data/images/dice.png"



image pigs, :at => [50,450], :scale => 0.5

ruport = "data/images/ruport_transparent.png"



image ruport, :at => [50,525]

end



这个小例子将会生成如下的 PDF:



毫无疑问,Prawn 将吸引 Rails/Ruport世界的目光,在 Edge Ruport 中的 PDF::Writer 将会很快被 Prawn 所取代。Prawn 的发布是采访的 Gregory 的最佳契机,他还建立的由社区资助的项目:Ruby Mendicant。6 个月前,Gregory 发出号召,希望大家资助其在接下来的 6 个月将要专注于的开源项目。在募集到超过 10000 美元以后,Gregory 选择了 Prawn。



InfoQPrawn 又是个 PDF 程序库吗?

Gregory Brown:Prawn 与其它的 Ruby 的 PDF 库有显著的不同:它不是使用其他语言编写的 PDF 库的移植,也不是低层次库的封装。我们并不研究其他的解 决方案,除非我们需要考虑一些特定的方面。所以我怀疑我们正在创建某个已有的 PDF 解决方案的副本。我们希望这是个好东西,并且它能提供一个更自然的解决 问题的方法。
是什么致使你编写它?

感谢 Ruby Mendicant 项目所提供的时间,我知道我能解决一个困难的问题。PDF 规范有超过 1300 页以上,尽管其中只有一部分关注于 PDF 生成,这也是个可 怕的任务,不太可能使用业余时间很容易地完成。我需要一个舒服的 PDF 库来帮助工作,这给了我很大的动力去阅读。催化剂是 James Gray 的一个贴子,贴子中建议说写一个新库比维护 PDF::Writer 从长期来看消耗更少的努力。你可以从
这里看到这篇文章。 为什么你放弃 PDF::Writer?

我没有放弃。从技术上说,我仍旧是维护者,并且将会修正关键的问题,然后发布它们直到 Prawn 被广泛接受。目前我做的唯一决定是不会有 PDF::Writer 1.2,至少我不会为它工作。Michael Milner 和我几个月前从 Austin Ziegler 手中接管 PDF::Writer,仅仅是因为没有人能接手这个工作,其中这些年积累起来的非常多的修补需要被应用到它上面。我们发布了这些 维护成果,这让 PDF::Writer 更好。

但是有一个原因致使 PDF::Writer 找不到维护者:代码在很大程度上不可维护。尽管这个库在它那个时代是不错的,但是要扩展或修补它却困难重重。这 就是为什么我认为 Prawn 是向前之路,有一个机会去避免一些在当年第一次开发 PDF::Writer 时无法发现的缺陷。

Prawn 的性能应该更好吧?

它在表渲染上快得多。这主要是因为算法的不同,库本身没有对一些细节进行优化。但是,这些算法的不同将导致数级的性能提升,不再有人抱怨性能问题了。;)
你进行了一些测评吗?

我 们有一个和代码一起发布的测试,测试比较了 Prawn 和 PDF writer 生成一个含有 1833 条记录的两列表格。在我的机器上,Prawn 花费了 3.5 秒,PDF::Writer 花费了 90-100 秒。当你增加数 据量时,这个差距将会增大。在添加了新的特性以后,这两个库的性能可能比较类似,但是我自己并没有运行过这些测试。

我也听到过 Prawn 比 FPDF(一个 PHP 同名库的移植)快得多的报告,但是我自己并没有进行测评。一个用户提到他的报表生成代码原来耗费 3 分钟,使用 Prawn 后只耗费 37 秒。





你能和其它低层次的库竞争吗?

我没有就 C 库和类似的东西进行测评。我认为目标是让 Prawn 成为快速的 Ruby 库,性能达到可用。我内心希望 Prown 是纯 Ruby 并且保持代码尽量可 读,我并不会牺牲这些以压榨出每一分性能。但是用户们可以确定我们会关注性能并避免 PDF 成为瓶颈而致使他们使用其它语言实现。
你能和其它语言编写的库竞争吗?

当我为 Prawn 调研时,我关注过另外两种我喜欢的语言:Perl 和 Python。我不得不说它们中没有一种提供了让我印象极其深刻的解决方案。虽然 Prawn 尝试保持简单并且以核心功能为中心,我认为它与其它语言编写的库相比,有更好的接口。

当然,我在 Ruby 上花的时间比在 Perl 和 Python 上花的时间多得多,所以我可能忽略了一些东西。如果是这样,我真心希望借鉴尽可能多的好想法。

你能告诉我们更多关于六个月前立的 Ruby Mendicant 的情况吗?

这 是一个突然的念头,感觉到过度压力和因为我的合同工作而感觉到烦恼的时候,我在 O'Reilly 博客上发了一个贴子。我说我希望从工作中抽出一些时间专心 工作于开源。一些人很重视我,当足够的人开始支持我时,我设立了一个捐款运动。一个月以后,我有了 22 周的资助,这就是 Ruby Mendicant 如何而来。

为什么你选择 PDF 生成作为你第一个项目呢?



PDF 生成是我的一些想法之一。接下来社区中最流行的事情是专用文本方面,当我接触到一批类库并且整理好 rdoc,或许写一些教程。PDF 受到越来越多支持,人们因为它目标单一一致而喜欢它。它是我真正需要的东西,这使我更容易保持对它的热情,所以我认为它是个好选择。



你短期的计划是什么?

在近期内,Prawn 将可以进行基本的内联风格化。我们也正在向图像支持添加一些附加特性,使你可以保持图片比例的同时缩放图片。我们同时也有一个增加 Prawn 表格生成灵活性的大计划。

马上,你就能创建由基本绘图操作、图像和其它你要想的东西所组成的组件,并且能将这些组件连接到表格单元中,就像将他们添加到文字中一样。这些组件同样可以直接在 PDF 中渲染,也许在多个位置。也许我们将会允许人们编写一些简洁的以核心插件形式分发的第三方小部件。





长期的呢?

我很希望同 PDF::Writer 的用户一起找出必要的特性并移植到 Prown 中使 PDF::Writer 的用户可以迁移到 Prawn。最大的障碍是我们 并不会试图提供任何 API 兼容特性,但是我们的特性和稳定将很又希望将人们吸引过来。我的梦想是让 PDF::Writer 退休,将 Prawn 的命名空间改 为 PDF,成为 PDF::Document。

当这成为现实,我想与 PDF::Reader(目前由 James Healy 维护)紧密集成。尽管它们仍旧是独立的 gem 包,我想将它们统一到一个单一的 Ruby PDF 项目下。然后我们可以将其他的 PDF 相关包也放进来,我们有就一个真正的统一的 Ruby 的 PDF 解决方案。

但是这些都依赖于事情的发展速度和社区的对此想法的看法。时间将会告知一切。





现在 Ruby 骇客的生活困难吗?

这 怎么可能?我们是紧俏商品,客户需要我们多于我们需要他们。我们的社区是了不起的,即使在巨大的成长的烦恼下,Rails 坚定地来到我们面前。但是,我不 能抱怨社区,他们付钱让他们信赖的一些人为他们修改项目。这展示了虽然商业成功在继续,仍有许多人支持草根的努力。这非常令人鼓舞。

我知道的主要问题是互联网大肆宣传机器创造了一大批的戏剧性事件并且歪曲了公众注意力,使得人们倾向于认为 Ruby 程序员是一群只喜欢 Ruby 而抨击所有 其他东西的狂热者。一般来说这错的离谱。一些伟大的 Ruby 人实际上比外人更人容易被这事情烦恼,所以我对此也感觉到痛苦。;)





为什么你停止了在 Oreilly 的博客?

我将会在 Oreilly 新闻上发表博客文章。O'Reilly 正在改变它们内部的博客网络,其中有一些不能为公众讨论的巨大变化。但是我仍将在 O'Reilly 说 Ruby,只是 URL 有变化。O'Reilly 新闻内容的标准将有些不同,但我喜欢事情这样发展。

关于我非正式的技术贴,我正在开始一个与独立于我个人博客的博客,以使其更加专注。一旦我正在构建的博客软件完成,关注那些事情的可以密切关注我。

总之,两个地方都可以让我涉猎 Ruby 外的各种语言和概念。我经常想写一写我正在使用的各种 *nix 工具, 我也正打算花更多时间在 Erlang 上面,所以它能够让我写一些不同的、我认为更有趣的文章。

RubyRuby on Rails社区语言 & 开发文化 & 方法