printform-xls : Класс-обертка для заполнения форм в формате XLS (PHPExcel)

Назначение класса CPrintFormXls - генерация XLS-файлов с пользовательскими данными на основе подготовленных шаблонов. На листы выходного файла формата MS Excel (и на весь файл) может поставлена парольная защита.
Собственно для чтения исходного XLS файла шаблона, занесения в него пользовательксих данных и сохранения результата используется известный набор классов PHPExcel (дистрибутив PHPExcel необходимо самостоятельно скачать с сайта разработчиков (codeplex.com) и установить на свой WEB-сервер).


В текущей версии класс имеет следующий функционал:

Пример : Создаем XLS файл из шаблона и своих данных



Напомним, что PHP-модули PHPExcel необходимо разместить на своем сервере, и папку с расположенным файлом PHPExcel.php добавить в свой php.ini-параметр "include_path" (при работе на площадке провайдера, когда доступа к PHP.ini нет, как обычно спасет функция set_include_path() ).
require_once('PHPExcel.php');
require_once('PHPExcel/IOFactory.php');
require_once('PHPExcel/Reader/Excel5.php'); # или другой файл, если нужен вывод в Excel 2007 и т.п.
Предположим, у нас подготовлен файл шаблона template-test.xls, а также есть следующий файл конфигурации cfg-test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<printdef>
  <version>1.0</version>
  <description>sample format for testing</description>
  <dateformat>dd/mm/yyyy</dateformat>
  <stringcharset>WINDOWS-1251</stringcharset>
  <templatefile>config-test.xls</templatefile>
  <sheets>
   <sheet offset="0">
    <field name="last_name" col="3" row="5" type="string" convert="AddBraces" />
    <field name="first_name" col="3" row="7" type="string"/>
    <field name="birthdate" col="3" row="9" type="date"/>
    <field name="address" col="3" row="11" type="string"/>
    <field name="resident" col="3" row="13" type="bool"/>
    <field name="resident" col="5" row="15" type="bool-invert"/>
   </sheet>
  </sheets>
</printdef>
Создание заполненного XLS файла происходит в следующем скрипте:
require_once('PHPExcel.php'); // We use PHPExcel classes !
require_once('PHPExcel/IOFactory.php');
require_once('PHPExcel/Reader/Excel5.php');
require_once('printform-xls.php');

$excel = new CPrintFormXls(array(
   'configfile' => 'cfg-test.xml'
  ,'outname' => 'myfile-test.xls'
  ,'resident' => 1
));

# наши данные :
$data = array(
   'last_name'=>'Smirnoff'
  ,'first_name' => 'Ivan'
  ,'birthdate'  => '1970-04-18'
  ,'address'     =>'Russia, Moscow, Usacheva street, 33-999'
  ,'resident'   => 1
);

$excel->AddData($data); // XLS заполнится этими данными данными
$ok = $excel->Render(); // генерирует и выводит файл

if(!$ok) echo $excel->GetErrorMessage(); // что-то пошло не так ? Вывести последнюю ошибку
exit;

// наша ф-ция для данных last_name
function AddBraces($param) {
    return "[ $param ]";
}

CPrintFormXls : список методов

