Pull to refresh

Comments 59

Если нужно заменить строки текста (и не надо, например, собирать документ по кускам или вставлять картинки), то можно сделать проще.
Создаем любой сложности документ документ, так же размечаем — например {address}, {phone} и сохраняем в формате docx.
Потом открываем блокнотом и… видим обычный xml. В котором можем заменить данные простым str_replace.
> «Потом открываем блокнотом и… видим обычный xml»
Только сначала надо разархивировать, а потом уже открывать в блокноте.
> «Потом открываем блокнотом и…»
и уж точно не надо ипользовать для этих целей блокнот…
Не нужно ничего разархивировать.

1. Из Word'a шаблон документа сохраняем как file.xml
2. $template = file_get_contents(«file.xml»);
3. $template = str_replace("{phone}", "+7999887766", $template);
4. header(«Content-type: application/msword»);
5. echo $template.

Profit.
Если сохранить в формате docx, то в блокноте откроются кракозябы. Обычный XML мы получим только если сохраним документ в формате XML-документ Word. А это уже потребует дополнительноей конвертации в XML и обратно в doc.
Ваш вариант тоже рабочий, но не настолько прост как вы описали.
Забыл про внутренню структуру совсем. Но в любом случае архив распаковывается, и в \word\document.xml все читаемо и без крякозябр.
Спасибо за вариант, укажу о нём в статье
а с Doc такой вариант работает?
Если приспичит, можно конвертором каким-нибудь гонять doc -> docx -> doc.
так же размечаем — например {address}, {phone} и сохраняем в формате docx.

Ага и получаем косяков пачку. MS World вставляет дополнительную разметку в файл для что называется более простого сравнивания. В результате чего обычными xml средствами изменять файлы не возможно. Придется менять на xxxadressxxx, xxxphonexxx. их не разбивает.
Не понимаю чем вам вариант передачи HTML+php в rtf не устраевает? Делаем быстро шаблон через какой-нить визуальный редактор HTML, вставляем переменные PHP и генерируем RTF. www.cyberforum.ru/php/thread68701.html вот простой пример.

Почему именно docx? у заказчика проблемы с RTF?
Поддерживаю. В свое время решил подобную задачу именно при помощи RTF. Оригинальные шаблоны заказчика сохранил в RTF, проставил «макросы» в нужных местах, а в PHP читал файл и заменял макросы на значения. Всё просто, и у заказчика никаких проблем с редактированием шаблонов не возникало — в том же MS Word всё аналогично редактируется и прозрачно для пользователя.
Поясните, с какими из задач не справился (бы) phpword? (хотя судя по документу это большая таблица и ее следует делать в екселе, для чего есть и phpexcel).
На сколько мне известно PHPWord не может работать с форматом doc. А данный сервис может))
Я подобное делал с OpenOffice. Сохранял в fodt (да, это тоже xml) и менял. Сжатия там нет, так что все достаточно просто.
Единственный косяк — OpenOffice почему-то любит разбивать слова на куски. Лечится так: открываем текстовым редактором свой шаблон, находим свои %var% (или как там) и вручную приводим к человеческому виду.
А в чём сложность любой документ сохранить как html или mht и редактировать как HTML-шаблон обычный?
Как правило, нужно чтобы на выходе был тот же *.doc или *.docx
Достаточно написать в конце .doc, и voi la, перед нами .doc! Или вам зачем-то нужен именно документ внутреннего формата Word?
В таком случае при открытии оно выдает предупреждене что файл кагбы не совсем подлинного формата, и как правило юзеров очень напрягает, не опытным блондам на ум приходит только одно — «Ахтунг! это ВИРУС!» и начинается спамилка негатива во всех направлениях!
Основная задача, конечно же, чтобы загруженный документ корректно и без лишних вопросов открывался в M$ Word ;-)
совсем не то по ссылке
XML содержится не только в docx. Я работал с doc'ами содержащими XML. Они поддерживаются офисом начиная с 2003.
Справедливости ради есть ещё один вариант, очевидный, по-моему, для тех кто работает под для винды:
0) Использовать OLE automation, жаль под никсами это затруднительно, да и офис надо покупать.

Можно этот вариант развить и написать свой сервис, лишенный недостатков LiveDocx и делающий ровно то, что вам нужно без особых ограничений.

