С приблизително един милиард души, използващи Microsoft Office, форматът DOCX е най-популярният де факто стандарт за обмен на файлове с документи между офиси. Най-близкият му конкурент - ODT форматът - се поддържа само от Open / LibreOffice и някои продукти с отворен код, което го прави далеч от стандартния. Форматът PDF не е конкурент, тъй като PDF файловете не могат да бъдат редактирани и не съдържат пълна структура на документа, така че те могат да правят само ограничени местни промени като водни знаци, подписи и други подобни. Ето защо повечето бизнес документи се създават във формат DOCX; няма добра алтернатива, която да го замени.
Въпреки че DOCX е сложен формат, може да искате да го анализирате ръчно за по-прости задачи като индексиране, конвертиране в TXT и извършване на други малки модификации. Бих искал да ви дам достатъчно информация за вътрешните части на DOCX, за да не се налага да се позовавате на спецификациите на ECMA, масивно ръководство от 5000 страници.
Най-добрият начин да разберете формата е да създадете прост документ с една дума с MSWord и да наблюдавате как редактирането на документа променя основния XML. Ще се сблъскате с някои случаи, когато DOCX не се форматира правилно в MS Word и не знаете защо, или ще попаднете на случаи, когато не е очевидно как да генерирате желаното форматиране. Виждането и разбирането на точно какво се случва в XML ще помогне за това.
Работих около година върху съвместен редактор на DOCX, CollabOffice и искам да споделя част от това знание с общността на разработчиците. В тази статия ще обясня файловата структура на DOCX, обобщавайки информация, която е разпръсната из интернет. Тази статия е посредник между огромната, сложна спецификация на ECMA и простите интернет уроци, които се предлагат в момента. Можете да намерите файловете, придружаващи тази статия, в toptal-docx
проект на моя github акаунт .
DOCX файлът е ZIP архив на XML файлове. Ако създадете нов, празен документ на Microsoft Word, напишете една дума ‘Test’ вътре и разархивирайте съдържанието му, ще видите следната файлова структура:
Въпреки че създадохме прост документ, процесът на записване в Microsoft Word генерира теми по подразбиране, свойства на документи, таблици на шрифтове и т.н., във формат XML.
Всички файлове в DOCX са XML файлове, дори тези с разширението '.rels'. TweetЗа начало нека премахнем неизползваните неща и се съсредоточим върху document.xml
, който съдържа основните текстови елементи. Когато изтривате файл, уверете се, че сте изтрили всички препратки към отношенията към него от други xml файлове. Ето пример за различен код за това как съм изчистил зависимостите от app.xml и core.xml. Ако имате някакви неразрешени / липсващи препратки, MSWord ще счете файла за счупен.
Ето структурата на нашия опростен, минимален DOCX документ (и ето проекта на github ):
Нека да го разделим по файл оттук, отгоре:
Това определя препратката, която казва на MS Word къде да търси съдържанието на документа. В този случай той се позовава word/document.xml
:
[Content_Types].xml
Този файл определя препратки към ресурси, като изображения, вградени в съдържанието на документа. Нашият прост документ няма вградени ресурси, така че етикетът за връзка е празен:
Test
/word/styles.xml
съдържа информация за видовете носители в документа. Тъй като имаме само текстово съдържание, това е доста просто:
My heading 1
И накрая, тук е основният XML с текстовото съдържание на документа. Премахнах някои от декларациите за пространство на имена за по-голяма яснота, но можете да намерите пълната версия на файла в проекта github. В този файл ще откриете, че някои от препратките към пространството от имена в документа са неизползвани, но не трябва да ги изтривате, защото MS Word се нуждае от тях.
Ето нашия опростен пример:
styles.xml
Основният възелпредставлява самия документ, съдържа абзаци и вложени средени размери на страницата, дефинирани от.
е атрибут, който можете да игнорирате; използва се от вътрешните модули на MS Word.
Нека да разгледаме по-сложен документ с три абзаца. Откроих XML със същите цветове на екранната снимка от Microsoft Word, така че можете да видите корелацията:
w:p/w:r/w:rPr/*
Един прост документ се състои от абзаци, абзацът се състои от изпълнения (поредица от текст със същия шрифт, цвят и т.н.), а изпълненията се състоят от символи (като). Таговете могат да имат няколко знака вътре, а може да има и няколко в същото изпълнение.
Отново можем да игнорираме.
Основните свойства на текста са шрифт, размер, цвят, стил и т.н. Има около 40 маркера, които определят външния вид на текста. Както можете да видите в нашия пример с три абзаца, всяко изпълнение има свои собствени свойства, уточняване и смелост.
Важно е да се отбележи, че свойствата правят разлика между двете групи символи, нормален и сложен скрипт (например арабски) и че свойствата имат различен таг в зависимост от това кой тип характер засяга.
Повечето нормални маркери на свойства на скриптове имат съвпадащ сложен маркер на скрипт с добавено „C“, указващо свойството да е за сложни скриптове. Например: (курсив) става, а удебеленият таг за нормален скрипт ,, става за сложен скрипт.
В Microsoft Word има цяла лента с инструменти, посветена на стилове: нормално, без интервали, заглавие 1, заглавие 2, заглавие и т.н. Тези стилове се съхраняват в w:r/w:pPr/*
(забележка: в първата стъпка в нашия прост пример премахнахме този XML от DOCX. Направете нов DOCX, за да видите това).
След като определите текста като стил, ще намерите препратка към този стил вътре в маркера за свойства на абзаца ,. Ето пример, в който съм дефинирал текста си със заглавие 1 на стила:
/word/styles.xml
и тук е самият стил от w:styles/w:docDefaults/w:rPrDefault/*
:
w:styles/w:docDefaults/w:pPrDefault/*
Thexpath посочва, че шрифтът е удебелен, и указва цвета на шрифта. Инструктира MSWord да използва стил „Normal“ за липсващи свойства.
Свойствата на текста се наследяват. Изпълнението има свои собствени свойства (w:type='paragraph'
), но също така наследява свойства от параграф (w:default='1'
) и двете могат да препращат свойствата на стила от word/_rels/document.xml.rels
.
word/theme/themes1.xml
Параграфите и изпълненията започват със свойства по подразбиране: a:themeElements/a:fontScheme/a:majorFont
и a:minorFont
. За да получите крайния резултат от свойствата на даден герой, трябва:
Когато казвам „добавяне“ на B към A, имам предвид да прегледам всички свойства на B и да отменя всички свойства на A, оставяйки всички не пресичащи се свойства такива, каквито са.
Още едно място, където могат да бъдат разположени свойствата по подразбиране, е в тега с w:docDefaults/w:rPrDefault
и w:val
. Имайте предвид, че самите символи в дадено изпълнение никога нямат стил по подразбиране, всъщност содовете не засягат нито един текст.
1554402290400-dbb29eef3ba6035df7ad726dfc99b2af.png)
Символите в изпълнение могат да наследят от неговия абзац и двамата могат да наследят от styles.xml.Някои от свойствата са „превключващи“ свойства, като (получер) или (курсив); тези атрибути се държат като XOR оператор.
Това означава, че ако родителският стил е удебелен, а детското изпълнение е удебелено, резултатът ще бъде обикновен, не-удебелен текст.
Трябва да направите много тестове и обратен инженеринг, за да се справите правилно с превключващите атрибути. Обърнете внимание на параграф 17.7.3 от спецификацията ECMA-376 Open XML, за да получите официалните подробни правила за превключване на свойствата /
Превключващите свойства са най-сложните, за да може даден лайтър да се справи правилно. TweetШрифтовете следват същите общи правила като другите текстови атрибути, но стойностите по подразбиране на свойствата на шрифта са посочени в отделен файл на тема, посочен под 'left'
като този:
'center'
Въз основа на горната препратка, името на шрифта по подразбиране ще бъде намерено в 'right'
, вътре в atag, 'both'
или 'left'
етикет.
Размерът на шрифта по подразбиране е 10, освен ако 'center'
липсва етикет, тогава е размер 11.
Подравняването на текста се определя от atag с четири 'right'
налични режими: 'both'
, w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip/@r:embed
, word/_rels/document.xml.rels
и word/_rels/document.xml.rels
.
left right
е режимът по подразбиране; текстът се започва отляво на правоъгълника на абзаца (обикновено ширината на страницата). (Този параграф е подравнен вляво, което е стандартно.)
w:spacing
режим, предсказуемо, центрира всички знаци в ширината на страницата. (Отново този параграф илюстрира центрирано подравняване.)
В w:after
режим, текстът на абзаца е подравнен вдясно. (Забележете как този текст е подравнен от дясната страна.)
w:before
режим поставя допълнително разстояние между думите, така че редовете да станат по-широки и да заемат пълната ширина на абзаца, с изключение на последния ред, който е подравнен вляво. (Този параграф е демонстрация на това.)
DOCX поддържа два вида изображения: вградени и плаващи.
Вградените изображения се появяват вътре в абзац заедно с останалите знаци, използва се вместо да се използва (текст). Можете да намерите ID на изображението със следния синтаксис на xpath:
w:line
Идентификаторът на изображението се използва за търсене на името на файла в w:line
файл и трябва да сочи към gif / jpeg файл в подпапка word / media. (Вижте файла 1.docx
на проекта на github, където можете да видите идентификатора на изображението.)
Плаващи изображения се поставят спрямо абзаци, като текстът тече около тях. (Ето го github проект образец на документ с плаващо изображение.)
Използвайте плаващи изображения вместо, така че ако изтриете какъвто и да е текст вътре, внимавайте с котвите, ако не искате изображенията да бъдат премахнати.
XML таговете за таблици са подобни на маркирането на HTML таблица - е същото като
ОБЩИ КОНВЕРСИИ НА DOCX XML ЕДИНИЦИ | ||||||
20-та точка | Точки dxa / 20 | Инчове пт / 72 | Сантиметри в * 2,54 | Половин размер на шрифта пт / 144 | ИПС в * 914400 | |
Пример | 11906 | 595.3 | 8.27 ... | 21 00086 ... | 4,135 | 7562088 |
Етикети, използващи това | pgSz / pgMar / w: интервал | в: sz | wp: обхват, a: вътр |
Ако искате да конвертирате DOCX файл (например в PDF), да го нарисувате на платно или да преброите броя на страниците, ще трябва да внедрите макет. Layout е алгоритъм за изчисляване на позиции на символи от DOCX файл.
Това е сложна задача, ако се нуждаете от 100% рендериране. Количеството време, необходимо за прилагане на добър макет, се измерва в човеко години, но ако се нуждаете само от прост, ограничен, това може да се направи сравнително бързо.
Layout запълва родителски правоъгълник, който обикновено е правоъгълник на страницата. Той добавя думи от изпълнение един по един. Когато текущата линия препълни, тя започва нова. Ако абзацът е твърде висок за родителския правоъгълник, той се премества на следващата страница.
Ето някои важни неща, които трябва да имате предвид, ако решите да приложите макет:
|_+_|, но това не е размерът на реда, както може да се очаква. За да получите размера на реда, вземете текущата височина на шрифта, умножете по
This is our example first paragraph. It's default is left aligned, and now I'd like to introduce some bold text , and also change the font style to 'Impact'. This is new paragraph. This is one more paragraph, a bit longer.и разделете на 12.
Когато не е очевидно как този или онзи XML маркер работи в MS Word, има два основни подхода за неговото разгадаване:
Създайте желаното съдържание стъпка по стъпка. Започнете с прост docx файл. Запазете всяка стъпка в свой собствен файл, като например
|_+_|, Разархивирайте всеки от тях и използвайте инструмент за визуална разлика за сравнение на папки, за да видите кои маркери се появяват след вашите промени. (За търговска опция опитайте Araxis Merge или безплатна опция WinMerge.)
Ако генерирате DOCX файл, който MS Word не харесва, работете назад. Опростете своя XML стъпка по стъпка. По някое време ще научите коя промяна MS Word е намерила за неправилна.
Той е сложен и лицензът на Microsoft забранява използването на MS Word от страна на сървъра за обработка на DOCX - това е доста стандарт за търговските продукти. Microsoft обаче предостави XSLT файл за обработка на повечето DOCX тагове, но това няма да ви даде 100 процента или дори 99 процента вярност. Процеси като обгръщане на текст върху изображения не се поддържат, но ще можете да поддържате по-голямата част от документите. (Ако не се нуждаете от сложност, помислете дали да не използвате Маркдаун като алтернатива.)
Ако имате достатъчен бюджет (няма безплатен механизъм за рендиране на DOCX), може да искате да използвате търговски продукти като Aspose или docx4j. Най-популярното безплатно решение е LibreOffice за конвертиране между DOCX и други формати, включително PDF. За съжаление LibreOffice съдържа много малки грешки по време на преобразуване и тъй като това е сложен продукт с отворен код C ++, той е бавен и труден за отстраняване на проблеми с верността.
Като алтернатива, ако смятате, че оформлението на DOCX е твърде сложно, за да се приложите сами, можете също да го конвертирате в HTML и да го използвате с браузър. Можете също да помислите за един от Разработчиците на XML на свободна практика на ApeeScape .