Почему Office OpenXML разделяет текст между тегами и как это предотвратить?
В настоящее время я пытаюсь работать с файлами docx, используя библиотеку PHPWord и ее систему шаблонов. Я нашел и обновил чей-то (не могу вспомнить имя, но это не важно) путь к этой библиотеке, которая может работать с таблицами (копировать ее строки, а затем использовать стандартное значение SET () из PHPWord для каждой строки).
Если я создаю свой собственный документ, данные в xml имеют обычную структуру, поэтому переменная, которую нужно заменить ${переменная}, находится в своем собственном теге, например это:
<w:tbl>
<w:tr>
...
${variable}
</w:tr>
</w:tbl>
Я упростил код, в фактическом коде есть ряд других тегов, описывающих размеры, стили и т.д.
Моя проблема в том, что мне приходится обрабатывать документы от других людей, где мне запрещено вносить большие изменения, я получаю документ, в котором в какой-то момент они представляют собой таблицу с одной пустой строкой. Я добавляю переменные ${variable} и запускаю их через PHPWord. Проблема в том, что он терпит неудачу. Проведя некоторое исследование, я обнаружил, что исходный XML выглядит следующим образом:
....
...
${va
...
riab
...
le}
....
(снова сильно упрощено, но вы получаете картину)
Эта структура является для меня проблемой, потому что функция для клонирования строк использует strpos(), substr() и регулярные выражения для работы и не работает с этой структурой (и я не могу представить элегантный способ сделать это так).
Итак, вопрос в том, знает ли кто-нибудь, почему docx делает это и как ему помешать? Я ищу решение с помощью word, а не PHP (мне нужны текущие функции для работы без особого редактирования)
3 answers
Я много работал с этой проблемой:
В Word документ можно сохранить следующим образом
<w:t>{</w:t>...
<w:t>variable</w:t>
<w:t>}</w:t>
Поэтому я создал библиотеку JS, которая работает, даже если имена переменных разделены: DOCXGENJS (также работает на стороне сервера). Что я обнаружил во время разработки, так это то, что имена переменных не разделяются, если:
- Текст, который нужно найти, состоит только из символов a-za-Z (без {, $ или })
- Текст может быть разделен, если текст не был написан в один штрих: например, если вы допустили орфографическую ошибку и написали ${varuable}, а затем отредактировали -> ${переменная}, текст внутри xml, скорее всего, будет разделен. В основном вам нужно написать имена переменных одним штрихом, и если вы хотите отредактировать одно из них, полностью перепишите имя переменной.
Я не думаю, что есть способ исправить документ docx с помощью одной команды в Word, но переписывание переменных, чтобы записать их одним штрихом, должно сработать.
Word делает это по определенным причинам, например, для обозначения орфографических ошибок или для отслеживания изменений и достижения лучшего результата при объединении документов на основе rsid-номеров (http://blogs.msdn.com/b/brian_jones/archive/2006/12/11/what-s-up-with-all-those-rsids.aspx).
И здесь вы можете найти решение для очистки документа: https://stackoverflow.com/a/7768161
Основной причиной этого является элемент proofErr
. Посредством чего Word идентифицирует то, что, по его мнению, написано неправильно, и заключает это в элемент <w:proofErr>
, неизбежно разделяя исходный текст.
Если это случится с вами, я рекомендую следующее, это утомительно, но единственный верный способ:
- Переименовать
.docx
в.zip
. - Извлеките содержимое архива.
- Открыть
word\document.xml
. - Внесите исправления (т.е. соедините разделенный текст вместе) и сохранить.
- Переименовать
.zip
в.docx
.
РЕДАКТИРОВАТЬ
Это Расширение Visual Studio позволяет напрямую редактировать содержимое пакета OpenXML. Это позволяет пропустить шаги 1 и 2.