docx_creator

pub package Dart SDK License: MIT

A developer-first DOCX generation library for Dart. Create, parse, read, and edit Microsoft Word documents with a fluent API, HTML/Markdown parsers, and full OpenXML compliance.

πŸ”— Live Demo / Showcase β€” try the Builder API, HTML/Markdown parsers, DOCX/PDF readers, and every export format right in your browser.

✨ Features

Feature Description
πŸ”§Fluent Builder API Chain methods to create documents quickly
🌐HTML Parser Convert HTML to DOCX with 141 CSS named colors
πŸ“Markdown Parser Parse Markdown including tables and nested lists
πŸ“–DOCX Reader Load and edit existing .docx files
πŸ“•PDF Reader Parse PDF files to DOCX structure
πŸ“„PDF Export Export documents directly to PDF (pure Dart), with an automatic Unicode fallback font
⬇️Markdown Export Export documents directly to Markdown (GFM)
🌍HTML Export Export documents directly to HTML
🎨Drawing Shapes 70+ preset shapes (rectangles, arrows, stars, etc.)
πŸ–ΌοΈImages Embed local, remote, or base64 images (Inline & Floating)
πŸ“ŠTables Styled tables, merged cells, borders, & conditional styles
πŸ“‹Lists Bullet, numbered, and nested lists (9 levels)
πŸ”€Fonts Embed custom fonts with OOXML obfuscation
πŸ“„Sections Headers, footers, page orientation, backgrounds
πŸ“ŒFootnotes Full support for footnotes and endnotes
🧒Drop Caps Stylized drop caps for paragraph beginnings
🎨Theme Support Theme colors, tints, shades, and font themes
🧬Advanced Styling Proper inheritance from docDefaults and style hierarchy
πŸ€–AI-Ready Optimized for AI agents withllm.txt context

πŸ“‹ What's Actually Supported: DOCX vs. PDF

docx_creator builds one internal document model (the DocxNode AST) and can export it to either DOCX (via DocxExporter, full OpenXML) or PDF (via PdfExporter, a from-scratch pure-Dart writer β€” no native/system dependencies). They don't have identical capabilities: DOCX export is the primary, feature-complete target; PDF export covers the vast majority of the same model but has a short list of known gaps, listed explicitly below rather than glossed over.

Side-by-side

Feature DOCX PDF
Headings, paragraphs, all text runs (bold/italic/underline/strike/double-strike/caps/small-caps/outline/shadow/emboss/imprint) βœ… βœ…
Custom font size, character spacing, superscript/subscript βœ… βœ…
Text color & highlight/shading (hex) βœ… βœ…
Theme color/tint/shade (text and shading) βœ… ⚠️ resolved to its literal hex where set; PDF has no OOXML theme palette to resolve accent1 etc. against
Custom/embedded fonts (TTF) βœ… (OOXML-obfuscated) βœ… (embedded with correct glyph widths & ToUnicode; used in paragraphs, table cells, and lists)
Paragraph alignment (left/center/right/justify) βœ… βœ…
Paragraph spacing, left/right indent, padding βœ… βœ…
Paragraph borders (incl. <hr>, blockquote rules) βœ… βœ… (actually drawn, not just spaced)
pageBreakBefore βœ… βœ…
Bullet/numbered lists, 9 levels, nested, custom bullets/formats, image bullets βœ… βœ… top-level; nested lists inside table cells render as plain text (formatting simplified)
Tables: merged cells (colSpan/rowSpan) βœ… βœ… (correct grid placement, no overlap)
Tables: per-cell/table borders, incl. "no border" styles βœ… βœ…
Tables: real column widths βœ… βœ…
Tables: cell shading, margins, conditional formatting βœ… βœ… shading; margins/cnfStyle not visually distinct in PDF
Tables: nested tables/lists inside cells βœ… βœ…
Tables spanning multiple pages N/A (Word reflows natively) βœ… splits by row automatically
Images: inline & floating, wrapping, alignment βœ… βœ… (floating-specific wrap/z-order collapses to normal inline flow in PDF)
Image formats PNG/JPEG/GIF/BMP as provided βœ… PNG/GIF/BMP/etc. decoded & re-embedded as JPEG; JPEG passthrough
Image borders βœ… βœ… drawn for both block-level and inline images
Text using non-Latin scripts (Cyrillic, Greek, Vietnamese, etc.) without a custom font βœ… βœ… auto-embeds a bundled fallback font (DejaVu Sans) the first time it's needed; CJK/Arabic still need an explicit addFont()
Drawing shapes (70+ presets), block-level βœ… βœ…
Drawing shapes, inline (inside a paragraph run) βœ… βœ…
Hyperlinks βœ… βœ… real clickable /Annot links
Headers & footers βœ… βœ…
Section background color/image (stretch/fit/center/tile, opacity) βœ… βœ…
Multiple sections (independent page size/orientation/margins) βœ… βœ…
Section break type (continuous/nextPage/evenPage/oddPage) βœ… N/A (PDF has no section-break concept)
Drop caps βœ… (true Word text-wrap) βœ… true wrap-around: following text flows in a narrower column beside the letter
Footnotes βœ… βœ… rendered at the bottom of the page; space is auto-reserved so body text can't overlap it. Font size matches body text (no automatic downscale)
Endnotes βœ… βœ… rendered on a trailing "Endnotes" page, with a superscript reference marker at the citation point
Table of Contents βœ… (live field, recalculated by Word) ⚠️ cached TOC content renders as static text; page numbers aren't recomputed against PDF pagination
Checkboxes (☐ β˜‘ β˜’) βœ… βœ…
Multi-page pagination N/A βœ… automatic; paragraphs and tables both split cleanly across pages with no overlap; a nested list inside a table cell numbers correctly per level
Long words/URLs wider than the line N/A βœ… split across lines like any other overflow, instead of drawing past the margin
Raw/unmodeled OOXML passthrough ("Shadow Model") βœ… N/A (DOCX-specific fidelity feature)

