DOCX에 대한 비공식 소개

게시 됨: 2022-03-11

약 10억 명이 Microsoft Office를 사용하고 있는 DOCX 형식은 사무실 간에 문서 파일을 교환하는 데 가장 널리 사용되는 사실상의 표준입니다. 가장 가까운 경쟁자인 ODT 형식은 Open/LibreOffice 및 일부 오픈 소스 제품에서만 지원되므로 표준과는 거리가 멀습니다. PDF 형식은 경쟁자가 아닙니다. PDF는 편집할 수 없고 전체 문서 구조를 포함하지 않기 때문에 워터마크, 서명 등과 같은 제한된 로컬 변경만 수행할 수 있기 때문입니다. 이것이 대부분의 비즈니스 문서가 DOCX 형식으로 생성되는 이유입니다. 그것을 대체할 좋은 대안이 없습니다.

DOCX는 복잡한 형식이지만 인덱싱, TXT로 변환 및 기타 작은 수정과 같은 간단한 작업을 위해 수동으로 구문 분석할 수 있습니다. 5,000페이지에 달하는 방대한 매뉴얼인 ECMA 사양을 참조할 필요가 없도록 DOCX 내부에 대한 충분한 정보를 제공하고 싶습니다.

형식을 이해하는 가장 좋은 방법은 MSWord로 간단한 한 단어 문서를 만들고 문서를 편집하면 기본 XML이 어떻게 변경되는지 관찰하는 것입니다. DOCX가 MS Word에서 제대로 형식을 지정하지 않고 이유를 모르는 경우가 있거나 원하는 형식을 생성하는 방법이 명확하지 않은 경우가 있습니다. XML에서 무슨 일이 일어나고 있는지 정확히 보고 이해하면 도움이 될 것입니다.

저는 협업 DOCX 편집기인 CollabOffice에서 약 1년 동안 일했으며 그 지식 중 일부를 개발자 커뮤니티와 공유하고 싶습니다. 이 기사에서는 인터넷에 흩어져 있는 정보를 요약하여 DOCX 파일 구조에 대해 설명합니다. 이 기사는 거대하고 복잡한 ECMA 사양과 현재 사용 가능한 간단한 인터넷 자습서 사이의 중개자입니다. 내 github 계정의 toptal-docx 프로젝트에서 이 기사와 함께 제공되는 파일을 찾을 수 있습니다.

간단한 DOCX 파일

DOCX 파일은 XML 파일의 ZIP 아카이브입니다. 비어 있는 새 Microsoft Word 문서를 만들고 내부에 'Test'라는 단어를 쓰고 내용의 압축을 풀면 다음 파일 구조가 표시됩니다.

우리의 새로운 테스트 DOCX 구조.

간단한 문서를 만들었지만 Microsoft Word의 저장 프로세스에서는 기본 테마, 문서 속성, 글꼴 테이블 등을 XML 형식으로 생성했습니다.

DOCX 내부의 모든 파일은 확장자가 ".rel"인 경우에도 XML 파일입니다.
트위터

시작하려면 사용하지 않는 항목을 제거하고 주요 텍스트 요소가 포함된 document.xml 에 집중하겠습니다. 파일을 삭제할 때 다른 xml 파일에서 해당 파일에 대한 모든 관계 참조를 삭제했는지 확인하십시오. 다음은 app.xml 및 core.xml에 대한 종속성을 제거한 방법에 대한 code-diff 예제입니다. 해결되지 않은/누락된 참조가 있는 경우 MSWord는 파일이 손상된 것으로 간주합니다.

다음은 단순화된 최소 DOCX 문서의 구조입니다(여기에 github의 프로젝트가 있습니다).

단순화된 DOCX 구조.

여기에서 위에서부터 파일별로 분류해 보겠습니다.

_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>

문서.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: <w:body> > 내에 중첩된 것은 <w:sectPr> 에 의해 정의된 페이지 차원입니다.

<w:rsidR> 은 무시할 수 있는 속성입니다. MS Word 내부에서 사용됩니다.

세 단락으로 구성된 더 복잡한 문서를 살펴보겠습니다. 상관 관계를 볼 수 있도록 Microsoft Word의 스크린샷에서 동일한 색상으로 XML을 강조 표시했습니다.

스타일링이 포함된 복잡한 단락 예제.

<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="보존">, </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> 및 boldness <w:b> 를 지정합니다.

