如何使用mod_perl和CGI :: Application提供临时文件下载?

时间:2009-08-28 20:20:24

标签: perl apache download mod-perl cgi-application

我的网络应用程序使用CGI :: Application在Apache mod_perl上运行。我想提供生成文件的下载。在过去(在我们使用mod_perl和CGI :: App之前)我只是在生成csv文件时将其伪装成STDOUT。现在我正在进行更多改进 - 使用Spreadsheet :: WriteExcel创建一个Excel电子表格 - 我似乎无法将其从文件句柄中打印出来。

sub export_list {
  my $self = shift;

  binmode(STDOUT);
  my $str;
  open my $fh, '>', \$str;
  my $workbook = Spreadsheet::WriteExcel->new($fh);
  my $worksheet = $workbook->add_worksheet();

  $worksheet->write_col(0,0, ['some','data','here']);
  warn $str;
  return $str;
}

输出只是一个空白响应,警告也是空白。

我用来将电子表格写入文件句柄的方法非常直接来自documentation,所以我认为问题是由于我的一些CGI :: App noobery。文档的文件句柄和mod_perl的建议方法也证明是徒劳的。

我想我应该提一下我在Windows上运行,而我目前的解决方法是创建一个文件并为用户提供一个链接。但是,这会带来更多问题,包括清除目录以及何时执行此操作,以及访问生成文件的身份验证。

连连呢?尖刻的批评?

3 个答案:

答案 0 :(得分:4)

你不应该混淆STDOUT; CGI-App应该在幕后为您正确处理。在尝试发送数据之前,您可能还需要关闭文件句柄。

但是,您似乎没有为Excel数据设置正确的内容类型。对于text / html以外的任何内容,您需要手动设置它。尝试这样的事情:

sub export_list {
    my $self = shift;

    my $str;
    open my $fh, '>', \$str or die "Can't open to var: $!";
    my $workbook = Spreadsheet::WriteExcel->new($fh);
    my $worksheet = $workbook->add_worksheet();

    $worksheet->write_col(0,0, ['some','data','here']);

    $workbook->close;
    close $fh;

    warn $str;

    $self->header_add( -type => 'application/vnd.ms-excel' );
    return $str;

}

您可能也对CGI::Application::Plugin::Stream

感兴趣

答案 1 :(得分:4)

不是在内存中创建整个电子表格,而是应该将其写入文件,然后在完成时将其流式传输(在这里使用CGI::Application::Plugin::Stream帮助,但是之后你仍然需要清理它,但是实际上每个Web应用程序都应该有一个定期清理的临时目录)或者在创建它时打印它(这意味着制作FH STDIN而不是mod_perl下可能更棘手或者可能不是。)

然后记得在完成后关闭工作簿。

答案 2 :(得分:3)

您想要关闭工作簿。同时关闭文件句柄:

warn "length 1=".length($str);
$workbook->close();
close($fh) or die "error on close: $!";
warn "length 2=".length($str);

length 1=0 at wx.pl line 16.
length 2=5632 at wx.pl line 19.