docx

repository·master·Indexed 26 days ago

https://github.com/dolanmiu/docx

A JavaScript/TypeScript library for generating and modifying .docx files with a declarative API. Compatible with Node.js and browser environments, it allows programmatic creation of Word documents including paragraphs, tables, images, and styled text using classes like Document, Packer, and TextRun.

Tokens
72.8K
Snippets
210
Records
285
Agent score
90%

What's inside docx

  1. Overview of docx library

    master
    The docx library allows you to easily generate and modify .docx files using JavaScript or TypeScript. It is designed to work in both Node.js and Browser environments. The library features a simple, declarative API and is highly mature with 100% test coverage.
  2. Export documents in Node.js

    master

    In a Node.js environment, you can export a document using Packer.toBuffer to save to a file or Packer.toStream to pipe the document to a write stream.

    // Save to File
    Packer.toBuffer(doc).then((buffer) => {
        fs.writeFileSync("document.docx", buffer);
    });
    
    // Stream
    Packer.toStream(doc).then((stream) => {
        stream.pipe(fs.createWriteStream("document.docx"));
    });
  3. Add accessibility labels to CheckBoxes

    master

    Use the alias property to provide an accessibility label for the checkbox, which helps screen readers identify the purpose of the control.

    new Paragraph({
        children: [
            new TextRun("Do you agree to the terms?"),
            new TextRun({ break: 1 }),
            new CheckBox({
                checked: false,
                alias: "Terms agreement checkbox",
            }),
            new TextRun(" Yes, I agree"),
        ],
    });
  4. Export documents in the Browser

    master

    To trigger a download in a browser, use Packer.toBlob and a library like file-saver to save the resulting blob.

    import { saveAs } from "file-saver";
    
    Packer.toBlob(doc).then((blob) => {
        saveAs(blob, "document.docx");
    });
  5. Use custom fonts in a Browser environment

    master

    In a browser, you must fetch the font file and convert it to an ArrayBuffer or base64 string. Use Buffer.from() to wrap the data for the Document constructor. Use Packer.toBlob() to export the document for downloading.

    import { CharacterSet, Document, Packer, Paragraph, TextRun } from "docx";
    import { saveAs } from "file-saver";
    
    // Fetch the font file and convert to ArrayBuffer
    const response = await fetch("./fonts/MyFont.ttf");
    const fontData = await response.arrayBuffer();
    
    const doc = new Document({
        fonts: [
            {
                name: "MyFont",
                data: Buffer.from(fontData),
                characterSet: CharacterSet.ANSI,
            },
        ],
        sections: [
            {
                children: [
                    new Paragraph({
                        children: [
                            new TextRun({
                                text: "Text with embedded font",
                                font: "MyFont",
                            }),
                        ],
                    }),
                ],
            },
        ],
    });
    
    // Export the document
    Packer.toBlob(doc).then((blob) => {
        saveAs(blob, "document.docx");
    });
  6. Prevent justified text stretching on soft line breaks

    master

    By default, justified paragraphs stretch incomplete lines ending in a soft line break to fill the width. To prevent this, enable doNotExpandShiftReturn in the Document compatibility options.

    const doc = new Document({
        compatibility: {
            doNotExpandShiftReturn: true,
        },
        sections: [
            {
                children: [
                    new Paragraph({
                        text: "This justified paragraph won't stretch soft line breaks.",
                        alignment: AlignmentType.JUSTIFIED,
                    }),
                ],
            },
        ],
    });
  7. Create basic equal-width columns

    master

    To create multi-column layouts like newspapers, configure the column property within a section's properties. For equal-width columns, specify the count and an optional space (in twips) between columns.

    import { Document, Paragraph } from "docx";
    
    const doc = new Document({
        sections: [
            {
                properties: {
                    column: {
                        count: 2,
                        space: 708, // Space between columns (~0.5 inches in twips; 1440 twips = 1 inch)
                    },
                },
                children: [new Paragraph("This text will flow across two columns...")],
            },
        ],
    });
  8. Use templates to modify existing Word documents

    master

    Templates allow you to generate dynamic documents from pre-designed .docx layouts by replacing placeholder tags with content using patchDocument.

    Workflow

    1. Create a Template: Open a Word processor and create a .docx file using double curly braces {{placeholder_name}} for your tags.
    2. Define Patches: Use the patchDocument function to map your placeholder names to new content.
    3. Export: Run the patcher to produce the modified document.

    Basic Usage Example

    import * as fs from "fs";
    import { patchDocument, PatchType, TextRun } from "docx";
    
    patchDocument({
        outputType: "nodebuffer",
        data: fs.readFileSync("template.docx"),
        patches: {
            customer_name: {
                type: PatchType.PARAGRAPH,
                children: [new TextRun("John Smith")],
            },
            order_number: {
                type: PatchType.PARAGRAPH,
                children: [new TextRun("12345")],
            },
        },
    }).then((doc) => {
        fs.writeFileSync("output.docx", doc);
    });
    import * as fs from "fs";
    import { patchDocument, PatchType, TextRun } from "docx";
    
    patchDocument({
        outputType: "nodebuffer",
        data: fs.readFileSync("template.docx"),
        patches: {
            customer_name: {
                type: PatchType.PARAGRAPH,
                children: [new TextRun("John Smith")],
            },
            order_number: {
                type: PatchType.PARAGRAPH,
                children: [new TextRun("12345")],
            },
        },
    }).then((doc) => {
        fs.writeFileSync("output.docx", doc);
    });
  9. Create basic bullet points

    master

    To create bullet points, add the bullet property to a Paragraph object. The bullet object requires a level property to define the indentation level.

    const doc = new Document({
        sections: [
            {
                children: [
                    new Paragraph({
                        text: "First item",
                        bullet: {
                            level: 0,
                        },
                    }),
                    new Paragraph({
                        text: "Second item",
                        bullet: {
                            level: 0,
                        },
                    }),
                    new Paragraph({
                        text: "Third item",
                        bullet: {
                            level: 0,
                        },
                    }),
                ],
            },
        ],
    });
  10. Configure Bullets and Numbering in Document

    master

    To use bullets or numbering, you must configure them within the Document constructor using the numbering property. This allows you to define reusable numbering styles throughout the document.

    Each configuration entry requires a unique reference string and a levels array that defines the visual hierarchy (starting from level 0 for the root list, level 1 for sub-lists, etc.).

    new Document({
        numbering: {
            config: [
                // configuration entries here
            ]
        }
    })
  11. Set page orientation (Portrait/Landscape)

    master

    Set the orientation using PageOrientation.LANDSCAPE or PageOrientation.PORTRAIT.

    Important: When switching to landscape, you must manually swap the width and height values. The orientation property only controls how Word displays the page; it does not automatically adjust the dimensions.

    import { Document, PageOrientation, Paragraph, convertMillimetersToTwip } from "docx";
    
    // Landscape A4
    // Note: For landscape, swap width and height values so the larger dimension becomes the width
    const doc = new Document({
        sections: [
            {
                properties: {
                    page: {
                        size: {
                            orientation: PageOrientation.LANDSCAPE,
                            width: convertMillimetersToTwip(297), // A4 height becomes landscape width
                            height: convertMillimetersToTwip(210), // A4 width becomes landscape height
                        },
                    },
                },
                children: [new Paragraph("Landscape page")],
            },
        ],
    });
  12. Embed custom fonts in a Document

    master

    To ensure consistent appearance across different systems, you can embed font data directly into the Document via the fonts property in the constructor. This requires providing the font name, the raw font data (as a Buffer), and an optional characterSet.

    import * as fs from "fs";
    import { CharacterSet, Document, Paragraph, TextRun } from "docx";
    
    const fontData = fs.readFileSync("./fonts/MyCustomFont.ttf");
    
    const doc = new Document({
        fonts: [
            {
                name: "MyCustomFont",
                data: fontData,
                characterSet: CharacterSet.ANSI,
            },
        ],
        sections: [
            {
                children: [
                    new Paragraph({
                        children: [
                            new TextRun({
                                text: "This text uses a custom font",
                                font: "MyCustomFont",
                            }),
                        ],
                    }),
                ],
            },
        ],
    });