Непереносимо и неуниверсально. Ниже написал — самый оптимальный вариант работы с обычными документами — это программная обработка исключительно ODF, а дальше, если уж никак без доков не обойтись, конвертация ODF в doc через OpenOffice PyUNO.
Я для генерации xls использую XML + XSLT, где на выходе получается SpreadsheetML
Легко и нет зависимости от сторонних сервисов
Есть еще вариант использовать UNO + OpenOffice.
года два назад был момент в жизни когда хотелось с ним разобраться но все закончилось после установки и запуска Офиса и модуля для ПХП, и тестового запуска из примеров :)
Вообще вещь очень интересная и на мой взгляд крайне функциональная, но в твоем случае ВОЗМОЖНО из пушки по воробям
Не, не из пушки. Если использовать UNO только для конвертации, а программно обрабатывать ODF — самое то. ИМХО, оптимальнейшей решение в 99.9% случаев когда необходимо программно обрабатывать документы. Прямая работа с форматами майкрософта это вообще изврат, который поискать ещё надо.
Хм. И эта система видит интернет? А как там в Питере с законодательством на этот счет?
OpenSource — сообщество не могло не высказаться по этому поводу. Позвольте добавить еще вариант:

4) Открытая LGPL библиотека PHPWord для создания docx-документов phpword.codeplex.com/ (имеется также PHPExcel и PHPPowerPoint)
Добавлю, что далее можно использовать команднострочные утилиты конвертации. К примеру, открытый AbiWord умеет преобразовывать форматы: rtf, doc, docx и др.
По-моему, самый простой вариант — использовать rtf. В нем расставляем переменные и потом через str_replace меняем их и перезаписываем файл. Правда, хз как с таблицами поступать, когда новые строки надо :)
каменный век какой-то: RTF, маркеры, замена…
У меня тестовое задание было на собеседовании по теме XSLT — нужно было из размеченного DOCX извлекать данные. В принципе оказалось очень просто. Внутри обцыный XML (правда структура довольно сложная, но нам все тонкости не нужно знать.

2 последовательных трансформации и готово… Строк 100 XSLT кода вышло.

Мой совет — забейте на этот жуткий бинарный doc пятнадцатилетней давности и используйте docx или rtf если odt не можете. И используйте XPath для навигации по XML а не str_replace. И, между прочим, docx поддерживает кастомные теги разметки для выделения спец. полей.

Использовать сторонний сервис для заполнения шаблонов документов — это как-то слишком ненадежно.
Зачем же костылить-то так? Есть нормальный odf, который парсится и создаётся на ура в любом виде из практически любого скриптового языка, в том числе PHP. Соответственно работаем всегда с ODF, а если, упаси Боже, кому-то нужны doc, то используем возможности OpenOffice по автоматической конвертации между форматами (PyUNO). Работать с docx или тем более с doc — это извращение, абсолютно бесполезное к тому же. Не надо себе трудностей создавать. Вся обработка электронных документов исключительно через ODF — это самый оптимальный способ, если у вас конечно не .NET приложение. Неоднокрано проверено.

1) использовать одну из библиотек для работы с Word документами

А таких много хоть сколько-нибудь годных? И они, наверное, бесплатные?

2) сохранить документ в формате docx, открыть архиватором и внутри мы увидим "\word\document.xml" — чистый xml, с которым можно работать через str_replace

Это п#здец, вообще говоря. Потом ещё удивляются, откуда столько «быдлокодеров» и «говнокода» берётся. Впрочем, ничего личного, может человек просто PHP изучил полгода назад, а до того программирование в глаза не видел, поэтому придумывает способы в рамках своих знаний.

Там где есть XML, не важно какой, есть и XSLT.
Преобразования/шаблонизация вордовских документов были ещё в Office 2003 доступны. Делаем шаблон документа, сохраняем как XML документ, расставляем элементы, привязываем к DOM. Потом остаётся только подгружать XML с подставляемыми данными и получать конечный документ.
Примеры:
XML/XSLT Word Report Generator
Generating Word documents using XSLT
Литература: Office 2003 XML for Power Users (скачать).
ну да, а что это даст, когда надо структуру документа изменить? Строчку в таблицу, например, добавить? Хотя это возможно и получится, а вот что-то более комплексное — нет. Не надо создавать себе трудностей и работать с форматами, для которых не существует адекватных библиотек парсинга и модификации. XSLT конечно хорошо, но, например, на Perl OpenOffice::OODoc явно получше для любых операций с документами. На PHP не помню что там есть для работы с ODF, но явно что-то должно быть. Парсить XML когда можно работать напрямую с данными и структурами в документе через какую-либо библиотеку — это всё же изврат.
ну да, а что это даст, когда надо структуру документа изменить? Строчку в таблицу, например, добавить? Хотя это возможно и получится, а вот что-то более комплексное — нет.

