【问题标题】:Make PDF reports in Perl?在 Perl 中制作 PDF 报告?
【发布时间】:2011-09-23 21:11:14
【问题描述】:

所有用于 Perl 的 PDF 库似乎都有些野蛮——停留在 1980 年代。您必须指定 PostScript 点才能进行布局。 Java 有 JasperReports,Ruby 有 Prawn,Python 有 ReportLab。是否有一个未灭绝的库/模块可以让我在不到一周的编码时间内制作出漂亮的 PDF? (我对 PDF::API2、PDF::Table 等感到有点沮丧)我不想生成 HTML 并对其进行转换。 Perl 是报告的理想选择,但主要报告文件格式不可用。人们使用哪些库?

我需要:

  • 表格
  • 图表(图片)
  • 颜色
  • 格式化(最好是自动的,不是逐个像素)
  • 页眉/页脚

如果绝对需要的话,我对封装外部(非 Perl)开源工具持略微开放的态度。但对主要的 Java 服务器方法并不真正感兴趣。对于赏金,我想要一个纯粹的 Perl 方法,因为我想在一个只能添加模块的服务器上运行它。如果您有一个运行良好的公开示例,请指出它。

【问题讨论】:

  • 男孩,这是一个很好的问题。我有同样的要求,我在 CPAN 中尝试了所有我能找到的东西。最后放弃了,学了足够多的 Python 来使用 ReportLab。很想把它带回 Perl。
  • 可以通过Inline::Python使用ReportLab吗?
  • 现在似乎没有维护 Inline 模块,但是 Inline::Python 确实可以工作,尽管 Inline::Ruby 没有通过最基本的测试——它是为 Perl 5.5 和我正在使用最近的 5。但是谢谢,如果纯 Perl 失败,ReportLab 看起来是个好主意...
  • @sventech,内联模块是非常独立的,即使 Inline::Ruby 失败了,这对 Inline::Python 并没有太多说明。完成繁重工作的基本框架是 Inline 模块,它最后一次更新是在 2011 年 2 月。实际上 Inline::Python 显示在 2011 年 7 月更新。我认为没有必要担心。
  • @JoelBerger 是的,应该没问题。从我最初看 CPAN 时,我认为它们是由同一个人开发的,并且没有更新。谷歌搜索结果似乎是旧版本。

标签: perl pdf charts reporting


【解决方案1】:

使用 Perl,生成 LaTeX,也许使用 Template::Toolkit,然后调用编译器,TeXLive 或 MikTeX 或您的操作系统所需的任何发行版。有一个名为 Template::LaTeX 的扩展,尽管您可能不需要它,它管理构建过程。

LaTeX 支持所有你需要的东西。表格有点有趣,但有一些现代表格包可以简化事情(我认为它称为ltxtable)。对于图表(您是指图表),有一种名为TikZ 的子语言非常强大。

这确实是一个非常简单的工作流程,特别是如果您希望每次结果都相似(即可以使用模板)。事实上,这与从模板创建 HTML 并将其提供给浏览器没有什么不同。

这样做的另一个好处是,如果您需要用另一种语言构建报告,模板(和准备好的源代码)将是可移植的。

【讨论】:

  • 谢谢,乔尔。我一直在考虑这个问题,因为我对 LaTeX 很满意,但它的开销很大——我需要生成很多报告。
  • 如果你已经习惯了 LaTeX,那么我认为它是 def。要走的路。每当我推荐这个工作流程时,我担心 LaTeX 会成为障碍。
  • 来自类似问题的旧答案:stackoverflow.com/questions/6017157/… 当然我会建议模板化我在那里所做的事情,但这是可能的
  • 我认为 LaTeX 对于服务器环境来说计算量太大,我无法真正将它放在我想运行我的代码的机器上。如果没有其他工作,我可能不得不乞求他们安装它或其他东西。不过,谢谢。
【解决方案2】:

如果 LaTeX 太大,也许可以使用Inline::Python 来包装 ReportLab,每个人似乎都非常喜欢(我没用过,对 Python 也不是很精通)。

编辑 3: 这是编辑 2,除了拆分为模块化样式,如果人们喜欢它(并且如果它是一种健壮的),也许我可以发布到 CPAN。现在将.pm 文件放在Inline/Python/ReportLab.pm 之类的文件结构中,位于@INC 的某个位置(脚本自己的基本目录通常在@INC 中)。

