Отправка данных из PHP в Office
У публикации есть спонсор (как стать спонсором):
Питомник йоркширских терьеров Люкс Миа продает щенков мини и стандарт.
Приветствую уважаемого читателя! В данной публикации мы снова коснемся темы программирования на PHP средствами фреймворка Kohana — научимся сохранять результат работы скрипта PHP в документ Open Office.
Я часто сталкиваюсь с задачей вывода результатов работы сайта в Word. Ведь отображения страницы в браузере не всегда достаточно: встречаются требования заполнить ту или иную форму, подготовленную в Office, данными, сформированными посредством PHP. Думаю, сегодня прекрасный день, чтобы решить эту задачу.
Для начала давайте скажем решительное НЕТ сложностям работы с форматом *.doc от MS Office. Результаты работы PHP-скрипта мы будем выводить в *.odt-файл (формат офисного текстового документа в пакете Open Office).
Заодно, очистим свои компьютеры от ворованного софта. Этот пост я набираю именно в Open Office и замечательно себя при этом чувствую. Что может быть приятнее, чем на совершенно законных основаниях скачать свежую версию Open Office с официального сайта. А нервно поскуливающих бабулек из бухгалтерии можно успокоить демонстрацией процесса сохранения подготовленного нами документа *.odt в так полюбившийся им *.doc.
Оказывается, существует специальный модуль odtPHP, предназначенный для решения поставленной задачи. Разберем принцип работы с данным модулем.
1. Подготавливаем PHP скрипт
<?php
require_once('../library/odf.php');
$odf = new odf("tutoriel1.odt");
$odf->setVars('titre', 'PHP');
$message = "PHP est un langage de scripts libre ...";
$odf->setVars('message', $message);
$odf->exportAsAttachedFile();
?>
2-я строка — подключение модуля (в скобках указывается местоположение скачанного модуля odtPHP).
3-я строка — указываем путь к шаблону документа Open Office.
4-я строка — устанавливается значение для переменной titre (titre указывается в шаблонном документе OpenOffice). Теперь вместо кодового {titre} в шаблоне tutoriel1.odt будет выводится буквосочетание «PHP».
2. Подготавливается шаблон
Создаем в Open Office новый документ и в нужных местах ставим метки {titre}и {message}, которые будут заменены на «PHP» и «PHP est un langage de scripts libre … ».
А вот как выглядит шаблонный документ:
{titre}
{message}
Думаю, дальше пояснять нет смысла все и так понятно из раздела Tutorials.
Мы будем копать глубже и прикрутим к фреймворку Kohana 3.2 модуль для работы с odt на основе odtPHP. Заодно я проиллюстрирую процесс вывода результатов работы скрипта PHP в Office-документ.
Если вы не знакомы с фреймворком Kohana, то у меня есть видеокурс, посвященный его изучению.
Реальная задача по выводу результатов работы PHP скрипта в Office
Постановка задачи. Есть сайт, на котором выводится таблица с номерами сертификатов и фамилиями лиц, прошедших обучение. Необходимо выбрать чекбоксом нужные фамилии и, нажав кнопку Экспорт, отправить данные по выбранным слушателям курсов в офисный документ утвержденной формы.
Видеоурок
Скачать видеоурок (21.2 МБ, *.wmv).
Публикую ссылку на загрузку заточки модуля odtPHP под Kohana 3.2.
Форма Office-документа:
Теперь пройдем все шаги от загрузки нужного модуля для Kohana 3.2 до открытия готового документа Open Office.
Итак, я считаю, что вы знакомы с видеокурсом по Kohana 3. Поэтому, без лишних скромностей, создайте в папке application каталог templates. Будем хранить там наши odt-шаблоны.
В свежесозданный каталог templates сохраним odt-докумет следующего вида:
Как видно из скриншота, в местах вывода информации по обучаемому (ФИО, номер сертификата и т. д.) установлены специальные символы ({number}, {surname}, {name}…), которые будут заменены на значения, полученные PHP-скриптом.
Поскольку строк в таблице может быть несколько — необходимо выводить информацию по обучаемым в цикле (каждая итерация выводит данные одного курсанта). Именно это и означает связка
[!-- BEGIN row.certificates --] ... [!-- END row.certificates --]
Все, что находится между данными операторами будет повторятся в цикле для блока данных row.certificates, который мы подготовим в контроллере.
Следующий шаг — скачать и подключить специальный модуль для Kohana 3.2, созданный на основе odtPHP.
Для подключения модуля нужно скопировать папку odtphp в каталог modules и указать инструкцию подключения в файле application/bootstrap.php
Далее, в методе, запускающем формирование odt-файла нужно указать следующий код:
protected function export_certificates()
{
$odf = new Odtphp(APPPATH.'templates/register.odt');
$odf->setVars('privet', 'Иван', $encode = TRUE, $charset='UTF-8');
$seg = $odf->setSegment('certificates');
if(isset($_POST['cb']))
{
foreach($_POST['cb'] as $key => $null)
{
$cert = ORM::factory('certificate', $key);
$seg->setVars('number', $cert->number, $encode = TRUE, $charset='UTF-8');
$seg->setVars('surname', $cert->surname, $encode = TRUE, $charset='UTF-8');
$seg->setVars('name', $cert->name, $encode = TRUE, $charset='UTF-8');
$seg->setVars('lastname_ru', $cert->lastname_ru, $encode = TRUE, $charset='UTF-8');
$seg->setVars('name_ru', $cert->name_ru, $encode = TRUE, $charset='UTF-8');
$seg->setVars('patronymic_ru', $cert->patronymic_ru, $encode = TRUE, $charset='UTF-8');
$seg->setVars('birthdate', $cert->birthdate, $encode = TRUE, $charset='UTF-8');
$seg->setVars('certdate', $cert->certdate, $encode = TRUE, $charset='UTF-8');
$seg->merge();
}
}
$odf->mergeSegment($seg);
$odf->exportAsAttachedFile();
exit;
}
Если что-то не понятно — смотрите видеоурок.
Еще раз публикую ссылку на загрузку заточки модуля odtPHP под Kohana 3.2.
С уважением, Андрей Морковин.
Похожие материалы:
Отзывов: 24 на «Отправка данных из PHP в Office»