n штук исходных XML + XSLT преобразование → новый XML, в т.ч. совершенно другой структуры
Делайте настолько комплексное, насколько хватит ваших знаний XML, XPath и XSL. Правда, исходя из вашего комментария, можно предположить, что их пока нет вообще.

Полистал описание OpenOffice::OODoc — как и ожидалось, просто некоторая специализированная надстройка над DOM и XPath для схемы ODF. Для Java в таком случае тоже есть нечто.
Если нужны именно преобразования одного документа (шаблона) в другой — не очень понимаю, чем для этого клиентские библиотеки (ориентированные прежде всего на создание документов и простейшие операции с уже существующими) подходят лучше, нежели XSLT.

На PHP не помню что там есть для работы с ODF, но явно что-то должно быть.

У него самого точно ничего нет, а сторонние библиотеки к чему угодно можно прикрутить. Только нужен ли в таком случае именно PHP? ;)

Парсить XML когда можно работать напрямую с данными и структурами в документе через какую-либо библиотеку — это всё же изврат.

Вообще говоря, «парсить» никто и не предлагал… Транформация ≠ парсинг. За вас всё отпарсит уже существующий код библиотек.
Просто XSLT предполагает то, что вы разбираетесь во внутренней структуре формата. А штуки по типу OODoc позволяют вам вообще не задумываться о том, что там внутри файла с расширение .odt находится, а работать только с данными, используя стандартную объектную модель. Спецификация ODF 1.2 не такая и маленькая, и ИМХО это не тот случай, когда надо применять XSLT, особенно когда есть полнофункциональные альтернативы. И нет, я знаю, что такое XSLT, но плотно никогда не работал, да, как-то не было случая помучить что-то XML'ное.
XSLT — это какое-это мегаофигенное, но не по-детски сложное говно. (ИМХО!)

И для генерации документов подходит так же, как крупнокалиберная корабельная пушка для прицельной стрельбы по воробьям.
ничуть не сложнее многих других способов
несколько хороших примеров + неделя практики = горы свернёте :)
но, конечно, без знаний XML и XPath никуда
>Это п#здец, вообще говоря. Потом ещё удивляются, откуда столько «быдлокодеров» и «говнокода» берётся

Откуда столько ненависти?

Вы забываете про целесообразность. Какие xslt? Какие шаблонизации? Еще книги какие-то читать?
Зачем это все, когда в документе нужно вставить фио, и есть элементарное решение в несколько строк кода?
если вам надо всего-лишь вставить ФИО и т.п., то это делается посредством «слияния»
Слияние документов Word
и не надо велосипед изобретать
Отдельный человек, который будет склеивать документы, тыкая по менюшкам в ворде, не нужен. Нужен скрипт ;)
освойте макросы и VBA
это всяко «ближе к телу», чем какие-то убожества по замене «А» на «Б» с помощью PHP
Оно работает на *nix серверах?
*NIX+MS Word вообще странный выбор
изобретать столько костылей из-за проприетарного формата, вместо того чтобы генерить HTML или PDF
но к чему вопрос? данный топик такую задачу не ставил, например
а в умелых руках всё работает
Часто нужны именно word-документы, к сожалению. Я знаю по опыту.

А еще, я искренне недоумеваю (серьезно, искренне!), почему вы (и еще некоторые люди тут) советуют не изобретать велосипед, а какие-то библиотеки, специализированные инструменты, когда программист может решить задачу за пару минут на любом известном ему серверном языке программирования :)

В данном случае, как раз, все эти инструменты — преусловутые велосипеды, которые нужно еще купить/привезти (установить, изучить), когда можно просто пройти десяток метров.

Посмотрите вот на этот комментарий. Даже для замены пары десятков значений код мало будет отличаться. Элементарное решение.

Нет, конечно, если программист умеет работать с преусловутыми «специализированными инструментами», можно воспользоваться ими, но мне почему-то кажется, что в этом случае придется затратить больше времени и тащить за проектом лишние библиотеки.
А нет решения для замены {Variables} для python? rtf, doc, docx без разницы. Парсить xml здорово, но хотелось бы попроще. Нужно для интеграции в arcgis, а там только python.
open("myfile.xml", "r").read().replace("{phone}", "2-12-85-06")?
Sign up to leave a comment.

Articles