Perl: как отдать Excel-файл из CGI-сценария

Date March 21st, 2014 Author Vitaly Agapov

Our purpose for living is to find that perfection and show it forth. // Смысл жизни в том, чтобы достигнуть совершенства и рассказать об этом другим.

Ричард Бах «Чайка по имени Джонатан Ливингстон»

perl-camel-xls

Новая микрозаметка из мира Perl, растерявшего в последнее время былую популярность, но не мой интерес и нежные чувства. На этот раз о том, как сгенерировать XLS-файл по запросу в CGI-сценарий о отдать его пользователю в виде аттачмента.

Сам процесс создания файла ложится на плечи модуля Spreadsheet::WriteExcel, о котором всю подробную документацию можно прочитать на CPAN.

Вот, собственно, сам сниппет с комментариями.





01.#!/usr/bin/perl
02.use Spreadsheet::WriteExcel;
03.use Encode;
04.use CGI;
05. 
06.my $cgi = new CGI;
07. 
08.# Добавляем заголовки Content-Type, Content-Disposition и Expires
09.print $cgi->header(
10.        -type    => 'application/xls',
11.        -attachment => 'alert.xls',
12.        -expires => '-1d'
13.);
14. 
15.# Будем писать в бинарный поток
16.binmode(STDOUT);
17.my $workbook = Spreadsheet::WriteExcel->new(\*STDOUT);
18. 
19.# Создаём новую страницу
20.my $worksheet = $workbook->add_worksheet('page1');
21. 
22.# Пишем значения, в общем симулируем полезные действия
23. 
24.my ($row, $col);
25.$worksheet->write($row, $col++, "Hello");
26.$worksheet->write($row, $col, "World");
27.$row++;
28.$col=0;
29.$worksheet->write($row, $col++, decode_utf8("Привет"));
30.$worksheet->write($row, $col, decode_utf8("Мир"));
31. 
32.# Закрываем файл
33.$workbook->close();

В общем-то всё. Для полноты картины, правда, ещё можно посмотреть, как отдать уже готовый файл. Или рассмотреть ситуацию, когда необходимо, чтобы файл не только отдавался пользователю, но и сохранялся на сервере для будущего использования. 

Во-первых, для этого понадобится заменить в конструкторе new() хэндлер на имя файла:

my $workbook = Spreadsheet::WriteExcel->new($filename);

Во-вторых, после $workbook->close() добавить вывод этого файла:

01.use constant BUFFER_SIZE => 4096;
02.open( FILE, '<', $filename ) or die("open failed: $!");
03.binmode(FILE);
04.binmode(STDOUT);
05.my $buf;
06.while ( read(FILE, $buf, BUFFER_SIZE) ) {
07.    print $buf;
08.}
09.close FILE;

Tags:
Category: Perl | No comments »

Comments

Leave a comment

 Comment Form