--- name: docx description: "Criacao, edicao e analise de documentos Word (.docx). Usar quando o utilizador mencionar \"Word\", \".docx\", ou pedir documentos profissionais com formatacao (indices, cabecalhos, numeracao de paginas, letterheads). Inclui extracao de conteudo, insercao/substituicao de imagens, find-and-replace, tracked changes, comentarios, e conversao de conteudo para Word. Aplica-se a relatorios, memorandos, cartas, templates e propostas em formato .docx. NAO usar para PDFs, folhas de calculo, Google Docs, ou tarefas de codigo nao relacionadas." layer: wiki --- # Criacao, edicao e analise de documentos DOCX ## Visao geral Um ficheiro .docx e um arquivo ZIP contendo ficheiros XML. ## Referencia rapida | Tarefa | Abordagem | |--------|-----------| | Ler/analisar conteudo | `pandoc` ou descompactar para XML bruto | | Criar novo documento | Usar `docx-js` - ver seccao Criar Novos Documentos | | Editar documento existente | Descompactar -> editar XML -> recompactar - ver seccao Editar Documentos Existentes | ### Converter .doc para .docx Ficheiros legacy `.doc` devem ser convertidos antes de editar: ```bash python scripts/office/soffice.py --headless --convert-to docx document.doc ``` ### Ler conteudo ```bash # Extracao de texto com tracked changes pandoc --track-changes=all document.docx -o output.md # Acesso ao XML bruto python scripts/office/unpack.py document.docx unpacked/ ``` ### Converter para imagens ```bash python scripts/office/soffice.py --headless --convert-to pdf document.docx pdftoppm -jpeg -r 150 document.pdf page ``` ### Aceitar tracked changes Para produzir um documento limpo com todas as alteracoes aceites (requer LibreOffice): ```bash python scripts/accept_changes.py input.docx output.docx ``` --- ## Criar novos documentos Gerar ficheiros .docx com JavaScript, depois validar. Instalacao: `npm install -g docx` ### Setup ```javascript const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, ImageRun, Header, Footer, AlignmentType, PageOrientation, LevelFormat, ExternalHyperlink, TableOfContents, HeadingLevel, BorderStyle, WidthType, ShadingType, VerticalAlign, PageNumber, PageBreak } = require('docx'); const doc = new Document({ sections: [{ children: [/* conteudo */] }] }); Packer.toBuffer(doc).then(buffer => fs.writeFileSync("doc.docx", buffer)); ``` ### Validacao Apos criar o ficheiro, validar. Se a validacao falhar, descompactar, corrigir o XML e recompactar. ```bash python scripts/office/validate.py doc.docx ``` ### Tamanho da pagina ```javascript // CRITICO: docx-js assume A4 por defeito // Definir sempre o tamanho da pagina explicitamente para resultados consistentes // Para documentos PT/EU, A4 e o padrao correcto sections: [{ properties: { page: { size: { width: 11906, // A4: 210mm em DXA height: 16838 // A4: 297mm em DXA }, margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 } // 1 polegada de margens } }, children: [/* conteudo */] }] ``` **Tamanhos de pagina comuns (unidades DXA, 1440 DXA = 1 polegada):** | Papel | Largura | Altura | Largura conteudo (margens 1") | |-------|---------|--------|-------------------------------| | A4 (padrao PT/EU) | 11.906 | 16.838 | 9.026 | | US Letter | 12.240 | 15.840 | 9.360 | **Orientacao paisagem:** docx-js troca largura/altura internamente, por isso passar dimensoes retrato e deixar a biblioteca tratar: ```javascript size: { width: 11906, // Passar lado CURTO como width height: 16838, // Passar lado LONGO como height orientation: PageOrientation.LANDSCAPE // docx-js troca no XML }, // Largura de conteudo = 16838 - margem esquerda - margem direita (usa o lado longo) ``` ### Estilos (Override Built-in Headings) Usar Arial como fonte por defeito (suporte universal). Manter titulos a preto para legibilidade. ```javascript const doc = new Document({ styles: { default: { document: { run: { font: "Arial", size: 24 } } }, // 12pt por defeito paragraphStyles: [ // IMPORTANTE: Usar IDs exactos para override dos estilos built-in { id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true, run: { size: 32, bold: true, font: "Arial" }, paragraph: { spacing: { before: 240, after: 240 }, outlineLevel: 0 } }, // outlineLevel necessario para TOC { id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true, run: { size: 28, bold: true, font: "Arial" }, paragraph: { spacing: { before: 180, after: 180 }, outlineLevel: 1 } }, ] }, sections: [{ children: [ new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun("Titulo")] }), ] }] }); ``` ### Listas (NUNCA usar bullets unicode) ```javascript // ERRADO - nunca inserir caracteres de bullet manualmente new Paragraph({ children: [new TextRun("* Item")] }) // MAU new Paragraph({ children: [new TextRun("\u2022 Item")]