บทนำสู่ DOCX . อย่างไม่เป็นทางการ
เผยแพร่แล้ว: 2022-03-11ด้วยจำนวนผู้ใช้ Microsoft Office ประมาณหนึ่งพันล้านคน รูปแบบ DOCX จึงเป็นมาตรฐานโดยพฤตินัยที่ได้รับความนิยมมากที่สุดสำหรับการแลกเปลี่ยนไฟล์เอกสารระหว่างสำนักงาน คู่แข่งที่ใกล้เคียงที่สุด - รูปแบบ ODT - รองรับเฉพาะ Open/LibreOffice และผลิตภัณฑ์โอเพ่นซอร์สบางตัว ทำให้ไม่มาตรฐาน รูปแบบ PDF ไม่ใช่คู่แข่งเพราะแก้ไข PDF ไม่ได้และไม่มีโครงสร้างเอกสารที่สมบูรณ์ จึงสามารถเปลี่ยนแปลงได้เฉพาะในเครื่องเท่านั้น เช่น ลายน้ำ ลายเซ็น และอื่นๆ นี่คือสาเหตุที่เอกสารทางธุรกิจส่วนใหญ่สร้างขึ้นในรูปแบบ DOCX ไม่มีทางเลือกอื่นที่ดีมาแทนที่
แม้ว่า DOCX จะเป็นรูปแบบที่ซับซ้อน คุณอาจต้องการแยกวิเคราะห์ด้วยตนเองสำหรับงานที่ง่ายกว่า เช่น การทำดัชนี การแปลงเป็น TXT และการแก้ไขเล็กน้อยอื่นๆ ฉันต้องการให้ข้อมูลเพียงพอเกี่ยวกับ DOCX internals เพื่อให้คุณไม่ต้องอ้างอิงข้อกำหนด ECMA ซึ่งเป็นคู่มือขนาดใหญ่ 5,000 หน้า
วิธีที่ดีที่สุดในการทำความเข้าใจรูปแบบคือการสร้างเอกสารคำเดียวอย่างง่ายด้วย MSWord และสังเกตว่าการแก้ไขเอกสารเปลี่ยนแปลง XML พื้นฐานอย่างไร คุณอาจเผชิญบางกรณีที่ DOCX ไม่ได้ฟอร์แมตอย่างถูกต้องใน MS Word และคุณไม่รู้ว่าทำไม หรืออาจพบกรณีที่ไม่มีวิธีสร้างการจัดรูปแบบที่ต้องการอย่างชัดเจน การเห็นและเข้าใจสิ่งที่เกิดขึ้นใน XML อย่างชัดเจนจะช่วยได้
ฉันทำงานเป็นเวลาประมาณหนึ่งปีกับ CollabOffice ซึ่งเป็นบรรณาธิการ DOCX ที่ทำงานร่วมกัน และฉันต้องการแบ่งปันความรู้บางอย่างกับชุมชนนักพัฒนา ในบทความนี้ ผมจะอธิบายโครงสร้างไฟล์ DOCX โดยสรุปข้อมูลที่กระจัดกระจายอยู่บนอินเทอร์เน็ต บทความนี้เป็นตัวกลางระหว่างข้อกำหนด ECMA ขนาดใหญ่ที่ซับซ้อนและบทช่วยสอนทางอินเทอร์เน็ตอย่างง่ายที่มีอยู่ในปัจจุบัน คุณสามารถค้นหาไฟล์ที่มาพร้อมกับบทความนี้ใน toptal-docx
ในบัญชี github ของฉัน
ไฟล์ DOCX อย่างง่าย
ไฟล์ DOCX เป็นไฟล์ ZIP ของไฟล์ XML หากคุณสร้างเอกสาร Microsoft Word ใหม่ที่ว่างเปล่า โดยเขียนคำว่า 'Test' ในหนึ่งคำแล้วแตกไฟล์ คุณจะเห็นโครงสร้างไฟล์ต่อไปนี้:
แม้ว่าเราจะสร้างเอกสารอย่างง่าย แต่กระบวนการบันทึกใน Microsoft Word ได้สร้างธีมเริ่มต้น คุณสมบัติของเอกสาร ตารางฟอนต์ และอื่นๆ ในรูปแบบ XML
ในการเริ่มต้น ให้เราลบสิ่งที่ไม่ได้ใช้และเน้นที่ document.xml
ซึ่งมีองค์ประกอบข้อความหลัก เมื่อคุณลบไฟล์ ตรวจสอบให้แน่ใจว่าคุณได้ลบการอ้างอิงความสัมพันธ์ทั้งหมดไปยังไฟล์นั้นออกจากไฟล์ xml อื่น นี่คือตัวอย่าง code-diff เกี่ยวกับวิธีที่ฉันล้างการขึ้นต่อกันของ app.xml และ core.xml หากคุณมีข้อมูลอ้างอิงที่ยังไม่ได้แก้ไข/ขาดหายไป MSWord จะถือว่าไฟล์เสีย
นี่คือโครงสร้างของเอกสาร DOCX ที่เรียบง่ายและเรียบง่ายของเรา (และนี่คือโครงการบน GitHub):
มาแยกเป็นไฟล์กันจากด้านบนนี้:
_rels/.rels
สิ่งนี้กำหนดการอ้างอิงที่บอกให้ MS Word ค้นหาเนื้อหาในเอกสาร ในกรณีนี้ จะอ้างอิง word/document.xml
:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/> </Relationships>
_rels/document.xml.rels
ไฟล์นี้กำหนดการอ้างอิงถึงทรัพยากร เช่น รูปภาพ ที่ฝังอยู่ในเนื้อหาเอกสาร เอกสารอย่างง่ายของเราไม่มีทรัพยากรฝังตัว ดังนั้นแท็กความสัมพันธ์จึงว่างเปล่า:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> </Relationships>
[Content_Types].xml
[Content_Types].xml
มีข้อมูลเกี่ยวกับประเภทของสื่อภายในเอกสาร เนื่องจากเรามีเพียงเนื้อหาที่เป็นข้อความ จึงค่อนข้างง่าย:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/> <Default Extension="xml" ContentType="application/xml"/> <Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/> </Types>
document.xml
สุดท้าย นี่คือ XML หลักที่มีเนื้อหาข้อความของเอกสาร ฉันได้ลบการประกาศเนมสเปซบางส่วนเพื่อความชัดเจน แต่คุณสามารถค้นหาเวอร์ชันเต็มของไฟล์ได้ในโปรเจ็กต์ github ในไฟล์นั้น คุณจะพบว่าการอ้างอิงเนมสเปซบางส่วนในเอกสารนั้นไม่ได้ใช้ แต่คุณไม่ควรลบออกเพราะ MS Word ต้องการ
นี่คือตัวอย่างแบบง่ายของเรา:
<w:document> <w:body> <w:pw:rsidR="005F670F" w:rsidRDefault="005F79F5"> <w:r><w:t>Test</w:t></w:r> </w:p> <w:sectPr w:rsidR="005F670F"> <w:pgSz w:w="12240" w:h="15840"/> <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/> <w:cols w:space="720"/> <w:docGrid w:linePitch="360"/> </w:sectPr> </w:body> </w:document>
โหนดหลัก <w:document>
แสดงถึงตัวเอกสาร <w:body>
มีย่อหน้า และซ้อนอยู่ภายใน <w:body>
คือมิติข้อมูลของหน้าที่กำหนดโดย <w:sectPr>
<w:rsidR>
เป็นแอตทริบิวต์ที่คุณสามารถละเว้นได้ มันถูกใช้โดย MS Word ภายใน
มาดูเอกสารที่ซับซ้อนมากขึ้นซึ่งมีสามย่อหน้ากัน ฉันได้เน้น XML ด้วยสีเดียวกันบนหน้าจอจาก Microsoft Word ดังนั้นคุณจึงสามารถเห็นความสัมพันธ์:
<w:pw:rsidR="0081206C" w:rsidRDefault="00E10CAE"> <w:r> <w:t xml:space="preserve">นี่คือตัวอย่างย่อหน้าแรกของเรา ค่าเริ่มต้นคือการจัดชิดซ้าย และตอนนี้ฉันอยากจะแนะนำ</w:t> </w:r> <w:r> <w:rPr> <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/> <w:color w:val="000000"/> </w:rPr> <w:t>ตัวหนาบางตัว</w:t> </w:r> <w:r> <w:rPr> <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/> <w:b/> <w:color w:val="000000"/> </w:rPr> <w:t xml:space="preserve"> ข้อความ</w:t> </w:r> <w:r> <w:rPr> <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/> <w:color w:val="000000"/> </w:rPr> <w:t xml:space="preserve">, </w:t> </w:r> <w:proofErr w:type="gramStart"/> <w:r> <w:t xml:space="preserve">และเปลี่ยน</w:t> </w:r> <w:rw:rsidRPr="00E10CAE"> <w:rPr><w:rFonts w:ascii="ผลกระทบ" w:hAnsi="ผลกระทบ"/> </w:rPr> <w:t>รูปแบบตัวอักษร</w:t> </w:r> <w:r> <w:rPr> <w:rFonts w:ascii="Impact" w:hAnsi="Impact"/> </w:rPr> <w:t xml:space="preserve"> </w:t> </w:r> <w:r> <w:t>เป็น 'ผลกระทบ'</w:t></w:r> </w:p> <w:pw:rsidR="00E10CAE" w:rsidRDefault="00E10CAE"> <w:r> <w:t>นี่คือย่อหน้าใหม่</w:t> </w:r></w:p > <w:pw:rsidR="00E10CAE" w:rsidRPr="00E10CAE" w:rsidRDefault="00E10CAE"> <w:r> <w:t>นี่คืออีกหนึ่งย่อหน้า ยาวขึ้นอีกนิด</w:t> </w:r> </w:p>
โครงสร้างย่อหน้า
เอกสารอย่างง่ายประกอบด้วยย่อหน้า ย่อหน้าประกอบด้วยการรัน (ชุดข้อความที่มีแบบอักษร สี ฯลฯ เหมือนกัน) และการเรียกใช้ประกอบด้วยอักขระ (เช่น <w:t>
) <w:t>
แท็กอาจมีอักขระหลายตัวอยู่ภายใน และอาจมีบางตัวในการเรียกใช้งานเดียวกัน
อีกครั้งเราสามารถละเลย <w:rsidR>
คุณสมบัติข้อความ
คุณสมบัติข้อความพื้นฐานได้แก่ แบบอักษร ขนาด สี ลักษณะ และอื่นๆ มีแท็กประมาณ 40 แท็กที่ระบุลักษณะข้อความ ดังที่คุณเห็นในตัวอย่างสามย่อหน้าของเรา การวิ่งแต่ละครั้งมีคุณสมบัติของตัวเองอยู่ภายใน <w:rPr>
โดยระบุ <w:color>
, <w:rFonts>
และตัวหนา <w:b>
สิ่งสำคัญที่ควรทราบคือคุณสมบัติสร้างความแตกต่างระหว่างอักขระสองกลุ่ม สคริปต์ปกติและสคริปต์ที่ซับซ้อน (เช่น อาหรับ) และคุณสมบัติมีแท็กต่างกันขึ้นอยู่กับประเภทของอักขระที่ส่งผลกระทบ
แท็กคุณสมบัติสคริปต์ปกติส่วนใหญ่มีแท็กสคริปต์ที่ซับซ้อนที่ตรงกัน โดยเพิ่ม "C" ซึ่งระบุว่าคุณสมบัตินั้นมีไว้สำหรับสคริปต์ที่ซับซ้อน ตัวอย่างเช่น: <w:i>
(ตัวเอียง) กลายเป็น <w:iCs>
และแท็กตัวหนาสำหรับสคริปต์ปกติ <w:b>
กลายเป็น <w:bCs>
สำหรับสคริปต์ที่ซับซ้อน
สไตล์
มีแถบเครื่องมือทั้งหมดใน Microsoft Word สำหรับสไตล์โดยเฉพาะ: ปกติ, ไม่มีระยะห่าง, ส่วนหัว 1, ส่วนหัว 2, ชื่อเรื่อง และอื่นๆ สไตล์เหล่านี้ถูกเก็บไว้ใน /word/styles.xml
(หมายเหตุ: ในขั้นตอนแรกในตัวอย่างง่ายๆ เราลบ XML นี้ออกจาก DOCX สร้าง DOCX ใหม่เพื่อดูสิ่งนี้)
เมื่อคุณกำหนดข้อความเป็นสไตล์แล้ว คุณจะพบการอ้างอิงถึงสไตล์นี้ภายในแท็กคุณสมบัติย่อหน้า <w:pPr>
ต่อไปนี้คือตัวอย่างที่ฉันกำหนดข้อความด้วยสไตล์ หัวข้อที่ 1:
<w:p> <w:pPr> <w:pStyle w:val="Heading1"/> </w:pPr> <w:r> <w:t>My heading 1</w:t> </w:r> </w:p>
และนี่คือสไตล์ของตัวเองจาก styles.xml
:
<w:style w:type="paragraph" w:style> <w:name w:val="heading 1"/> <w:basedOn w:val="Normal"/> <w:next w:val="Normal"/> <w:link w:val="Heading1Char"/> <w:uiPriority w:val="9"/> <w:qFormat/> <w:rsid w:val="002F7F18"/> <w:pPr> <w:keepNext/> <w:keepLines/> <w:spacing w:before="480" w:after="0"/> <w:outlineLvl w:val="0"/> </w:pPr> <w:rPr> <w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi"/> <w:b/> <w:bCs/> <w:color w:val="365F91" w:themeColor="accent1" w:themeShade="BF"/> <w:sz w:val="28"/> <w:szCs w:val="28"/> </w:rPr> </w:style>
<w:style/w:rPr/w:b>
xpath ระบุว่าแบบอักษรเป็นตัวหนา และ <w:style/w:rPr/w:color>
ระบุสีแบบอักษร <w:basedOn>
สั่งให้ MSWord ใช้รูปแบบ "ปกติ" สำหรับคุณสมบัติที่ขาดหายไป

