пятница, 6 июля 2007 г.

Генерация Excel документов на perl

Описание задачи. Имеется программная телефонная станция на базе asterisk. Журнал звонков этой телефонной станции ведется в базе данных mysql. Названия полей таблицы соответствуют названиям полей CDR (Call Detail Record). Возникла необходимость в доступе к этому журналу для менеджеров. Менеджеры, братья наши меньшие, абсолютно не очарованы таблицами баз данных, SQL для них чужд. Зато документы в формате Excel милы их сердцам. Поэтому напишем perl скрипт для генерации Excel отчета из базы данных. Для создания excel файлов воспользуемся perl модулем Excel::Template, позволяющем, как видно из названия, создавать .xls файлы на основе xml шаблона. Вы ведь не хотите менять программу каждый раз, когда нужно будет увеличить размер шрифта или поменять местами колонки в отчете? Сначала приведем содержимое файла шаблона report.xml:
<workbook>
 <worksheet name="report">
   <format align="center" valign="vcenter" bold="bold" border="2">
     <row>
       <cell width="15">Откуда</cell>
       <cell width="15">Куда</cell>
       <cell width="15">Начало</cell>
       <cell width="15">Длительность</cell>
     </row>
   </format>

   <format border="1">
     <loop name="report_data">
       <row>
         <cell><var name="src" /></cell>
         <cell><var name="dst" /></cell>
         <cell><var name="start" /></cell>
         <cell><var name="billsec" /></cell>
       </row>
     </loop>
   </format>
 </worksheet>
</workbook>
В данном шаблоне описывается excel документ, содержащий один лист с данными. На этом листе первая строка содержит заголовки 4-х колонок отчета: «Откуда» — номер вызывающего абонента, «Куда» — номер вызываемого абонента, «Начало» — время начала звонка, «Длительность» — длительность звонка. Остальные строки заполняются данными отчета по количеству записей в нём. Подробное описание всех тегов шаблона присутствует в документации perl модуля Excel::Template. Теперь сам скрипт report.pl:
#!/usr/bin/perl -w -t
use strict;

use DateTime;
use DBI;
use Excel::Template;

# подключение к базе данных
my $dsn    = 'dbi:mysql:database=...;host=...';
my $dbuser = '...';
my $dbpass = '...';
my $dbh    = DBI->connect( $dsn, $dbuser, $dbpass, { RaiseError => 1 } );

# задаем период формирования отчета
my $period_begin = DateTime->new( year => 2007, month => 6, day => 1 );
my $period_end   = DateTime->new( year => 2007, month => 7, day => 1 );

# подготовка и исполнение sql запроса на выборку данных
my $sth = $dbh->prepare( q/
    SELECT `src`, `dst`, `start`, `answer`, `end`, `duration`
    FROM   `cdr`
    WHERE  `start` BETWEEN ? AND ?
/ );
$sth->execute( $period_begin, $period_end );

# извлечение данных из базы и подготовка их для шаблона
my @report_data;
while ( my $report_row = $sth->fetchrow_hashref ) {
    push @report_data, $report_row;
}

# формирование excel отчета по шаблону и данным
my $template_file = 'report.xml';
my $template = Excel::Template->new( filename => $template_file );
$template->param( report_data => \@report_data );
print $template->output;

Скрипт report.pl выдает excel отчет на стандартный поток вывода, поэтому вызывать его нужно так: « ./report.pl > report.xls ». Как видите — ничего сложного. Подобным же образом можно генерировать excel документы и для web.

P.S. Данный скрипт работоспособный, хотя и был немного упрощен, чтобы донести основную идею использования шаблонов. На самом деле условия отбора записей сложнее, период формирования отчета задается в аргументах скрипта report.pl; даты преобразуются во внутренний формат excel, а не вставлются текстовой строкой; решены вопросы c кодировками. Но опытному perl программисту не составит труда адаптировать этот скрипт под свои нужды.

4 комментария:

Анонимный комментирует...
Этот комментарий был удален администратором блога.
Анонимный комментирует...
Этот комментарий был удален администратором блога.
Анонимный комментирует...

а чо ты каменты удаляешь??
не будут тебя читать,нужен больно ты такой.

xeim комментирует...

Удаляются только комментарии, содержащие рекламные ссылки.