Reading it both ways works too: DocxReader round-trips everything in the DOCX column above β€” load a .docx, every property listed as βœ… comes back onto the AST correctly, not just write-only.

If a gap above matters for your use case, please open an issue β€” they're tracked, just not implemented yet.


Help Maintenance

I've been maintaining quite many repos these days and burning out slowly. If you could help me cheer up, buying me a cup of coffee will make my life really happy and get much energy out of it.

Buy Me A Coffee

πŸ€– AI-Agent Friendly

This package includes an llm.txt file at the root, providing a structured map of the codebase and architectural patterns to help AI coding agents work more effectively and safely.

πŸ“¦ Installation

Add to your pubspec.yaml:

dependencies:
  docx_creator: ^1.3.2

Then run:

dart pub get

πŸš€ Quick Start

Hello World

import 'package:docx_creator/docx_creator.dart';

void main() async {
  // Create a simple document
  final doc = docx()
    .h1('Hello, World!')
    .p('This is my first DOCX document.')
    .build();

  // Save to file
  await DocxExporter().exportToFile(doc, 'hello.docx');
}

From HTML

final htmlContent = '''
<h1>Report Title</h1>
<p>This is a <b>bold</b> and <i>italic</i> paragraph.</p>
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
</ul>
''';

final elements = await DocxParser.fromHtml(htmlContent);
final doc = DocxBuiltDocument(elements: elements);
await DocxExporter().exportToFile(doc, 'from_html.docx');

From Markdown

final markdown = '''
# Project Report

## Summary
This is **important** information.

- Task 1: Complete
- Task 2: In Progress
''';

final elements = await MarkdownParser.parse(markdown);
final doc = DocxBuiltDocument(elements: elements);
await DocxExporter().exportToFile(doc, 'from_markdown.docx');

πŸ“– Documentation

Table of Contents

  1. Builder API
  2. Text Formatting
  3. Lists
  4. Tables
  5. Images
  6. Shapes & Drawings
  7. HTML Parser
  8. Markdown Parser
  9. Markdown Export
  10. DOCX Reader & Editor
  11. PDF Reader
  12. PDF Export
  13. Sections & Page Layout
  14. Font Embedding
  15. API Reference

PDF Export

Export documents directly to PDF with the PdfExporter. This is a pure Dart implementation with no native dependencies.

Basic Usage

import 'package:docx_creator/docx_creator.dart';

