← Volver al directorio
Skill GLOBAL es

DOCX Document Processing

Crea, lee, edita y genera documentos Word (.docx) con formato profesional: tablas de contenido, encabezados, pie de página, listas, tablas, imágenes, hipervínculos, notas a pie, cambios controlados y comentarios.

Contenido completo

--- name: docx description: Use this skill for any Word document (.docx) task — creating new documents, reading/editing existing ones, tracked changes, comments, tables, images, TOC, headers/footers. Trigger on any mention of "Word", ".docx", or requests to produce a report/memo/letter as a .docx file. --- # DOCX Processing ## Creating New Documents (JavaScript — docx library) ```bash npm install -g docx ``` ```javascript const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, ImageRun, Header, Footer, AlignmentType, PageOrientation, ExternalHyperlink, InternalHyperlink, Bookmark, FootnoteReferenceRun, TabStopType, TabStopPosition, PositionalTab, PositionalTabAlignment, PositionalTabRelativeTo, PositionalTabLeader, TableOfContents, HeadingLevel, BorderStyle, WidthType, ShadingType, PageNumber, PageBreak, LevelFormat, SectionType, Column } = require('docx'); const fs = require('fs'); const doc = new Document({ sections: [{ children: [/* content */] }] }); Packer.toBuffer(doc).then(buf => fs.writeFileSync("doc.docx", buf)); ``` ### Page Size (CRITICAL — defaults to A4) ```javascript sections: [{ properties: { page: { size: { width: 12240, height: 15840 }, // US Letter (DXA: 1440 = 1 inch) margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 } } }, children: [/* ... */] }] // Landscape: pass portrait dims, let docx swap size: { width: 12240, height: 15840, orientation: PageOrientation.LANDSCAPE } ``` | Paper | Width | Height | Content Width (1" margins) | |-------|-------|--------|---------------------------| | US Letter | 12,240 | 15,840 | 9,360 | | A4 | 11,906 | 16,838 | 9,026 | ### Styles ```javascript const doc = new Document({ styles: { default: { document: { run: { font: "Arial", size: 24 } } }, // 12pt paragraphStyles: [ { 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 } }, { 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("Title")] }), ] }] }); ``` ### Lists (NEVER unicode bullets) ```javascript const doc = new Document({ numbering: { config: [ { reference: "bullets", levels: [{ level: 0, format: LevelFormat.BULLET, text: "•", alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }, { reference: "numbers", levels: [{ level: 0, format: LevelFormat.DECIMAL, text: "%1.", alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }, ] }, sections: [{ children: [ new Paragraph({ numbering: { reference: "bullets", level: 0 }, children: [new TextRun("Item")] }), new Paragraph({ numbering: { reference: "numbers", level: 0 }, children: [new TextRun("Item")] }), ] }] }); ``` ### Tables (CRITICAL — dual widths required) ```javascript const border = { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" }; const borders = { top: border, bottom: border, left: border, right: border }; new Table({ width: { size: 9360, type: WidthType.DXA }, // NEVER use PERCENTAGE columnWidths: [4680, 4680], // must sum to table width rows: [ new TableRow({ children: [ new TableCell({ borders, width: { size: 4680, type: WidthType.DXA }, // match columnWidths shading: { fill: "D5E8F0", type: ShadingType.CLEAR }, // CLEAR not SOLID margins: { top: 80, bottom: 80, left: 120, right: 120 }, children: [new Paragraph({ children: [new TextRun("Cell")] })] }) ] }) ] }) ``` ### Images ```javascript new Paragraph({ children: [new ImageRun({ type: "png", // REQUIRED: png, jpg, jpeg, gif, bmp, svg data: fs.readFileSync("image.png"), transformation: { width: 200, height: 150 }, altText: { title: "Title", description: "Desc", name: "Name" } // all 3 required })] }) ``` ### Hyperlinks ```javascript // External new Paragraph({ children: [new ExternalHyperlink({ children: [new TextRun({ text: "Click here", style: "Hyperlink" })], link: "https://example.com", })] }) // Internal (bookmark → reference) new Paragraph({ heading: HeadingLevel.HEADING_1, children: [ new Bookmark({ id: "ch1", children: [new TextRun("Chapter 1")] }), ]}) new Paragraph({ children: [new InternalHyperlink({ children: [new TextRun({ text: "See Ch 1", style: "Hyperlink" })], anchor: "ch1", })]}) ``` ### Footnotes ```javascript const doc = new Document({ footnotes: { 1: { children: [new Paragraph("Source: Report 2024")] }, }, sections: [{ children: [new Paragraph({ children: [new TextRun("Revenue up 15%"), new FootnoteReferenceRun(1)], })] }] }); ``` ### Tab Stops (right-align on same line) ```javascript new Paragraph({ children: [new TextRun("Company"), new TextRun("\tJan 2025")], tabStops: [{ type: TabStopType.RIGHT, position: TabStopPosition.MAX }], }) // Dot leader (TOC-style) new Paragraph({ children: [new TextRun("Introduction"), new TextRun({ children: [ new PositionalTab({ alignment: PositionalTabAlignment.RIGHT, relativeTo: PositionalTabRelativeTo.MARGIN, leader: PositionalTabLeader.DOT, }), "3", ]})], }) ``` ### Multi-Column ```javascript sections: [{ properties: { column: { count: 2, space: 720, equalWidth: true, separate: true }, }, children: [/* flows across columns */] }] // Custom widths column: { equalWidth: false, children: [new Column({ width: 5400, space: 720 }), new Column({ width: 3240 })], } // Force column break new Section({ type: SectionType.NEXT_COLUMN, children: [/* ... */] }) ``` ### Table of Contents ```javascript // Headings MUST use HeadingLevel, not custom styles new TableOfContents("Índice", { hyperlink: true, headingStyleRange: "1-3" }) ``` ### Headers/Footers ```javascript sections: [{ properties: { page: { margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 } } }, headers: { default: new Header({ children: [new Paragraph({ children: [new TextRun("Header")] })] }) }, footers: { default: new Footer({ children: [new Paragraph({ children: [new TextRun("Page "), new TextRun({ children: [PageNumber.CURRENT] })] })] }) }, children: [/* content */] }] ``` ### Page Breaks ```javascript new Paragraph({ children: [new PageBreak()] }) // or new Paragraph({ pageBreakBefore: true, children: [new TextRun("New page")] }) ``` ## Reading & Converting ```bash # Text extraction (with tracked changes) pandoc --track-changes=all document.docx -o output.md # Convert to PDF (LibreOffice) libreoffice --headless --convert-to pdf document.docx # Convert to images libreoffice --headless --convert-to pdf document.docx pdftoppm -jpeg -r 150 document.pdf page # Accept tracked changes (LibreOffice) # Use scripts/accept_changes.py input.docx output.docx ``` ## Critical Rules - **Set page size explicitly** — defaults to A4, not US Letter - **Landscape**: pass portrait dims, set `PageOrientation.LANDSCAPE` - **Never use `\n`** — use separate Paragraph elements - **Never use unicode bullets** — use `LevelFormat.BULLET` - **PageBreak** must be inside a Paragraph - **ImageRun requires `type`** — always specify - **Tables need dual widths** — `columnWidths` AND cell `width`, both DXA - **Never use `WidthType.PERCENTAGE`** — breaks in Google Docs - **Use `ShadingType.CLEAR`** — never SOLID - **Never use tables as dividers** — use paragraph borders instead - **TOC requires HeadingLevel only** — no custom styles on headings - **Include `outlineLevel`** — required for TOC (0=H1, 1=H2, ...)