У каждой задачи есть несколько вариантов решения. И иногда в угоду скорости приходится выбирать не самый красивый, зато работающий и выполняющий поставленные перед ним цели. Итак, в один не очень прекрасный день возникла необходимость реализовать следующую функцию: у каждой (почти) страницы сайта должны быть автоматически сгенерированные копии в форматах DOC и PDF. С сохранением всех таблиц и картинок внутри контента. И если с PDF всё относительно просто (tcpdf наш друг и брат), то с DOC'ом возникла морока. Под катом — пример решения данной задачи.В голову приходили последовательно такие варианты решения:
Пример применения написанной функции:
А вот и исходный код функции:
Update: в комментариях протестировали получившийся файл — нормально он открывается только в Microsoft Word 2003 и выше, в сторонних продуктах (OpenOffice и другие) возникают проблемы. Так же в комментариях приведены ссылки на многие другие, более правильные методы преобразования
Update 2: Обновил исходник — FlexIDK предложил более удачную регулярку, выбирающую пути картинок без лишних символов.
- Установить на сервер OpenOffice (сервер на FreeBSD) и разобраться с преобразованием. Красивое решение, но время поджимало.
- Сгенерировать вместо DOC'а файлик в формате RTF, благо формат открытый и библиотек для работы с ним много. Минус – готового преобразователя HTML->RTF (с, напомню, сохранением картинок и таблиц) я не нашел, а писать свою – для этого нужен определённый запас времени
- Не очень честный — просто “в лоб” сохранить HTML страницу с расширением DOC – Word 2003 и выше откроет без проблем, проверено. Плюс – отличнейшая скорость преобразования и сохранение всей верстки. Минус – картинки таким образом не сохранить (да и честность метода несколько хромает).
Пример применения написанной функции:
$link="m.habrahabr.ru/post/136811/"; CreateDOC($link,"test.doc");
А вот и исходный код функции:
Естественно, можно написать на основе этого гораздо более универсальный и прямой класс, но для наших целей этого было достаточно. Главное — данное решение работает, и достаточно быстро. Надеюсь, оно покажется кому то достаточно полезным.function CreateDOC($link,$filename) { //выделяем базовый домен, пригодится $base_link=$link; $base_link=explode("/",$link); unset($base_link[count($base_link)-1]); $base_link[]=""; $base_link=implode("/",$base_link); //получаем текст страницы $get_text=file_get_contents($link); //создаём объект, который и будет генерировать нам конечный mht $MhtFileMaker = new MhtFileMaker(); //подключаем картинки к файлу //более прямая регулярка, вытаски��аюшая пути картинок, спасибо хабраюзеру FlexIDK preg_match_all('@<img(.*)?src="([^"]+)"@ui', $get_text, $matches); foreach ($matches[4] as $img) { $img_tmp=$img; $img_tmp_old=$img; //помните, базовая ссылка? пригодилась же! if (strpos($img_tmp,"http")===FALSE) $img_tmp=$base_link.$img_tmp; //выделяем путь картинки БЕЗ адреса домена $img_array=explode("//",$img_tmp); $img_name_only=$img_array[1]; $img_name_only=explode("/",$img_name_only); unset($img_name_only[0]); $img_name_only=implode("/",$img_name_only); //заменяем адрес картинки на относительный (без домена) $get_text=str_replace($img_tmp_old,$img_name_only,$get_text); //добавляем картинку в конечный файлГ $MhtFileMaker->AddFile($img_tmp, $img_name_only, NULL); }; //разобрали картинки, теперь создаём окончательный файл $MhtFileMaker->AddContents("index.html","text/html",$get_text); //сохраняем файл $MhtFileMaker->MakeFile($filename); };
Update: в комментариях протестировали получившийся файл — нормально он открывается только в Microsoft Word 2003 и выше, в сторонних продуктах (OpenOffice и другие) возникают проблемы. Так же в комментариях приведены ссылки на многие другие, более правильные методы преобразования
Update 2: Обновил исходник — FlexIDK предложил более удачную регулярку, выбирающую пути картинок без лишних символов.