// Create a document
final doc = docx()
  .h1('PDF Export Demo')
  .p('This document will be exported to PDF.')
  .bullet(['Feature 1', 'Feature 2', 'Feature 3'])
  .build();

// Export to PDF file
await PdfExporter().exportToFile(doc, 'output.pdf');

// Or get as bytes
final pdfBytes = PdfExporter().exportToBytes(doc);

From HTML or Markdown

// From HTML
final html = '<h1>Title</h1><p>Content with <b>bold</b>.</p>';
final htmlDoc = DocxBuiltDocument(elements: await DocxParser.fromHtml(html));
await PdfExporter().exportToFile(htmlDoc, 'from_html.pdf');

// From Markdown
final md = '# Title\n\nParagraph with **bold**.';
final mdDoc = DocxBuiltDocument(elements: await MarkdownParser.parse(md));
await PdfExporter().exportToFile(mdDoc, 'from_markdown.pdf');

Automatic Unicode Fallback Font

If your text uses a script a standard PDF font can't render β€” Cyrillic, Greek, Vietnamese, and other scripts covered by DejaVu Sans β€” the exporter automatically embeds a bundled fallback font the first time it's needed, with zero network or filesystem access (it works on web too). You don't need to do anything:

final doc = docx().p('ΠŸΡ€ΠΈΠ²Π΅Ρ‚, ΠΌΠΈΡ€! ΓΡιά σου ΞΊΟŒΟƒΞΌΞ΅!').build();
await PdfExporter().exportToFile(doc, 'cyrillic_greek.pdf'); // just works

An explicit addFont() call always takes priority over the fallback. CJK and Arabic scripts need dedicated, much larger, shaping-aware fonts that aren't reasonable to bundle unconditionally β€” for those, call addFont() with a font that covers them.

Supported Features

Feature Support
Headings (H1-H6) βœ…
Bold/Italic/Underline/Strikethrough βœ…
Custom font sizes, superscript/subscript βœ…
Text colors, highlight/background shading βœ…
Custom embedded fonts (TTF), incl. in tables/lists βœ…
Automatic Unicode fallback font (Cyrillic/Greek/etc.) βœ…
Text alignment (left/center/right/justify) βœ…
Paragraph spacing/indent/padding/borders βœ…
Forced page breaks (pageBreakBefore) βœ…
Bullet & numbered lists (nested) βœ…
Tables: merged cells (colSpan/rowSpan) βœ…
Tables: real column widths & per-cell/table borders βœ…
Tables: nested lists/tables in cells βœ…
Tables spanning multiple pages βœ… auto-splits by row
Long words/URLs wider than the line βœ… split across lines
Images (PNG/JPEG/GIF/BMP), alignment βœ…
Inline images inside paragraph text βœ…
Image borders βœ…
Hyperlinks (clickable) βœ…
Headers & footers βœ…
Section background (color/image, opacity) βœ…
Drop caps βœ… true wrap-around
Footnotes βœ… auto-reserves page space
Endnotes βœ… trailing page with reference markers
Inline shapes (shape inside a paragraph run) βœ…
Page sizes (A4, Letter) βœ…
Multi-page pagination βœ… automatic, no overlap

See the "What's Actually Supported: DOCX vs. PDF" section near the top of this README for the full side-by-side with DOCX.


Builder API

The DocxDocumentBuilder provides a fluent interface for document creation:

final doc = DocxDocumentBuilder()
  // Headings
  .h1('Title')
  .h2('Chapter')
  .h3('Section')
  
  // Paragraphs
  .p('Simple paragraph text')
  .p('Right-aligned', align: DocxAlign.right)
  
  // Lists
  .bullet(['Item 1', 'Item 2', 'Item 3'])
  .numbered(['Step 1', 'Step 2', 'Step 3'])
  
  // Tables
  .table([
    ['Header 1', 'Header 2'],
    ['Cell 1', 'Cell 2'],
  ])
  
  // Special elements
  .pageBreak()
  .hr()  // Horizontal rule
  .quote('Blockquote text')
  .code('print("Hello");')
  
  .build();

Short vs Full Method Names