, 27.01.2012 в 10:56
Андрей, большое спасибо за видео. Очень полезная штука!
кстати, по поводу word/excel против OpenOffice по набору стандартных функций они, конечно, почти не отличаются. но если копнуть глубже, то бесплатный продукт все-таки проигрывает (рисование (word), условное форматирование (excel), выделение цветом(excel), работа с данными(excel). самое обидное, что многие люди все-равно не пользуются всеми благами платных продуктов и используют их так же, как могли бы OpenOffice.
а вообще, полностью Вас поддерживаю в попытках перевести сознание людей на легальное использование программного обеспечение! с Вашей подачи, так сказать, я удалил Dreamweaver )))
, 27.01.2012 в 11:18
Я рад, что видео оказалось полезным.
Конечно, есть моменты, где бесплатный софт значительно слабее своих аналогов. Но на то он и бесплатный, видимо.
Отлично, что отказались от Dreamweaver.
, 01.02.2012 в 09:56
Андрей, а не могли бы вы выложить исходника view? Я просто не могу понять как odtphp, узнает, что надо именно с галочками экспортировать. И как сделать соответствующий вид.
, 02.02.2012 в 08:38
Ошибка! что делать? Все проверил, все как в уроке. Вот сама ошибка: ErrorException [ Warning ]: tempnam() [function.tempnam]: open_basedir restriction in effect. File() is not within the allowed path(s): (/home/users2/k/kondyrev/:/usr/local/zend/share/pear/:/tmp/)
, 02.02.2012 в 12:01
Андрей ответьте, пожалуйста, я уже всю голову сломал.
, 02.02.2012 в 16:55
У меня тоже выскакивает такая же ошибка, хотя проверила все 100 раз, и шаблон лежит в папке templates/ Вот сама ошибка: ErrorException [ Warning ]: tempnam() [function.tempnam]: open_basedir restriction in effect. File() is not within the allowed path(s):
, 02.02.2012 в 17:35
И у меня такая же проблема, так как её решить? Андрей подскажите… Важный проект — я в тупике, завтра сдавать…. Все делал по вашим урокам, остался только экспорт, а тут затык…..
, 02.02.2012 в 18:41
Скорее всего проблема в том, что не указан параметр PATH_TO_TMP модуля odtphp.
Скопируйте конфиг модуля (MODPATH/odtphp/config/odtphp.php) в каталог application/config, затем откройте его в редакторе и установите параметр PATH_TO_TMP. Это путь к временному каталогу. Пример:
‘PATH_TO_TMP’ => ‘/tmp’,
А если хотите быстрый и точный ответ, всегда сообщайте также файл и номер строки, где возникла ошибка.
, 02.02.2012 в 19:04
Я все сделал как вы сказали, но все равно результат тот же…
ErrorException [ Warning ]: tempnam() [function.tempnam]: open_basedir restriction in effect. File() is not within the allowed path(s): (/home/users2/k/kondyrev/:/usr/local/zend/share/pear/:/tmp/)
MODPATH/odtphp/vendor/odtphp/odf.php [ 66 ]
61 throw new OdfException(«Nothing to parse — check that the content.xml file is correctly formed»);
62 }
63
64 $this->file->close();
65
66 $tmp = tempnam($this->config['PATH_TO_TMP'], md5(uniqid()));
67 copy($filename, $tmp);
68 $this->tmpfile = $tmp;
69 $this->_moveRowSegments();
70 }
71 /**
, 02.02.2012 в 19:05
Я все сделал как вы сказали, но все равно результат тот же…
MODPATH/odtphp/vendor/odtphp/odf.php [ 66 ]
61 throw new OdfException(«Nothing to parse — check that the content.xml file is correctly formed»);
62 }
63
64 $this->file->close();
65
66 $tmp = tempnam($this->config['PATH_TO_TMP'], md5(uniqid()));
67 copy($filename, $tmp);
68 $this->tmpfile = $tmp;
69 $this->_moveRowSegments();
70 }
71 /**
, 02.02.2012 в 19:21
Покажите файл application/config/odtphp.php
, 02.02.2012 в 19:24
‘PclZipProxy’,
// ‘DELIMITER_LEFT’ => ‘{‘,
// ‘DELIMITER_RIGHT’ => ‘}’,
// ‘PATH_TO_TMP’ => ‘/tmp’,
);
, 02.02.2012 в 19:29
У меня два вопроса:
1) Хостер позволяет писать в /tmp ?
2) Внимательно посмотрите на тот параметр, который Вы изменили в конфиге.
, 02.02.2012 в 19:35
Права на templates выставлены 777
А по поводу второго вопроса не понял?..
, 02.02.2012 в 19:42
Что же тут непонятного ?
Откройте файл application/config/odtphp.php в текстовом редакторе и посмотрите на его содержимое.
Подумайте, какой будет результат выполнения этого файла. Это же php файл, так ?
, 02.02.2012 в 19:45
АААААААА, там все закомментировано!!!!! Надо разкомментировать?
, 02.02.2012 в 19:50
Разкомментировал, теперь другая ошибка…
OdfException [ 0 ]: ‘certificates’ segment not found in the document
MODPATH/odtphp/vendor/odtphp/odf.php [ 215 ]
210 return $this->segments[$segment];
211 }
212 // $reg = «#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm»;
213 $reg = «#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm»;
214 if (preg_match($reg, html_entity_decode($this->contentXml), $m) == 0) {
215 throw new OdfException(«‘$segment’ segment not found in the document»);
216 }
217 $this->segments[$segment] = new Segment($segment, $m[1], $this);
218 return $this->segments[$segment];
219 }
220 /**
, 02.02.2012 в 20:04
Алексей, научитесь читать сообщения об ошибках.
Как переводится фраза: ‘certificates’ segment not found in the document ?
, 02.02.2012 в 19:59
Разкомментировал, теперь другая ошибка…
OdfException [ 0 ]: ‘certificates’ segment not found in the document
MODPATH/odtphp/vendor/odtphp/odf.php [ 215 ]
210 return $this->segments[$segment];
211 }
212 // $reg = «#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm»;
213 $reg = «#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm»;
214 if (preg_match($reg, html_entity_decode($this->contentXml), $m) == 0) {
215 throw new OdfException(«‘$segment’ segment not found in the document»);
216 }
217 $this->segments[$segment] = new Segment($segment, $m[1], $this);
218 return $this->segments[$segment];
219 }
220 /**
, 02.02.2012 в 20:03
1. Знак // перед строкой ‘PATH_TO_TMP’ означает, что данная строка закомментирована и не участвует в конфигурировании модуля. Для начала раскомментируйте строку (просто удалите //).
2. ‘/tmp’ это путь к временной папке сервера с ОС Linux, которая очищается автоматически и не имеет никакого отношения к папке template. Запросто может быть так, что хостер запрещает туда писать. Тогда вам нужно будет указать путь к временной папке внутри своей домашней директории.
, 02.02.2012 в 20:06
Спасибо, я все сделал так, разкомментировал, проверил папку tmp на сервере, все ок. Но теперь другая ошибка…
OdfException [ 0 ]: ‘certificates’ segment not found in the document
, 02.02.2012 в 20:27
Андрей, подскажите, пожалуйста все проверил, и в odf уыть certificates и в контроллере я его указываю, просто не пойму в чем может быть проблема….
, 02.02.2012 в 19:27
Вот на всякий случай еще код:
protected function export_sertificates(){
$odf = new Odtphp(APPPATH.’templates/register.odt’);
$seg = $odf->setSegment(‘certificates’);
$export=array();
$ch = $_POST['ch'];
$seg->setVars(‘name’, ‘Василий’, $encode =TRUE, $charset = ‘UTF-8′);
foreach($ch as $c){
$edina = ORM::factory(‘zakaz’, array(‘id’=>$c));
$edins = ORM::factory(‘ediniza’, array(‘id’=>$edina->idtov));
$art = ORM::factory(‘article’, array(‘id’=>$edina->article))->name;
$naim = $edins->name;
$zvet = RM::factory(‘cvet’, array(‘id’=>$edina->cvet))->name;
$k = $edina->colvo;
$izm = RM::factory(‘edizm’, array(‘id’=>$edina->edizm))->name;
$seg->setVars(‘article’, $art, $encode =TRUE, $charset = ‘UTF-8′);
$seg->setVars(‘name’, $naim, $encode =TRUE, $charset = ‘UTF-8′);
$seg->setVars(‘zvet’, $zvet, $encode =TRUE, $charset = ‘UTF-8′);
$seg->setVars(‘kol’, $k, $encode =TRUE, $charset = ‘UTF-8′);
$seg->setVars(‘izm’, $izm, $encode =TRUE, $charset = ‘UTF-8′);
$seg->merge();
}
$odf->mergeSegment($seg);
$odf->exportAsAttachedFile();
exit;
}
, 02.02.2012 в 20:44
СПАСИБО ВСЕМ!!! Во всем разобрался — все заработало! Андрей спасибо за ваши уроки, они просто супер!!! Жду, по возможности урок импорта из xml либо html либо из любого другого популярного файла! СПАСИБО!!!