Criação, edição e análise de DOCX
Um .docx é um arquivo ZIP contendo arquivos XML. Escolha sua abordagem conforme a tarefa:
| Tarefa | Abordagem |
|---|---|
| Criar um novo documento | Escreva um script docx (npm) — veja as pegadinhas abaixo |
| Editar um documento existente | unzip → edite word/document.xml → zip (docx-js não consegue abrir arquivos existentes) |
| Ler conteúdo | pandoc -t markdown file.docx |
Os caminhos de script abaixo são relativos ao diretório desta habilidade.
Criando com docx-js — pegadinhas
docx está pré-instalado — não execute npm install primeiro; escreva o script e use require('docx') diretamente. Apenas se esse require falhar: npm install docx. O modelo conhece a API; estas são as armadilhas:
- O tamanho da página padrão é A4. Para Carta (EUA), defina
page: { size: { width: 12240, height: 15840 } }(DXA; 1440 = 1″). - Paisagem: passe as dimensões retrato e
orientation: PageOrientation.LANDSCAPE— o docx-js troca largura/altura internamente. - Tabelas precisam de larguras duplas: defina
columnWidthsna tabela Ewidthem cada célula, ambos emWidthType.DXA(PERCENTAGE quebra no Google Docs). As larguras das colunas devem somar a largura da tabela. - Sombreamento de tabela: use
ShadingType.CLEAR, nuncaSOLID(renderiza preto). - Listas: nunca insira
•literalmente; use uma configuraçãonumberingcomLevelFormat.BULLET. ImageRunrequertype:("png","jpg", …).PageBreakdeve estar dentro de umParagraph.- Nunca use
\n— use elementosParagraphseparados. - SUMÁRIO (TOC): os títulos devem usar
HeadingLevel.*embutidos; estilos de título personalizados precisam deoutlineLeveldefinido ou não aparecerão. - Não use uma tabela como linha horizontal — use uma borda inferior de parágrafo.
- Pontilhado / alinhado à direita na mesma linha: use
PositionalTab(alignment: PositionalTabAlignment.RIGHT,leader: PositionalTabLeader.DOT) dentro de umTextRun, não pontos.literais ou espaçamento.
Verifique a saída
Após escrever um .docx, renderize-o e veja-o:
python scripts/office/soffice.py --headless --convert-to pdf output.docx
pdftoppm -jpeg -r 100 output.pdf page
ls page-*.jpg # em seguida, Leia as imagens
pdftoppm preenche com zeros os números de página até a largura da contagem de páginas (page-01.jpg…page-12.jpg).
Editando documentos existentes
Documentos .doc legados devem ser convertidos primeiro: python scripts/office/soffice.py --headless --convert-to docx file.doc.
unzip -q doc.docx -d unpacked/
find unpacked -type l -delete # remove entradas de link simbólico — docx de fontes externas não é confiável
python scripts/merge_runs.py unpacked/ # coalesce execuções fragmentadas para que o texto seja encontrável
# edite unpacked/word/document.xml no local — NÃO reformate ou prettifique
(cd unpacked && rm -f ../out.docx && zip -Xr ../out.docx .)
python scripts/office/validate.py out.docx --original doc.docx # verificações XSD; --auto-repair corrige problemas comuns
# redlining? adicione --author "<o nome sob o qual você fez o redline>" para verificar se cada edição está rastreada
O Word divide o texto em muitas execuções <w:r> (IDs de revisão, marcadores de verificação ortográfica), então uma frase que você vê no documento muitas vezes não existe como uma string contígua no XML. merge_runs.py mescla execuções adjacentes com formatação idêntica em word/document.xml sem alterar conteúdo ou renderização; ele também aceita um .docx diretamente (python scripts/merge_runs.py doc.docx -o merged.docx).
Controle de alterações: ao fazer redlining, valide com --author "<o nome sob o qual você fez o redline>" (precisa de --original) — ele relata qualquer texto que você alterou sem um <w:ins>/<w:del> ao redor, o que é fácil de acontecer acidentalmente e invisível na visualização de aceitação. Envolva as execuções em <w:ins>/<w:del> com atributos w:id, w:author, w:date. Dentro de <w:del>, o elemento de texto é <w:delText>, não <w:t>. Uma marca de parágrafo deletada (<w:pPr><w:rPr><w:del w:id=".." w:author=".." w:date=".."/></w:rPr></w:pPr>) significa "mesclar este parágrafo no próximo" — então deletar um parágrafo por completo é isso mais um <w:del> em torno de cada execução. O <w:del/> deve vir antes dos outros filhos do rPr; sua ordem é imposta pelo esquema.
Para produzir uma cópia limpa com todas as alterações aceitas: python scripts/accept_changes.py in.docx out.docx.
Aceitar uma marca de parágrafo deletada deve juntar esse parágrafo ao abaixo dele, então um parágrafo cujas execuções são todas deletadas desaparece. O Word faz isso; accept_changes.py e pandoc --track-changes=accept nem sempre. Ambos falham da mesma forma — eles removem o texto deletado, mas deixam o parágrafo vazio, que aparece como um marcador vazio perdido quando era numerado automaticamente:
pandoc --track-changes=acceptnunca junta os parágrafos.accept_changes.py(LibreOffice) os junta corretamente, exceto quando o parágrafo deletado é seguido por um parágrafo espaçador vazio.
Um marcador vazio em qualquer visualização é um artefato dessa visualização, não um defeito no documento. Verifique as exclusões de parágrafo no XML.
Comentários
Comentários exigem seis arquivos vinculados entre si. Use o helper — modo diretório quando você também for editar document.xml (economiza um ciclo de unzip/rezip), modo .docx direto caso contrário:
# Contra um diretório já descompactado (preferido ao também colocar marcadores)
python scripts/comment.py unpacked/ "O limite de taxas e despesas é muito baixo"
python scripts/comment.py unpacked/ "Concordo" --parent 0
# Contra um .docx diretamente
python scripts/comment.py contract.docx "Este limite é muito baixo" -o annotated.docx
O script escreve comments.xml, commentsExtended.xml, commentsIds.xml, commentsExtensible.xml, os relacionamentos e as substituições de tipo de conteúdo. Os IDs de comentários são atribuídos automaticamente. Em seguida, ele imprime o trecho <w:commentRangeStart>/<w:commentRangeEnd>/<w:commentReference> a ser adicionado em word/document.xml para que o comentário ancore em texto específico — até que você coloque esses marcadores, o comentário existe mas não fica visível.
Dependências
docx (npm, pré-instalado — instale apenas se require('docx') falhar) · pandoc · LibreOffice (soffice) · pdftoppm (Poppler)