Short Full Description
h1(text) heading1(text) Heading level 1
h2(text) heading2(text) Heading level 2
h3(text) heading3(text) Heading level 3
p(text) text(content) Paragraph
bullet(items) addList(DocxList) Bullet list
numbered(items) addList(DocxList) Numbered list
hr() divider() Horizontal rule

Text Formatting

Create rich text with DocxText and DocxParagraph:

final doc = DocxDocumentBuilder()
  .add(DocxParagraph(children: [
    // Basic formatting
    DocxText('Bold ', fontWeight: DocxFontWeight.bold),
    DocxText('Italic ', fontStyle: DocxFontStyle.italic),
    DocxText('Underline ', decoration: DocxTextDecoration.underline),
    DocxText('Strikethrough', decoration: DocxTextDecoration.strikethrough),
  
    // Colors
    DocxText('Red text ', color: DocxColor.red),
    DocxText('Custom color ', color: DocxColor('#FF6600')),
    DocxText('With background ', shadingFill: 'FFFF00'),
  
    // Font size
    DocxText('Large text', fontSize: 24),
  
    // Superscript/Subscript
    DocxText('E=mc'),
    DocxText('2', isSuperscript: true),
    DocxText(' H'),
    DocxText('2', isSubscript: true),
    DocxText('O'),
  
    // Highlighting
    DocxText('Highlighted', highlight: DocxHighlight.yellow),
  
    // Hyperlinks
    DocxText('Click here', 
      href: 'https://example.com',
      color: DocxColor.blue,
      decoration: DocxTextDecoration.underline),
  ]))
  
  // Paragraph with specific line spacing
  .add(DocxParagraph(
    children: [DocxText('Exact Spacing')],
    lineSpacing: 240,       // 12 pt
    lineRule: 'exact',      // 'auto', 'exact', 'atLeast'
  ))
  .build();

Available Colors

// Predefined colors
DocxColor.black, DocxColor.white, DocxColor.red, DocxColor.blue,
DocxColor.green, DocxColor.yellow, DocxColor.orange, DocxColor.purple,
DocxColor.gray, DocxColor.lightGray, DocxColor.darkGray, DocxColor.cyan,
DocxColor.magenta, DocxColor.pink, DocxColor.brown, DocxColor.navy,
DocxColor.teal, DocxColor.lime, DocxColor.gold, DocxColor.silver

// Custom hex colors
DocxColor('#FF5722')
DocxColor('4285F4')  // # is optional

Lists

Simple Lists

// Bullet list
.bullet(['First item', 'Second item', 'Third item'])

// Numbered list
.numbered(['Step 1', 'Step 2', 'Step 3'])

Nested Lists

final nestedList = DocxList(
  style: DocxListStyle.disc,
  items: [
    DocxListItem.text('Level 0 - First', level: 0),
    DocxListItem.text('Level 1 - Nested', level: 1),
    DocxListItem.text('Level 2 - Deep', level: 2),
    DocxListItem.text('Level 1 - Back', level: 1),
    DocxListItem.text('Level 0 - Root', level: 0),
  ],
);

docx().add(nestedList).build();

List Styles

DocxListStyle.disc       // β€’ Solid disc (default)
DocxListStyle.circle     // β—¦ Circle
DocxListStyle.square     // β–ͺ Square
DocxListStyle.dash       // - Dash
DocxListStyle.arrow      // β†’ Arrow
DocxListStyle.check      // βœ“ Checkmark
DocxListStyle.decimal    // 1, 2, 3
DocxListStyle.lowerAlpha // a, b, c
DocxListStyle.upperAlpha // A, B, C
DocxListStyle.lowerRoman // i, ii, iii
DocxListStyle.upperRoman // I, II, III

Tables

Simple Table

.table([
  ['Name', 'Age', 'City'],
  ['Alice', '25', 'New York'],
  ['Bob', '30', 'Los Angeles'],
])

Styled Table

final styledTable = DocxTable(
  rows: [
    DocxTableRow(cells: [
      DocxTableCell(
        children: [DocxParagraph(children: [
          DocxText('Header', fontWeight: DocxFontWeight.bold, color: DocxColor.white)
        ])],
        shadingFill: '4472C4',  // Blue background
        verticalAlign: DocxVerticalAlign.center,
      ),
      // More cells...
    ]),
    // More rows...
  ],
);

