在Perl中制作PDF报告?

sve*_*hie 13 pdf perl charts reporting

Perl的所有PDF库看起来都有些野蛮 - 卡在1980年代.您必须指定PostScript点才能进行布局.Java有JasperReports,Ruby有Prawn,Python有ReportLab.是否有一个非灭绝的库/模块可以让我在不到一周的编码时制作漂亮的PDF?(我对PDF :: API2,PDF :: Table等有点沮丧)我不想生成HTML并将其转换.Perl非常适合报告,但主报告文件格式无法以可用的方式提供.人们使用哪些图书馆?

我需要:

  • 图表(图片)
  • 颜色
  • 格式化(理想情况下是自动的,不是逐个像素)
  • 页眉/页脚

如果绝对需要,我稍微愿意包装外部(非Perl)开源工具.但对主要的Java服务器方法并不感兴趣.对于赏金,我想要一个纯粹的Perl方法,因为我想在一个我无法添加模块的服务器上运行它.如果你有一个运作良好的公开示例,请指出我.

Joe*_*ger 10

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

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

这真的是一个非常简单的工作流程,特别是如果您希望每次结果都相似(即可以使用模板).实际上,它与从模板创建HTML并将其提供给浏览器的方式完全不同.

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


Joe*_*ger 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;
Run Code Online (Sandbox Code Playgroud)

然后脚本可能是这样的:

#!/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();
Run Code Online (Sandbox Code Playgroud)

编辑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();
Run Code Online (Sandbox Code Playgroud)

编辑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();
Run Code Online (Sandbox Code Playgroud)