我的网络应用程序使用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上运行,而我目前的解决方法是创建一个文件并为用户提供一个链接。但是,这会带来更多问题,包括清除目录以及何时执行此操作,以及访问生成文件的身份验证。
连连呢?尖刻的批评?
答案 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;
}
感兴趣答案 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.