Images

import 'dart:io';

// From file
final imageBytes = await File('logo.png').readAsBytes();
final doc = docx()
  .add(DocxImage(
    bytes: imageBytes,
    extension: 'png',
    width: 200,
    height: 100,
    align: DocxAlign.center,
  ))
  .build();

// Inline image in paragraph
.add(DocxParagraph(children: [
  DocxText('See image: '),
  DocxInlineImage(bytes: imageBytes, extension: 'png', width: 50, height: 50),
  DocxText(' above.'),
]))

Shapes & Drawings

Create DrawingML shapes with 70+ presets:

// Basic shapes
DocxShapeBlock.rectangle(
  width: 200,
  height: 60,
  fillColor: DocxColor.blue,
  outlineColor: DocxColor.black,
  outlineWidth: 2,
  text: 'Click Me',
  align: DocxAlign.center,
)

DocxShapeBlock.ellipse(width: 100, height: 100, fillColor: DocxColor.green)
DocxShapeBlock.circle(diameter: 80, fillColor: DocxColor.red)
DocxShapeBlock.triangle(width: 100, height: 100, fillColor: DocxColor.yellow)
DocxShapeBlock.star(points: 5, fillColor: DocxColor.gold)
DocxShapeBlock.diamond(width: 80, fillColor: DocxColor.purple)
DocxShapeBlock.rightArrow(width: 100, height: 40, fillColor: DocxColor.blue)
DocxShapeBlock.leftArrow(width: 100, height: 40, fillColor: DocxColor.red)

// Inline shapes in paragraph
.add(DocxParagraph(children: [
  DocxShape.circle(diameter: 30, fillColor: DocxColor.red),
  DocxText(' Red circle '),
  DocxShape.star(points: 5, fillColor: DocxColor.gold),
  DocxText(' Gold star'),
]))

Shape Presets

Over 70 preset shapes including: rect, ellipse, triangle, diamond, star4, star5, star6, rightArrow, leftArrow, upArrow, downArrow, heart, lightning, flowChartProcess, flowChartDecision, and many more.


HTML Parser

Supported HTML Tags

Tag Output
<h1> - <h6> Headings
<p> Paragraph
<b>, <strong> Bold
<i>, <em> Italic
<u> Underline
<s>, <del> Strikethrough
<mark> Highlight
<sup> Superscript
<sub> Subscript
<a href=""> Hyperlink
<code> Inline code
<pre> Code block
<ul>, <ol> Lists
<table> Tables
<img> Images
<blockquote> Blockquote
<hr> Horizontal rule
<br> Line break
<div>, <span> Containers with styles
<dl>, <dt>, <dd> Definition list (term + indented definition)

Supported CSS Properties

color: red;                    /* Text color: hex, rgb()/rgba(), hsl()/hsla(), or 141 named colors */
color: #FF5722;               /* Hex color */
color: dodgerblue;            /* CSS named color (141 supported) */
color: hsl(210, 80%, 50%);    /* HSL color */
background-color: yellow;      /* Background/shading */
font-size: 16px;              /* Font size: px, pt, em, rem, and % are all converted correctly */
font-weight: bold;            /* Bold (also matches numeric weights 600-900) */
font-style: italic;           /* Italic */
text-align: center;           /* Alignment */
text-decoration: underline;   /* Underline/strikethrough */
margin-left: 20px;            /* Paragraph/cell indentation */
padding-left: 20px;           /* Paragraph/cell indentation */
text-indent: 20px;            /* First-line indentation */

Property matching is case- and whitespace-insensitive (FONT-WEIGHT:BOLD works the same as font-weight: bold), and grouped selectors (.foo, .bar { ... }) apply to every class listed.

CSS Named Colors

All 141 W3C CSS3 Extended Color Keywords are supported:

<span style="color: dodgerblue;">DodgerBlue</span>
<span style="color: mediumvioletred;">MediumVioletRed</span>
<span style="color: darkolivegreen;">DarkOliveGreen</span>
<span style="color: papayawhip;">PapayaWhip</span>

Including grey/gray variations: grey, darkgrey, lightgrey, etc.

Example