CPrintFormXls($param='' [, $data [, $outname [, $tofile]]]) - конструктор класса.
$param - или строка (передает путь/имя конфигурационного XML файла), или (предпочтительный способ) -
ассоциативный массив со всеми нужными параметрами
КлючНазначение
template Путь/Имя файла XLS шаблона.
outname Имя создаваемого файла. Если передан ненулевой параметр "tofile", файл будет сохранен под этим именем.
tofile По умолчанию содержимое созданного файла посылается в браузер клиента (пользователь увидит запрос на открытие или сохранение файла). Если передать ненулевое значение в параметре 'tofile', файл будет сохранен на диске, без вывода в "поток" к клиенту.
configfile Полный путь/имя конфигурационного XML файла, хранящего все настройки вывода (имена полей данных и их позиции на листах XLS, и другие параметры (см. описание файла). Если параметр не задан при вызове кноструктора, вам придется позднее вызвать метод LoadConfig().
outfmt Формат (и тип) выходного файла. Допустим любой формат, поддерживаемый классами PHPExcel. Если вы задаете люьой формат, отличный от 'Excel5', соответственно вы должны подключить соответствующие модули из комплекта PHPExcel (Include, require, incude_once и т.д.)
В частности допустим формат 'pdf'. Т.к. PHPExcel уже содержит классы CPDF для записи в PDF файл, он может быть выбран как выходной формат. Однако эта опция тестировалась только на простых XLS шаблонах, при генерации PDF из "сложных" файлов XLS замечены зависания.
protectsheets Включает защиту всех листов выходного XLS файла. Учтите, что исходный XLS файл не должен быть защищен ! Кроме того, режим защиты листов можно отдельно включать/выключать методом ProtectSheets().
password Общий пароль на все листы, используемый при включении защиты.
protectbook Включает режим защиты книги ('1' или true для включения режима) Также есть отдельный метод ProtectBook() для переключения режима.
bookpassword Пароль для защиты книги.
data Ассоциативный массив данных для заполнения шаблона. Если не передан в конструкторе, позднее можно вызвать AddData().


LoadConfig($cfgname) загружает параметры из XML-файла конфигурации. Файл подготавливается в следующем формате:

Файл конфигурации (XML)
<?xml version="1.0" encoding="UTF-8"?>
<printdef>
  <version>1.0</version> /* версия формата */
  <description>sample format for testing</description> /* не сипользуется, просто для информации */
  <dateformat>dd/mm/yyyy</dateformat>         /* формат вывода даты в конечном XLS файле, по умолчанию - 'dd/mm/yyyy' */
  <stringcharset>WINDOWS-1251</stringcharset>   /* кодировка строчных исходных данных */
  <templatefile>config-test.xls</templatefile>  /* путь/имя файла шаблона XLS */
  <protectsheets>1</protectsheets> /* включить защиту листов */
  <protectpassword>mypassword</protectpassword> /* пароль для листов */
  <sheets> /* Задание заполняемых полей данных */
   <sheet offset="0"> /* offset - 0-based номер листа в файле шаблона */
    /* Атрибуты: "name" - имя поля; "col" номер колонки (0-based); "row" - номер строки (1-based) */
    <field name="last_name" col="3" row="5" type="string" convert="AddBraces" />
    <field name="birthday" col="3" row="11" type="date"/>
    /* etc... */
   </sheet>
  </sheets>
</printdef>

Вместо имени XML-файла можно передавать собственно XML-блок данных (well formed XML, соответствующий описанному формату).
Каждый лист книги Excel должен иметь атрибут "offset", задающий 0-based номер листа в исходном XLS файле шаблона.

Атрибуты тега "field" :
name - имя поля. В переданном массиве данных - ключ элемента.
col - номер колонки, 0-based (начинается с нуля).
row - номер строки, 1-based.
type - необязательный - тип поля (по умолчанию считается string).
type: поддерживаемые типы - "string", "date", "bool" и "bool-invert". Если "date" значения оказываются строкой, в классе делается авто-конвертация из возможных форматов 'yyyy-mm-dd', 'yy/dd/yyyy' и 'dd.mm.yyyy' во "внутренний" целочисленный вид XLS-даты (номер дня начиная с 01.01.1900). Если передано числовое значение, оно не конвертируется - считается, что программист самостоятельно привел дату к числовому XLS-формату.

"bool" тип : любое не-нулевое значение превращается в символ 'X' в соответствующей XLS-ячейке, в противном случае выводится пробел.
"bool-invert" делает обратное: единичное (не-нулевое) значение станет пробелом, и ноль - символом 'X' - благодаря этому типа можно с помощью единственного элемента в данных управлять двумя выходными ячейками. Например, это может пригодиться для формирования полей типа "резидент РФ" - ДА [X] - НЕТ [ ].

convert - необязательный атрибут, задающий имя функции конвертора, вызываемой над переданным значением и возвращающей "конвертированное" значение. Функция будет вызвана перед авто-конвертацией char-set-а и помещением данных в XLS .

AddData($param, $pval=null) - метод добавляет блок данных для вывода в XLS файл. $param может быть строкой, содержащей имя поля ( в этом случае во втором параметре передается значение). Или $param может быть ассоциативным массивом в формате имя_поля => значение.
AddData() может быть вызван несколько раз (до вызова финального Render() ), данные в итоге накапливаются.

ProtectSheets($protect, $password='') включает ($protect=1 или true) или выключает (0|false) защиту листов, с передачей пароля.

ProtectBook($protect, $password=null) включает ($protect=1 или true) или выключает (0|false) защиту "книги" XLS.
ВНИМАНИЕ: Замечено, что защита книги может не работать (используемая версия PHPExcel - 1.7.3c), поэтому перед применением нуждается в дополнительном тестировании.

Render() выполняет финальную генерацию выходного XLS файла с выводом в браузер либо сохранением на диск.

GetErrorMessage() возвращает строку с последней произошедшей ошибкой, если она возникла.

GetXlsObject() возвращает внутренний объект класса PHPExcel, чтобы программист мог напрямую работать над ним с помощью вызовов методов из классов PHPExcel, например, записать в XLS файл дополнительные значения ячеек, сменить параметры файла, листа и т.д.

Примеры использования

Пример 1. Защищаем листы паролем
$excel = new CPrintFormXls(array(
   'configfile' => 'cfg-test.xml'
  ,'outname' => 'myfile-test.xls'
));

$data = array(
   'last_name'=>'Smirnoff'
  ,'first_name' => 'Ivan'
# ...
);
$excel->AddData($data);

$excel =>ProtectSheets(true,'mypassword'); // включаем защиту листов паролем

$ok = $excel->Render();
Пример 2. Выводим в PDF-файл
$excel = new CPrintFormXls(array(
   'configfile' => 'cfg-test.xml'
  ,'outname' => 'myfile-test.pdf' // Set correct output file extension
  ,'outfmt' => 'pdf' // set output format to PDF
));

$data = array(
   'last_name'=>'Smirnoff'
  ,'first_name' => 'Ivan'
# ...
);
$excel->AddData($data);
$ok = $excel->Render();
Примечание: ввиду ограничений PHP-классов CPDF вид готового PDF файла может существенно отличаться от "двойника" XLS.

Пример 3. Работа с объектом PHPExcel напрямую.
$excel = new CPrintFormXls(array(
   'configfile' => 'cfg-test.xml'
  ,'outname' => 'myfile-test.xls'
));
# ...

$xlsobj = $excel->GetXlsObject();
$xlsobj->getSheet(0)->setCellValueByColumnAndRow(3, 17, 'This text inserted outside class !');

$excel->AddData($data);
$ok = $excel->Render();


Распространяется по лицензии BSD

Ссылки

История

1.01.005 (13.07.2010)
1.00.004 (07.07.2010)


Copyright © 2010 Alexander Selifonov, www.selifan.ru