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, ...)