final html = '''
<div style="background-color: #f0f0f0; padding: 10px;">
  <h1 style="color: navy;">Report Title</h1>
  <p>This is <span style="color: red; font-weight: bold;">important</span> text.</p>
  <table border="1">
    <tr style="background-color: #4472C4; color: white;">
      <th>Name</th>
      <th>Status</th>
    </tr>
    <tr>
      <td>Task 1</td>
      <td style="background-color: lightgreen;">Complete</td>
    </tr>
  </table>
</div>
''';

final elements = await DocxParser.fromHtml(html);

Markdown Parser

Supported Syntax

Markdown Output
# Heading H1-H6
**bold** Bold
*italic* Italic
~~strike~~ Strikethrough
[text](url) Links
`code` Inline code
``` Code blocks
- item Bullet list
1. item Numbered list
> quote Blockquote
--- Horizontal rule
` a
[ ] / [x] Task lists

Nested Lists

- Level 1
    - Level 2
        - Level 3
    - Level 2
- Level 1

Nested lists are automatically converted to multi-level Word lists with proper indentation.

Tables with Alignment

| Left | Center | Right |
|:-----|:------:|------:|
| L    | C      | R     |

Column alignment from the :---/:---:/---: delimiter row is applied to each cell.

Ordered lists preserve their start number (5. Five starts numbering at 5), and a list item spanning multiple paragraphs (separated by a blank line, indented under the marker) stays one logical item instead of splitting into several.


Markdown Export

Export documents directly to Markdown (GitHub-Flavored Markdown) with MarkdownExporter β€” the reverse direction of the Markdown parser above.

import 'package:docx_creator/docx_creator.dart';

final doc = docx()
  .h1('Report')
  .p('Body text with **bold** and *italic*.')
  .bullet(['Item 1', 'Item 2'])
  .table([
    ['Name', 'Status'],
    ['Task 1', 'Done'],
  ])
  .build();

final markdown = MarkdownExporter().export(doc);
await MarkdownExporter().exportToFile(doc, 'report.md');

Supported Features

Feature Support
Headings (H1-H6) βœ…
Bold/Italic/Bold+Italic/Strikethrough βœ…
Inline code (CommonMark-correct backtick fencing) βœ…
Links, superscript/subscript/underline (HTML passthrough), highlighted text βœ…
Fenced code blocks, blockquotes, horizontal rules βœ…
Nested bullet/numbered lists, GFM task-list items βœ…
Tables (synthesized header separator row) βœ…
Inline/block images (as data URIs) βœ…
Footnote/endnote references with trailing definitions βœ…
Table cell merges (colSpan/rowSpan) ⚠️ collapses to a plain cell β€” Markdown tables have no merge syntax
Floating images, drawing shapes, raw OOXML, section breaks, TOC fields ❌ no Markdown equivalent

DOCX Reader & Editor

Loading an Existing Document

// From file path
final doc = await DocxReader.load('existing.docx');

// From bytes
final bytes = await File('existing.docx').readAsBytes();
final doc = await DocxReader.loadFromBytes(bytes);

Accessing Elements

for (final element in doc.elements) {
  if (element is DocxParagraph) {
    for (final child in element.children) {
      if (child is DocxText) {
        print('Text: ${child.content}');
        print('Bold: ${child.fontWeight == DocxFontWeight.bold}');
        print('Color: ${child.color?.hex}');
      }
    }
  } else if (element is DocxTable) {
    print('Table with ${element.rows.length} rows');
  } else if (element is DocxList) {
    print('List with ${element.items.length} items');
  }
}

Modifying and Re-Saving

// Load document
final doc = await DocxReader.load('report.docx');

// Modify elements
final modifiedElements = <DocxNode>[];
for (final element in doc.elements) {
  if (element is DocxParagraph) {
    // Find and replace text
    final newChildren = element.children.map((child) {
      if (child is DocxText) {
        return DocxText(
          child.content.replaceAll('OLD', 'NEW'),
          fontWeight: child.fontWeight,
          color: child.color,
        );
      }
      return child;
    }).toList();
    modifiedElements.add(DocxParagraph(children: newChildren));
  } else {
    modifiedElements.add(element);
  }
}

