Perl的所有PDF库看起来都有些野蛮 - 卡在1980年代。您必须指定PostScript点才能进行布局。 Java有JasperReports,Ruby有Prawn,Python有ReportLab。是否有一个非灭绝的库/模块可以让我在不到一周的编码时制作漂亮的PDF? (我对PDF :: API2,PDF :: Table等有点沮丧)我不想生成HTML并将其转换。 Perl非常适合报告,但主报告文件格式无法以可用的方式提供。人们使用哪些图书馆?
我需要:
如果绝对需要,我对包装外部(非Perl)开源工具略显开放。但对主要的Java服务器方法并不感兴趣。对于赏金,我想要一个纯粹的Perl方法,因为我想在一个我无法添加模块的服务器上运行它。如果你有一个运作良好的公开示例,请指出我。
答案 0 :(得分:10)
使用Perl生成LaTeX,也许使用Template::Toolkit,然后调用编译器,TeXLive或MikTeX或您的操作系统所需的任何分发。有一个名为Template::LaTeX的扩展名,但您可能不需要它来管理构建过程。
LaTeX支持您需要的所有内容。表格有点有趣但是有一些现代的表格包可以简化事情(我认为它叫做ltxtable
)。对于图表(你的意思是图表),有一种名为TikZ
的子语言非常强大。
这确实是一个非常简单的工作流程,特别是如果您希望每次结果都相似(即可以使用模板)。事实上,它与从模板创建HTML并将其提供给浏览器的方式完全不同。
这样做的另一个好处是,如果您需要使用其他语言构建报告,模板(和准备好的源代码)将是可移植的。
答案 1 :(得分:5)
如果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仍然有用,但似乎(告诉我,如果我不正确!)我已经想出如何创建一个'Canvas'实例并直接公开它的方法:
#!/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:此部分留作更多手动界面的示例。我认为编辑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();
答案 2 :(得分:0)
经过深思熟虑和实验,我最终编写了大量代码来包装PDF :: API2。不幸的是,这是一个公司内部的项目,所以不会发布开源,但坦率地说,我建议使用不同的语言(Python / Ruby),也许通过JSON或其他东西传递数据。我的最终结果是有效的,但它需要大量的编码。在CPAN上正在进行PDF :: API2的重构,但它似乎停滞不前。