มรดกทรัพย์สิน
คุณสมบัติข้อความได้รับการสืบทอด การรันมีคุณสมบัติของตัวเอง ( w:p/w:r/w:rPr/*
) แต่ยังสืบทอดคุณสมบัติจากย่อหน้า ( w:r/w:pPr/*
) และทั้งคู่สามารถอ้างอิงคุณสมบัติของสไตล์จาก /word/styles.xml
.
<w:r> <w:rPr> <w:rStyle w:val="DefaultParagraphFont"/> <w:sz w:val="16"/> </w:rPr> <w:tab/> </w:r>
ย่อหน้าและเรียกใช้เริ่มต้นด้วยคุณสมบัติเริ่มต้น: w:styles/w:docDefaults/w:rPrDefault/*
และ w:styles/w:docDefaults/w:pPrDefault/*
เพื่อให้ได้ผลลัพธ์สุดท้ายของคุณสมบัติของตัวละคร คุณควร:
- ใช้คุณสมบัติเริ่มต้น/ย่อหน้าเริ่มต้น
- ผนวกคุณสมบัติลักษณะการเรียกใช้/ย่อหน้า
- ผนวกคุณสมบัติการรัน / ย่อหน้าในเครื่อง
- ผนวกคุณสมบัติการเรียกใช้ผลลัพธ์เหนือคุณสมบัติย่อหน้า
เมื่อฉันพูดว่า "ผนวก" B ถึง A ฉันหมายถึงการวนซ้ำคุณสมบัติ B ทั้งหมดและแทนที่คุณสมบัติของ A ทั้งหมด โดยปล่อยให้คุณสมบัติที่ไม่ตัดกันทั้งหมดตามที่เป็นอยู่
ที่อื่นที่อาจพบคุณสมบัติเริ่มต้นอยู่ในแท็ก <w:style>
ด้วย w:type="paragraph"
และ w:default="1"
โปรดทราบว่าอักขระภายในการวิ่งจะไม่มีรูปแบบเริ่มต้น ดังนั้น <w:style w:type="character" w:default="1">
จะไม่ส่งผลต่อข้อความใดๆ
1554402290400-dbb29eef3ba6035df7ad726dfc99b2af.png)
สลับคุณสมบัติ
คุณสมบัติบางอย่างเป็นคุณสมบัติ "สลับ" เช่น <w:b>
(ตัวหนา) หรือ <w:i>
(ตัวเอียง); คุณลักษณะเหล่านี้ทำงานเหมือนตัวดำเนินการ XOR
ซึ่งหมายความว่าหากรูปแบบหลักเป็นตัวหนาและรายการย่อยเป็นตัวหนา ผลลัพธ์จะเป็นข้อความปกติและไม่ใช่ตัวหนา
คุณต้องทำการทดสอบและวิศวกรรมย้อนกลับเป็นจำนวนมากเพื่อจัดการกับแอตทริบิวต์การสลับอย่างถูกต้อง ดูย่อหน้าที่ 17.7.3 ของข้อกำหนด ECMA-376 Open XML เพื่อรับกฎอย่างเป็นทางการโดยละเอียดสำหรับคุณสมบัติการสลับ/
แบบอักษร
แบบอักษรใช้กฎทั่วไปเดียวกันกับแอตทริบิวต์ข้อความอื่นๆ แต่ค่าดีฟอลต์ของคุณสมบัติแบบอักษรถูกระบุในไฟล์ธีมแยกต่างหาก อ้างอิงภายใต้ word/_rels/document.xml.rels
ดังนี้:
<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>
จากข้อมูลอ้างอิงข้างต้น ชื่อแบบอักษรเริ่มต้นจะอยู่ใน word/theme/themes1.xml
ภายในแท็ก <a:theme>
, a:themeElements/a:fontScheme/a:majorFont
หรือแท็ก a:minorFont
ขนาดแบบอักษรเริ่มต้นคือ 10 เว้นแต่แท็ก w:docDefaults/w:rPrDefault
จะหายไป ดังนั้นจึงมีขนาด 11
การจัดตำแหน่งข้อความ
การจัดตำแหน่งข้อความระบุโดยแท็ก <w:jc>
ที่มีโหมด w:val
สี่โหมด: "left"
, "center"
, "right"
และ "both"
"left"
เป็นโหมดเริ่มต้น ข้อความเริ่มต้นที่ด้านซ้ายของสี่เหลี่ยมผืนผ้าย่อหน้า (โดยปกติคือความกว้างของหน้า) (ย่อหน้านี้จัดชิดซ้ายซึ่งเป็นมาตรฐาน)
โหมด "center"
คาดเดาได้ว่าจะจัดอักขระทั้งหมดให้อยู่กึ่งกลางภายในความกว้างของหน้า (อีกครั้ง ย่อหน้านี้แสดงตัวอย่างการจัดตำแหน่งกึ่งกลาง)
ในโหมด "right"
ข้อความย่อหน้าจะจัดชิดขอบขวา (สังเกตว่าข้อความนี้จัดชิดขวาอย่างไร)
โหมด "both"
เพิ่มระยะห่างพิเศษระหว่างคำเพื่อให้บรรทัดกว้างขึ้นและใช้ความกว้างของย่อหน้าเต็ม ยกเว้นบรรทัดสุดท้ายที่จัดชิดซ้าย (ย่อหน้านี้เป็นการสาธิตสิ่งนั้น)
รูปภาพ
DOCX รองรับรูปภาพสองประเภท: แบบอินไลน์และแบบลอย
รูปภาพในบรรทัดจะปรากฏภายในย่อหน้าพร้อมกับอักขระอื่นๆ <w:drawing>
จะใช้แทนการใช้ <w:t>
(ข้อความ) คุณสามารถค้นหา ID รูปภาพด้วยไวยากรณ์ xpath ต่อไปนี้:
w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip/@r:embed
รหัสรูปภาพใช้สำหรับค้นหาชื่อไฟล์ในไฟล์ word/_rels/document.xml.rels
และควรชี้ไปที่ไฟล์ gif/jpeg ภายในโฟลเดอร์ย่อย word/media (ดูไฟล์ word/_rels/document.xml.rels
ของโปรเจ็กต์ github ซึ่งคุณสามารถดู ID รูปภาพได้)
รูปภาพลอยตัวจะวางสัมพันธ์กับย่อหน้าที่มีข้อความวนเวียนอยู่รอบๆ (นี่คือเอกสารตัวอย่างโปรเจ็กต์ github ที่มีรูปภาพลอยตัว)
รูปภาพลอยตัวใช้ <wp:anchor>
แทน <w:drawing>
ดังนั้นหากคุณลบข้อความใด ๆ ภายใน <w:p>
โปรดใช้ความระมัดระวังกับจุดยึดหากคุณไม่ต้องการให้ลบรูปภาพ
โต๊ะ
แท็ก XML สำหรับตารางคล้ายกับมาร์กอัปตาราง HTML– ตรงกับ <tr> เป็นต้น
<w:tbl>
ตัวตารางมีคุณสมบัติตาราง <w:tblPr>
และคุณสมบัติแต่ละคอลัมน์แสดงโดย <w:gridCol>
ภายใน <w:tblGrid>
แถวต่อจากแท็ก <w:tr>
ทีละแถว และแต่ละแถวควรมีจำนวนคอลัมน์เท่ากันตามที่ระบุใน <w:tblGrid>
:
<w:tbl> <w:tblPr> <w:tblW w:w="5000" w:type="pct" /> </w:tblPr> <w:tblGrid><w:gridCol/><w:gridCol/></w:tblGrid> <w:tr> <w:tc><w:p><w:r><w:t>left</w:t></w:r></w:p></w:tc> <w:tc><w:p><w:r><w:t>right</w:t></w:r></w:p></w:tc> </w:tr> </w:tbl>
ความกว้างสำหรับคอลัมน์ตารางสามารถระบุได้ในแท็ก <w:tblW>
แต่ถ้าคุณไม่ได้กำหนดไว้ MS Word จะใช้อัลกอริธึมภายในเพื่อค้นหาความกว้างที่เหมาะสมที่สุดของคอลัมน์สำหรับขนาดตารางที่มีประสิทธิภาพที่เล็กที่สุด
หน่วย
แอตทริบิวต์ XML จำนวนมากภายใน DOCX ระบุขนาดหรือระยะทาง แม้ว่าจะเป็นจำนวนเต็มใน XML แต่ทั้งหมดก็มีหน่วยต่างกัน ดังนั้นจึงจำเป็นต้องแปลงบางส่วน หัวข้อนี้ซับซ้อนมาก ดังนั้นฉันจึงแนะนำบทความนี้โดย Lars Corneliussen เกี่ยวกับหน่วยในไฟล์ DOCX ตารางที่เขานำเสนอมีประโยชน์ แม้ว่าจะมีการพิมพ์ผิดเล็กน้อย: นิ้วควรเป็น pt/72 ไม่ใช่ pt*72
นี่คือแผ่นโกง:
การแปลงหน่วย DOCX XML ทั่วไป | ||||||
จุดที่ 20 | คะแนน dxa/20 | นิ้ว pt/72 | เซนติเมตร ใน*2,54 | ขนาดตัวอักษรครึ่ง pt/144 | EMU ใน*914400 | |
ตัวอย่าง | 11906 | 595.3 | 8,27… | 21.00086… | 4,135 | 7562088 |
แท็กโดยใช้สิ่งนี้ | pgSz/pgMar/w:ระยะห่าง | w:sz | wp:extent, a:ext |
เคล็ดลับสำหรับการใช้เลย์เอาต์
หากคุณต้องการแปลงไฟล์ DOCX (เช่น เป็น PDF) ให้วาดบนแคนวาส หรือนับจำนวนหน้า คุณจะต้องติดตั้งเลย์เอาต์ เลย์เอาต์คืออัลกอริธึมสำหรับคำนวณตำแหน่งอักขระจากไฟล์ DOCX
นี่เป็นงานที่ซับซ้อนหากคุณต้องการการเรนเดอร์ที่แม่นยำ 100 เปอร์เซ็นต์ ระยะเวลาที่จำเป็นในการติดตั้งเลย์เอาต์ที่ดีนั้นวัดกันเป็นปีชาย แต่ถ้าคุณต้องการแค่เลย์เอาต์ที่เรียบง่ายและจำกัด ก็สามารถทำได้ค่อนข้างเร็ว
เลย์เอาต์จะเติมสี่เหลี่ยมพาเรนต์ ซึ่งมักจะเป็นสี่เหลี่ยมของหน้า มันเพิ่มคำจากการทำงานทีละคำ เมื่อบรรทัดปัจจุบันล้น จะขึ้นบรรทัดใหม่ ถ้าย่อหน้าสูงเกินไปสำหรับสี่เหลี่ยมหลัก ย่อหน้านั้นจะถูกรวมไว้ในหน้าถัดไป
ต่อไปนี้คือสิ่งสำคัญบางประการที่ควรคำนึงถึงหากคุณตัดสินใจใช้เลย์เอาต์:
- เลย์เอาต์ควรดูแลเกี่ยวกับการจัดตำแหน่งข้อความและข้อความที่ลอยอยู่เหนือรูปภาพ
- มันควรจะสามารถจัดการวัตถุที่ซ้อนกัน เช่น ตารางที่ซ้อนกัน
- หากคุณต้องการให้การสนับสนุนอย่างเต็มที่สำหรับรูปภาพดังกล่าว คุณจะต้องใช้ตัวจัดวางเลย์เอาต์อย่างน้อยสองครั้ง ขั้นตอนแรกจะรวบรวมตำแหน่งของรูปภาพแบบลอย และขั้นตอนที่สองจะเติมพื้นที่ว่างด้วยอักขระข้อความ
- ระวังการเยื้องและการเว้นวรรค แต่ละย่อหน้ามีระยะห่างก่อนและหลัง และตัวเลขเหล่านี้ถูกระบุโดยแท็ก
w:spacing
ระยะห่างแนวตั้งระบุด้วยแท็กw:after
และw:before
โปรดทราบว่าการเว้นวรรคบรรทัดถูกระบุโดยw:line
แต่นี่ไม่ใช่ขนาดของบรรทัดอย่างที่คาดไว้ เพื่อให้ได้ขนาดของเส้น ให้ใช้ความสูงของฟอนต์ปัจจุบัน คูณด้วยw:line
แล้วหารด้วย 12 - ไฟล์ DOCX ไม่มีข้อมูลเกี่ยวกับการแบ่งหน้า คุณจะไม่พบจำนวนหน้าในเอกสาร เว้นแต่คุณจะคำนวณว่าคุณต้องการพื้นที่ว่างเท่าใดสำหรับแต่ละบรรทัดเพื่อยืนยันจำนวนหน้า หากคุณต้องการค้นหาพิกัดที่แน่นอนของอักขระแต่ละตัวบนหน้า อย่าลืมคำนึงถึงระยะห่าง การเยื้อง และขนาดทั้งหมดด้วย
- หากคุณใช้เลย์เอาต์ DOCX ที่มีคุณสมบัติครบถ้วนซึ่งจัดการตาราง ให้สังเกตกรณีพิเศษเมื่อตารางขยายหลายหน้า เซลล์ที่ทำให้หน้าล้นจะมีผลกับเซลล์อื่นๆ ด้วย
- การสร้างอัลกอริธึมที่เหมาะสมที่สุดสำหรับการคำนวณความกว้างของคอลัมน์ในตารางเป็นปัญหาทางคณิตศาสตร์ที่ท้าทาย และโปรแกรมประมวลผลคำและเลย์เอาต์มักจะใช้การใช้งานที่ไม่เหมาะสม ฉันเสนอให้ใช้อัลกอริทึมจากเอกสารตาราง W3C HTML เป็นการประมาณครั้งแรก ฉันไม่พบคำอธิบายของอัลกอริทึมที่ใช้โดย MS Word และ Microsoft ได้ปรับอัลกอริทึมอย่างละเอียดเมื่อเวลาผ่านไป ดังนั้น Word เวอร์ชันต่างๆ อาจจัดวางตารางแตกต่างกันเล็กน้อย
หากมีบางอย่างไม่ชัดเจน: วิศวกรรมย้อนกลับ XML!
เมื่อไม่ชัดเจนว่าแท็ก XML นี้หรือแท็กทำงานอย่างไรใน MS Word มีสองวิธีหลักในการค้นหา:
สร้างเนื้อหาที่ต้องการทีละขั้นตอน เริ่มต้นด้วยไฟล์ docx อย่างง่าย บันทึกแต่ละขั้นตอนลงในไฟล์ของตนเอง เช่น
1.docx
,2.docx
เป็นต้น เปิดเครื่องรูดแต่ละรายการและใช้เครื่องมือกระจายภาพเพื่อเปรียบเทียบโฟลเดอร์เพื่อดูว่าแท็กใดปรากฏขึ้นหลังจากการเปลี่ยนแปลงของคุณ (สำหรับตัวเลือกเชิงพาณิชย์ ให้ลองใช้ Araxis Merge หรือ WinMerge สำหรับตัวเลือกฟรี)หากคุณสร้างไฟล์ DOCX ที่ MS Word ไม่ชอบ ให้ดำเนินการย้อนกลับ ลดความซับซ้อนของ XML ของคุณทีละขั้นตอน เมื่อถึงจุดหนึ่ง คุณจะได้เรียนรู้ว่าการเปลี่ยนแปลงใดใน MS Word ที่พบว่าไม่ถูกต้อง
DOCX ค่อนข้างซับซ้อนใช่ไหม
มีความซับซ้อน และใบอนุญาตของ Microsoft ห้ามมิให้ใช้ MS Word ที่ฝั่งเซิร์ฟเวอร์สำหรับการประมวลผล DOCX ซึ่งเป็นมาตรฐานที่ค่อนข้างดีสำหรับผลิตภัณฑ์เชิงพาณิชย์ อย่างไรก็ตาม Microsoft ได้จัดเตรียมไฟล์ XSLT เพื่อจัดการกับแท็ก DOCX ส่วนใหญ่ แต่จะไม่ให้ความถูกต้อง 100 เปอร์เซ็นต์หรือ 99 เปอร์เซ็นต์แก่คุณ ไม่รองรับกระบวนการต่างๆ เช่น การตัดข้อความบนรูปภาพ แต่คุณจะสามารถรองรับเอกสารส่วนใหญ่ได้ (หากคุณไม่ต้องการความซับซ้อน ให้พิจารณาใช้ Markdown เป็นทางเลือก)
หากคุณมีงบประมาณเพียงพอ (ไม่มีเครื่องมือแสดงผล DOCX ฟรี) คุณอาจต้องการใช้ผลิตภัณฑ์เชิงพาณิชย์ เช่น Aspose หรือ docx4j โซลูชันฟรีที่ได้รับความนิยมมากที่สุดคือ LibreOffice สำหรับการแปลงระหว่าง DOCX และรูปแบบอื่นๆ รวมถึง PDF น่าเสียดายที่ LibreOffice มีจุดบกพร่องเล็กๆ มากมายระหว่างการแปลง และเนื่องจากเป็นผลิตภัณฑ์ C++ แบบโอเพ่นซอร์สที่ซับซ้อน จึงแก้ไขปัญหาความเที่ยงตรงได้ช้าและยาก
อีกทางหนึ่ง หากคุณพบว่าการจัดวาง DOCX ซับซ้อนเกินกว่าจะปรับใช้ด้วยตัวเอง คุณยังสามารถแปลงเป็น HTML และใช้เบราว์เซอร์เพื่อแสดงผลได้ คุณยังสามารถพิจารณาหนึ่งในนักพัฒนา XML อิสระของ Toptal ได้อีกด้วย
แหล่งข้อมูล DOCX สำหรับการอ่านเพิ่มเติม
- ข้อกำหนด ECMA DOCX
- ไลบรารี OpenXML สำหรับการจัดการ DOCX จาก C # ไม่มีข้อมูลเกี่ยวกับการจัดวางหรือโค้ดการแสดงผล แต่มีลำดับชั้นของคลาสที่ตรงกับโหนด XML ที่เป็นไปได้แต่ละรายการใน DOCX
- คุณสามารถค้นหาหรือถามใน stackoverflow ด้วยคำหลักเช่น docx4j, OpenXML และ docx; มีคนในชุมชนที่มีความรู้