// Add new content
modifiedElements.add(DocxParagraph.text('Added on: ${DateTime.now()}'));

// Create new document preserving metadata
final editedDoc = DocxBuiltDocument(
  elements: modifiedElements,
  // Preserve original document properties
  section: doc.section,
  stylesXml: doc.stylesXml,
  numberingXml: doc.numberingXml,
);

// Save
await DocxExporter().exportToFile(editedDoc, 'report_edited.docx');

Round-Trip Pipeline

// Load β†’ Parse β†’ Modify β†’ Export
final original = await DocxReader.load('input.docx');

// All formatting, lists, tables, shapes are preserved
final elements = List<DocxNode>.from(original.elements);

// Add new content
elements.add(DocxParagraph.heading2('New Section'));
elements.add(DocxParagraph.text('Content added programmatically.'));

// Export with preserved metadata
final output = DocxBuiltDocument(
  elements: elements,
  stylesXml: original.stylesXml,
  numberingXml: original.numberingXml,
);

await DocxExporter().exportToFile(output, 'output.docx');

PDF Reader

Parse PDF documents and convert them to editable DocxBuiltDocument objects. The reader supports a wide variety of PDF formats including legacy and modern PDFs.

Basic Usage

// Load PDF from file
final pdf = await PdfReader.load('input.pdf');

// Load from bytes
final bytes = await File('input.pdf').readAsBytes();
final pdf = await PdfReader.loadFromBytes(bytes);

// Convert to DOCX
final doc = pdf.toDocx();
await DocxExporter().exportToFile(doc, 'converted.docx');

Content Extraction

Access extracted elements directly:

final pdf = await PdfReader.loadFromBytes(pdfBytes);

print('Pages: ${pdf.pageCount}');
print('PDF Version: ${pdf.version}');
print('Page Size: ${pdf.pageWidth} x ${pdf.pageHeight}');

// Iterate over extracted elements
for (final element in pdf.elements) {
  if (element is DocxParagraph) {
    // Text content with formatting
    for (final child in element.children) {
      if (child is DocxText) {
        print('Text: ${child.content}');
        print('Bold: ${child.fontWeight == DocxFontWeight.bold}');
      }
    }
  } else if (element is DocxImage) {
    // Images are encoded as PNG
    print('Image: ${element.bytes.length} bytes');
    // Use directly in Flutter: Image.memory(element.bytes)
  } else if (element is DocxTable) {
    print('Table: ${element.rows.length} rows');
  }
}

// Get all text as a single string
print(pdf.text);

Image Extraction

Images are automatically extracted and encoded as PNG:

final pdf = await PdfReader.loadFromBytes(pdfBytes);

// Quick access to all images
for (final img in pdf.images) {
  print('${img.width}x${img.height}, ${img.bytes.length} bytes');
  
  // Save to file
  await File('image_${pdf.images.indexOf(img)}.png')
      .writeAsBytes(img.bytes);
  
  // Use in Flutter
  // Image.memory(img.bytes)
}

// Images are also available in elements list as DocxImage
for (final element in pdf.elements) {
  if (element is DocxImage) {
    // element.bytes contains PNG data
  }
}

Supported Features

Feature Status
Text extraction βœ…
Text formatting (bold, italic) βœ…
Font detection βœ…
Font sizes and colors βœ…
Paragraph grouping βœ…
Images (JPEG, PNG, FlateDecode) βœ…
Table detection βœ… (beta)
Multi-page documents βœ…
PDF 1.4 standard format βœ…
PDF 1.5+ XRef streams βœ…
Object streams βœ…
FlateDecode compression βœ…
LZWDecode compression βœ…
ASCII85/ASCIIHex encoding βœ…

Limitations

  • Image-only (scanned) PDFs: If a PDF contains only images with no text operators, no text will be extracted. Consider using OCR separately.
  • Complex layouts: Multi-column layouts may not preserve exact positioning.
  • Vertical Text: Vertical writing modes are not yet supported.

Sections & Page Layout