# Inline/Python/ReportLab.pm
package Inline::Python::ReportLab;

use strict;
use warnings;

use Carp;

use Inline::Python qw/py_eval/;
our @ISA = 'Inline::Python::Object';

sub import {
  py_eval('from reportlab.pdfgen.canvas import Canvas');
}

sub new {
  my $class = shift;
  my $filename = shift || croak "Must specify file name to contructor";
  return bless(Inline::Python::Object->new('__main__', 'Canvas', $filename), $class);
}

1;

那么脚本可能是这样的:

#!/usr/bin/env perl

use strict;
use warnings;

use Inline::Python::ReportLab;

my $c = Inline::Python::ReportLab->new('hello.pdf');
$c->drawString(100,100,"Hello World");
$c->showPage();
$c->save();

编辑 2: 虽然编辑 1 仍然令人感兴趣,但似乎(告诉我我是否不正确!)我已经想出了如何创建“画布”的实例并直接公开其方法:

#!/usr/bin/env perl

use strict;
use warnings;

use Inline::Python qw/py_eval/;

py_eval('from reportlab.pdfgen.canvas import Canvas');

my $c = Inline::Python::Object->new('__main__', 'Canvas', 'hello.pdf');
$c->drawString(100,100,"Hello World");
$c->showPage();
$c->save();

编辑 2/3:这部分作为更手动界面的示例。我认为 Edits 2/3 提供了一个更好的界面,它将繁重的工作留给了原始 Python 类,而无需(太多)包装。

编辑 1:我现在通过手动修改方法公开了一些功能。这意味着对于每个想要使用的方法,都必须添加一个包装器方法。虽然这已经是一个可行的解决方案,但我想知道是否没有更简单的方法来公开整个 python 'canvas' 类,但现在这就是我所在的位置:

#!/usr/bin/env perl

use strict;
use warnings;

use Inline Python => <<END_PYTHON;
from reportlab.pdfgen import canvas

class Canvas:
  def __init__(self,filename):
    self.canvas = canvas.Canvas(filename)
  def drawString(self,x,y,text):
    self.canvas.drawString(x,y,text)
  def save(self):
    self.canvas.showPage()
    self.canvas.save()

END_PYTHON

my $c = Canvas->new('hello.pdf');
$c->drawString(100,100,"Hello World");
$c->save();

【讨论】:

  • 谢谢,乔尔。这当然是有希望的。我仍然希望有一个纯粹的 Perl 解决方案,但你的想法似乎运作良好。
  • 感谢乔尔,感谢您的辛勤工作和独创性。我相信把这样的东西放在 CPAN 上可能会很有帮助,如果你只是添加需要访问的主要对象。但对我来说,你的代码很可能是一个很好的解决方案。我将更仔细地研究它是如何实现我的目的的。
  • @sventech,还有哪些对象需要构造函数?我已经开始把 CPAN 模块放在一起了。
  • platypus,lib,graphics,rl_config -- 不确定如何处理通过导入设置的页面大小、单位和样式... eecho.info/Echo/python/getting-started-with-reportlab-tutorial protocolostomy.com/2008/10/22/…
  • 假设您是达拉斯唯一的 sventech,我已将您添加为新 GitHub project 的合作者。走开,也许我们可以一起完成这项工作。
【解决方案3】:

经过深思熟虑和实验,我最终编写了很多代码来包装 PDF::API2。不幸的是,这是一家公司的内部项目,因此不会开源,但坦率地说,我建议使用不同的语言(Python / Ruby),也许使用 JSON 或其他方式传递数据。我的最终结果是高效的,但它需要大量的编码。 CPAN 上正在重构 PDF::API2,但它似乎停滞不前。

【讨论】:

  • 很高兴听到您的结果。如果你看过你会发现我没有把我的想法更进一步,因为我写它太难管理了。也就是说,我已经做了一些调整 Mojo::Template 来生成 LaTeX 的工作。我个人认为 LaTeX 是任何语言生成 PDF 的真正答案。干杯和祝贺。
  • 此外,有时公司会向 Perl 社区捐赠代码。如果您可以问一下,我相信许多其他人会受益!只是想我会这么说:-)
猜你喜欢
  • 1970-01-01
  • 2016-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-30
  • 2015-03-27
  • 1970-01-01
  • 2011-02-22
  • 2013-07-23
相关资源
最近更新 更多