주목해야 할 중요한 점은 속성이 일반 문자와 복합 문자(예: 아랍어)의 두 문자 그룹을 구별하고 속성이 영향을 미치는 문자 유형에 따라 다른 태그를 갖는다는 것입니다.

대부분의 일반 스크립트 속성 태그에는 복합 스크립트용 속성임을 지정하는 "C"가 추가된 일치하는 복합 스크립트 태그가 있습니다. 예: <w:i> (기울임꼴)는 <w:iCs> 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 에서 스타일 속성을 참조할 수 있습니다. /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/* 로 시작합니다. 캐릭터 속성의 최종 결과를 얻으려면 다음을 수행해야 합니다.

  1. 기본 실행/단락 속성 사용
  2. 실행/단락 스타일 속성 추가
  3. 로컬 실행/단락 속성 추가
  4. 단락 속성에 결과 실행 속성 추가

B를 A에 "추가"한다고 말하면 모든 B 속성을 반복하고 모든 A의 속성을 재정의하여 교차하지 않는 모든 속성을 있는 그대로 두는 것을 의미합니다.

기본 속성이 위치할 수 있는 또 다른 위치는 w:type="paragraph"w:default="1"<w:style> 태그입니다. 실행 내부의 문자 자체에는 기본 스타일이 없으므로 <w:style w:type="character" w:default="1"> 는 실제로 텍스트에 영향을 미치지 않습니다.

트위터

실행의 문자는 단락에서 상속할 수 있으며 둘 다 styles.xml에서 상속할 수 있습니다.

1554402290400-dbb29eef3ba6035df7ad726dfc99b2af.png)

실행의 문자는 단락에서 상속할 수 있으며 둘 다 styles.xml에서 상속할 수 있습니다.

속성 전환

일부 속성은 <w:b> (굵게) 또는 <w:i> (기울임꼴)와 같은 "토글" 속성입니다. 이러한 속성은 XOR 연산자처럼 작동합니다.

즉, 상위 스타일이 굵게 표시되고 하위 실행이 굵게 표시되면 결과는 굵게 표시되지 않은 일반 텍스트가 됩니다.

토글 속성을 올바르게 처리하려면 많은 테스트와 리버스 엔지니어링을 수행해야 합니다. 토글 속성/

토글 속성은 레이아웃이 올바르게 처리하기 위해 가장 복잡합니다.
트위터

글꼴

글꼴은 다른 텍스트 속성과 동일한 공통 규칙을 따르지만 글꼴 속성 기본값은 다음과 같이 word/_rels/document.xml.rels 에서 참조되는 별도의 테마 파일에 지정됩니다.

 <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>

위의 참조를 기반으로 기본 글꼴 이름은 <a:theme> 태그, a:themeElements/a:fontScheme/a:majorFont 또는 a:minorFont 태그 안에 있는 word/theme/themes1.xml 에서 찾을 수 있습니다.

w:docDefaults/w:rPrDefault 태그가 없으면 기본 글꼴 크기는 10이고 크기는 11입니다.

텍스트 정렬

텍스트 정렬은 "left" , "center" , "right""both" 등 4가지 w:val 모드를 사용할 수 있는 <w:jc> 태그로 지정됩니다.

"left" 은 기본 모드입니다. 텍스트는 단락 사각형의 왼쪽(일반적으로 페이지 너비)에서 시작됩니다. (이 단락은 왼쪽으로 정렬되어 표준입니다.)

"center" 모드는 예상대로 페이지 너비 내에서 모든 문자를 중앙에 배치합니다. (다시 말하지만, 이 단락은 가운데 정렬을 예시합니다.)

"right" 모드에서 단락 텍스트는 오른쪽 여백에 맞춰 정렬됩니다. (이 텍스트가 오른쪽에 어떻게 정렬되어 있는지 주목하십시오.)

"both" 모드는 왼쪽 정렬된 마지막 줄을 제외하고 줄이 더 넓어지고 전체 단락 너비를 차지하도록 단어 사이에 추가 공백을 넣습니다. (이 단락은 그 증거입니다.)

이미지

DOCX는 인라인과 부동의 두 가지 이미지를 지원합니다.

인라인 이미지는 다른 문자와 함께 단락 내부에 나타나며 <w:t> (텍스트) 대신 <w:drawing> 을 사용합니다. 다음 xpath 구문으로 이미지 ID를 찾을 수 있습니다.

w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip/@r:embed

이미지 ID는 word/_rels/document.xml.rels 파일에서 파일 이름을 찾는 데 사용되며 word/media 하위 폴더 내의 gif/jpeg 파일을 가리켜야 합니다. (이미지 ID를 볼 수 있는 github 프로젝트의 word/_rels/document.xml.rels 파일을 참조하세요.)

플로팅 이미지는 텍스트가 주위에 흐르는 단락을 기준으로 배치됩니다. (플로팅 이미지가 있는 github 프로젝트 샘플 문서는 다음과 같습니다.)

플로팅 이미지는 <w:drawing> <wp:anchor> 를 사용하므로 <w:p> 내부의 텍스트를 삭제하는 경우 이미지를 제거하지 않으려면 앵커에 주의하세요.

인라인 대 부동.

MS Word의 이미지 옵션은 이미지 정렬을 "텍스트 줄 바꿈 모드"라고 합니다.

테이블

테이블에 대한 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는 내부 알고리즘을 사용하여 가장 작은 유효 테이블 크기에 대한 최적의 열 너비를 찾습니다.

단위

DOCX 내부의 많은 XML 속성은 크기 또는 거리를 지정합니다. XML 내부의 정수이지만 모두 다른 단위를 가지므로 약간의 변환이 필요합니다. 주제는 복잡한 주제이므로 DOCX 파일의 단위에 대한 Lars Corneliussen의 이 기사를 추천합니다. 그가 제시한 표는 약간 잘못 인쇄되어 있지만 유용합니다. 인치는 pt*72가 아니라 pt/72여야 합니다.

다음은 치트 시트입니다.

공통 DOCX XML 단위 변환
20번째 포인트 포인트들
dxa/20
신장
pt/72
센티미터
in*2,54
글꼴 절반 크기
pt/144
에뮤
*914400에서
예시 11906 595.3 8,27… 21.00086… 4,135 7562088
이것을 사용하는 태그 pgSz/pgMar/w:간격 w:sz wp:extent, a:ext

레이아웃터 구현을 위한 팁

DOCX 파일(예: PDF로)을 변환하거나 캔버스에 그리거나 페이지 수를 계산하려면 레이아웃기를 구현해야 합니다. 레이아웃어는 DOCX 파일에서 문자 위치를 계산하기 위한 알고리즘입니다.

100% 충실도 렌더링이 필요한 경우 이는 복잡한 작업입니다. 좋은 레이아웃을 구현하는 데 필요한 시간은 man-years로 측정되지만 간단하고 제한된 레이아웃만 필요한 경우 비교적 빠르게 완료할 수 있습니다.

레이아웃기는 일반적으로 페이지의 직사각형인 부모 직사각형을 채웁니다. 실행에서 단어를 하나씩 추가합니다. 현재 줄이 오버플로되면 새 줄을 시작합니다. 단락이 부모 사각형에 비해 너무 높으면 다음 페이지로 줄 바꿈됩니다.

다음은 레이아웃자를 구현하기로 결정한 경우 염두에 두어야 할 몇 가지 중요한 사항입니다.

  • 레이아웃자는 이미지 위에 떠 있는 텍스트 정렬 및 텍스트를 처리해야 합니다.
  • 중첩 테이블과 같은 중첩 개체를 처리할 수 있어야 합니다.
  • 이러한 이미지에 대한 완전한 지원을 제공하려면 최소 2개의 패스로 레이아웃기를 구현해야 합니다. 첫 번째 단계는 부동 이미지의 위치를 ​​수집하고 두 번째 단계는 텍스트 문자로 빈 공간을 채웁니다.
  • 들여쓰기와 띄어쓰기에 주의하세요. 각 단락에는 앞뒤에 간격이 있으며 이러한 숫자는 w:spacing 태그로 지정됩니다. 세로 간격은 w:afterw:before 태그로 지정됩니다. 줄 간격은 w:line 에 의해 지정되지만 예상할 수 있는 줄의 크기가 아닙니다. 줄의 크기를 얻으려면 현재 글꼴 높이에 w:line 을 곱하고 12로 나눕니다.
  • DOCX 파일에는 페이지 매김에 대한 정보가 포함되어 있지 않습니다. 페이지 수를 확인하기 위해 각 행에 필요한 공간을 계산하지 않는 한 문서의 페이지 수를 찾을 수 없습니다. 페이지에서 각 문자의 정확한 좌표를 찾아야 하는 경우 모든 간격, 들여쓰기 및 크기를 고려해야 합니다.
  • 테이블을 처리하는 완전한 기능을 갖춘 DOCX 레이아웃을 구현하는 경우 테이블이 여러 페이지에 걸쳐 있는 특수한 경우에 유의하십시오. 페이지 오버플로를 일으키는 셀은 다른 셀에도 영향을 줍니다.
  • 테이블 열의 너비를 계산하기 위한 최적의 알고리즘을 만드는 것은 어려운 수학 문제이며 워드 프로세서와 레이아웃 작성자는 일반적으로 일부 차선책 구현을 사용합니다. W3C HTML 테이블 문서의 알고리즘을 첫 번째 근사값으로 사용할 것을 제안합니다. MS Word에서 사용하는 알고리즘에 대한 설명을 찾지 못했고 Microsoft는 시간이 지남에 따라 알고리즘을 미세 조정하여 Word 버전에 따라 표를 약간 다르게 배치할 수 있습니다.

명확하지 않은 경우: XML을 리버스 엔지니어링하십시오!

이 또는 저 XML 태그가 MS Word 내에서 어떻게 작동하는지 명확하지 않은 경우 이를 파악하는 두 가지 주요 접근 방식이 있습니다.

  • 원하는 콘텐츠를 단계별로 생성합니다. 간단한 docx 파일로 시작하십시오. 예를 들어 1.docx , 2.docx 와 같이 각 단계를 자체 파일에 저장합니다. 각각의 압축을 풀고 폴더 비교를 위해 시각적 diff 도구를 사용하여 변경 후 어떤 태그가 나타나는지 확인합니다. (상업적 옵션의 경우 Araxis Merge를, 무료 옵션의 경우 WinMerge를 시도하십시오.)

  • MS Word가 좋아하지 않는 DOCX 파일을 생성하면 거꾸로 작업하십시오. XML을 단계별로 단순화하십시오. 어느 시점에서 MS Word가 잘못 발견한 변경 사항을 알게 될 것입니다.

DOCX는 상당히 복잡하지 않습니까?

그것은 복잡하고 Microsoft의 라이선스는 DOCX 처리를 위해 서버 측에서 MS Word를 사용하는 것을 금지합니다. 이는 상용 제품의 표준입니다. 그러나 Microsoft는 대부분의 DOCX 태그를 처리하기 위해 XSLT 파일을 제공했지만 100% 또는 99%의 충실도를 제공하지는 않습니다. 이미지 위에 텍스트 줄 바꿈과 같은 프로세스는 지원되지 않지만 대부분의 문서를 지원할 수 있습니다. (복잡성이 필요하지 않다면 Markdown을 대안으로 사용하는 것을 고려하십시오.)

예산이 충분하다면(무료 DOCX 렌더링 엔진이 없음) Aspose 또는 docx4j와 같은 상용 제품을 사용하는 것이 좋습니다. 가장 인기 있는 무료 솔루션은 DOCX와 PDF를 포함한 다른 형식 간의 변환을 위한 LibreOffice입니다. 불행히도 LibreOffice는 변환하는 동안 많은 작은 버그를 포함하고 있으며 정교한 오픈 소스 C++ 제품이기 때문에 정확도 문제를 해결하는 데 느리고 어렵습니다.

또는 DOCX 레이아웃이 너무 복잡하여 스스로 구현하기 어렵다면 HTML로 변환하고 브라우저를 사용하여 렌더링할 수도 있습니다. Toptal의 프리랜스 XML 개발자 중 한 명을 고려할 수도 있습니다.

추가 읽기를 위한 DOCX 리소스

  • ECMA DOCX 사양
  • C#에서 DOCX 조작을 위한 OpenXML 라이브러리. 코드 레이아웃 또는 렌더링에 대한 정보는 포함되어 있지 않지만 DOCX에서 가능한 각 XML 노드와 일치하는 클래스 계층 구조를 제공합니다.
  • docx4j, OpenXML 및 docx와 같은 키워드를 사용하여 언제든지 stackoverflow를 검색하거나 요청할 수 있습니다. 지역 사회에 지식이 있는 사람들이 있습니다.