final doc = DocxDocumentBuilder()
  .section(
    orientation: DocxPageOrientation.portrait,
    pageSize: DocxPageSize.a4,
    backgroundColor: DocxColor('#F0F8FF'),
    header: DocxHeader(children: [
      DocxParagraph.text('Company Name', align: DocxAlign.right),
    ]),
    footer: DocxFooter(children: [
      DocxParagraph.text('Page 1', align: DocxAlign.center),
    ]),
  )
  .h1('Document Title')
  .p('Content...')
  .build();

Multi-Section Documents

docx()
  .p('Portrait section content')
  .addSectionBreak(DocxSectionDef(
    orientation: DocxPageOrientation.portrait,
  ))
  .p('Landscape section content')
  .addSectionBreak(DocxSectionDef(
    orientation: DocxPageOrientation.landscape,
  ))
  .build();

Footnotes & Endnotes

Add academic citations and notes programmatically:

final doc = docx()
  .p('This statement needs a citation.')
  .addFootnote(DocxFootnote(
    footnoteId: 1,
    content: [
      DocxParagraph.text('Source: Official Documentation, 2024.'),
    ],
  ))
  .p('Unexpected finding.')
  .addEndnote(DocxEndnote(
    endnoteId: 1,
    content: [
      DocxParagraph.text('Further investigation required.'),
    ],
  ))
  .build();

Note: IDs must be unique. Word handles re-numbering automatically, but you must provide improved internal IDs for linking.


Font Embedding

Embed custom fonts with OOXML-compliant obfuscation:

import 'dart:io';

final fontBytes = await File('fonts/Roboto-Regular.ttf').readAsBytes();

final doc = DocxDocumentBuilder()
  .addFont('Roboto', fontBytes)
  .add(DocxParagraph(children: [
    DocxText('Custom font text', fontFamily: 'Roboto'),
  ]))
  .build();

Note: Fonts are automatically obfuscated per the OpenXML specification. High Fidelity: When reading existing documents, docx_creator preserves embedded fonts byte-for-byte, ensuring exact visual fidelity during round-trip edits.


API Reference

DocxDocumentBuilder

Method Parameters Description
h1(text) String text Add H1 heading
h2(text) String text Add H2 heading
h3(text) String text Add H3 heading
heading(level, text) DocxHeadingLevel, String Add heading at level
p(text, {align}) String, DocxAlign? Add paragraph
bullet(items) List<String> Add bullet list
numbered(items) List<String> Add numbered list
table(data, {hasHeader, style}) List<List<String>> Add table
pageBreak() - Add page break
hr() - Add horizontal rule
quote(text) String Add blockquote
code(code) String Add code block
add(node) DocxNode Add any node
addFont(name, bytes) String, Uint8List Embed font
section({...}) Various Set page properties
build() - Build document

DocxExporter / PdfExporter / MarkdownExporter / HtmlExporter

All four exporters share the same shape:

Method Parameters Description
exportToFile(doc, path) DocxBuiltDocument, String Save to file
exportToBytes(doc) DocxBuiltDocument Get as bytes (DocxExporter/PdfExporter)
export(doc) DocxBuiltDocument Get as a string (MarkdownExporter/HtmlExporter)

DocxReader

Method Parameters Description
load(path) String Load from file path
loadFromBytes(bytes) Uint8List Load from bytes

DocxParser

Method Parameters Description
fromHtml(html) String Parse HTML to nodes
fromMarkdown(md) String Parse Markdown to nodes

MarkdownParser

Method Parameters Description
parse(markdown) String Parse Markdown to nodes

Troubleshooting

Common Issues

Q: Fonts don't display correctly in Word

A: Ensure the font is embedded using addFont(). Embedded fonts are obfuscated per OpenXML spec.

Q: Images don't appear

A: Verify image bytes are valid and extension matches format (png, jpg, gif).

Q: Lists don't have bullets/numbers

A: Ensure you're using the fluent API (bullet(), numbered()) or properly structured DocxList with DocxListItem.

Q: Colors look wrong

A: Use 6-digit hex codes without # prefix for shadingFill. For DocxColor, you can use #RRGGBB or plain RRGGBB.


Examples

See the example/ directory for comprehensive examples:


License

MIT License - see LICENSE for details.

Contributing

Contributions welcome! Please read our contributing guidelines and submit PRs to the main repository.

Libraries

docx_creator
docx_creator - A developer-first DOCX generation library