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 armadilhas 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 dos scripts abaixo são relativos ao diretório desta habilidade.
Criando com docx-js — armadilhas
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 pegadinhas:
- O tamanho da página padrão é A4. Para Carta dos EUA, defina
page: { size: { width: 12240, height: 15840 } }(DXA; 1440 = 1″). - Paisagem: passe dimensões de retrato e
orientation: PageOrientation.LANDSCAPE— 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 à largura da tabela. - Sombreamento de tabela: use
ShadingType.CLEAR, nuncaSOLID(renderiza preto). - Listas: nunca insira
•literalmente; use uma configuração denumberingcomLevelFormat.BULLET. ImageRunrequertype:("png","jpg", …).PageBreakdeve estar dentro de umParagraph.- Nunca use
\n— use elementosParagraphseparados. - Sumário: os títulos devem usar
HeadingLevel.*internos; 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.
- Linha pontilhada / 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 visualize-o:
python scripts/office/soffice.py --headless --convert-to pdf output.docx
pdftoppm -jpeg -r 100 output.pdf page
ls page-*.jpg # então Leia as imagens
pdftoppm preenche com zeros à esquerda os números de página na largura da contagem de páginas (page-01.jpg…page-12.jpg).
Editando documentos existentes
Arquivos .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 terceiros não é confiável
python scripts/merge_runs.py unpacked/ # mescla execuções fragmentadas para que o texto seja localizável
# edite unpacked/word/document.xml no lugar — NÃO reformate nem prettify
(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
# controle de alterações? adicione --author "<o nome sob o qual você fez as alterações>" para verificar se cada edição está rastreada
O Word divide o texto em várias execuções <w:r> (IDs de revisão, marcadores de verificação ortográfica), portanto 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).
Alterações controladas: ao usar controle de alterações, valide com --author "<o nome sob o qual você fez as alterações>" (precisa de --original) — ele relata qualquer texto alterado sem um <w:ins>/<w:del> ao redor, o que é fácil de fazer acidentalmente e invisível na visualização aceita. Envolva 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" — portanto, 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; a ordem é imposta pelo esquema.
Para produzir uma cópia limpa com todas as alterações controladas aceitas: python scripts/accept_changes.py in.docx out.docx.
Aceitar uma marca de parágrafo deletada deve unir esse parágrafo ao que está 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 funcionam. Ambos falham da mesma forma — eles removem o texto deletado, mas deixam o parágrafo vazio para trás, que aparece como um marcador vazio perdido quando era numerado automaticamente:
pandoc --track-changes=acceptnunca une os parágrafos.accept_changes.py(LibreOffice) une-os 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 exclusões de parágrafos no XML.
Comentários
Comentários exigem seis arquivos interligados. Use o auxiliar — modo diretório quando você também for editar document.xml (economiza um ciclo de descompactar/recompactar), modo .docx direto caso contrário:
# Contra um diretório já descompactado (preferido quando também estiver colocando 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 dos comentários são atribuídos automaticamente. Em seguida, ele imprime o trecho <w:commentRangeStart>/<w:commentRangeEnd>/<w:commentReference> para adicionar a word/document.xml para que o comentário seja ancorado a um 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)