Простейшая генерация odt файла из существующего — работа над ошибками
Всем свойственно ошибаться… но я считаю, что ошибки стоит исправлять.
Недавно обновился OpenOffice до версии 3.2 и я заметил, что генерируемые документы odt по-моему хабратопику открываются в нём с ошибками. Первой мыслью было то, что произошли какие-то кардинальные изменения в спецификации ODF 1.2. Но всё оказалось проще:
Спецификация ODF требует в начале zip архива несжатый файл mimetype. OpenOffice до версии 3.2 распознавал odt файлы и не соблюдающие этого требования, в новой же версии это обязательно.
Все испортил класс ZipArchive.
Дело все в том, что ziparchive после метода close() записывает файлы не в том порядке, в каком мы их добавили, и уж тем более не умеет нормально регулировать уровень сжатия файлов.
Пришлось искать альтернативу. Как альтернатива был взят файл zip.lib.php из phpmyadmin и совсем слегка «допилен» — буквально затронул две строчки, добавив степень сжатия для файлов. (поправленный файл можно найти в архиве в конце статьи)
Вот эти строки:
Вся наша работа над ошибками пройдёт только в файле download.php:
Вот собственно и все. Надеюсь кому-нибудь данная работа над ошибками пригодится!
Скачать исходник целиком
_________
Текст подготовлен в ХабраРедакторе
Недавно обновился OpenOffice до версии 3.2 и я заметил, что генерируемые документы odt по-моему хабратопику открываются в нём с ошибками. Первой мыслью было то, что произошли какие-то кардинальные изменения в спецификации ODF 1.2. Но всё оказалось проще:
Спецификация ODF требует в начале zip архива несжатый файл mimetype. OpenOffice до версии 3.2 распознавал odt файлы и не соблюдающие этого требования, в новой же версии это обязательно.
Все испортил класс ZipArchive.
Дело все в том, что ziparchive после метода close() записывает файлы не в том порядке, в каком мы их добавили, и уж тем более не умеет нормально регулировать уровень сжатия файлов.
Пришлось искать альтернативу. Как альтернатива был взят файл zip.lib.php из phpmyadmin и совсем слегка «допилен» — буквально затронул две строчки, добавив степень сжатия для файлов. (поправленный файл можно найти в архиве в конце статьи)
Вот эти строки:
public function addFile($data, $name, $time = 0, $compresslevel=-1) $zdata = gzcompress($data,$compresslevel); // compress data Вся наша работа над ошибками пройдёт только в файле download.php:
<?php
if (!file_exists('doc.list')) die;
//текущее время - время создания файлов
$time = time();
//файл, который будем отдавать
$outname = 'zayavlenie.odt';
// класс для создания zip архива
require_once 'zip.lib.php';
//создаем новый архив
$zip = new zipfile();
//проходимся по структуре нашего архива
$files = file('doc.list') ;
foreach ($files as $filename) {
$filename = trim($filename);
//если файл content.xml, то проводим в нем подстановку пользовательских полей
if ($filename == "content.xml") {
//значения полей
$vars = array(
'ФИО'=>'Иванова И.И.',
'Дата'=>date('d.m.Y'),
'Планета'=>'Юпитер'
);
//создаем объект simplexml
$xml = new SimpleXMLElement(file_get_contents('doc/' . $filename));
//получаем заранее нужные namespace
$ns = $xml->getNamespaces(true);
//проверяем есть ли в файле пользовательские поля
$fields = $xml->children($ns["office"])->body->text->children($ns["text"])->{"user-field-decls"};
if ($fields) {
//если есть, пробегаемся по ним и заменяем их атрибут string-value на новый
foreach ($fields->children($ns["text"]) as $field) {
if (isset($vars[(string) $field->attributes($ns["text"])->name])) {
$field->attributes($ns["office"])->{"string-value"} = $vars[(string) $field->attributes($ns["text"])->name];
}
}
}
$data = $xml->asXML();
}
else {
$data = file_get_contents('doc/' . $filename);
}
//Добавляем файл/директрию в архив
//Если файл mimetype, то его нельзя сжимать - уровень компрессии 0
$zip->addFile($data, $filename, $time, $filename == 'mimetype' ? 0 : - 1);
}
//очищаем буфер и выдаем файл
ob_clean();
header('Content-Disposition: attachment; filename="' . $outname . '"');
header('Content-type: application/odt');
print $zip->file();
?>
* This source code was highlighted with Source Code Highlighter.Вот собственно и все. Надеюсь кому-нибудь данная работа над ошибками пригодится!
Скачать исходник целиком
_________
Текст подготовлен в ХабраРедакторе



комментарии (3)