API
DocxReader — read, modify, write
Added in 1.3.0, DocxReader parses an existing DOCX file into a DocxDocument — enabling a full round-trip: read, modify with the normal mutation API, then write back out. It reads files created by Microsoft Word and other DOCX-compatible applications.
class DocxReader {
const DocxReader();
DocxDocument read(Uint8List bytes)
}Read a document and walk its content in order:
final reader = DocxReader();
final document = reader.read(docxBytes);
for (final item in document.content) {
if (item is DocxParagraph) {
print(item.plainText);
}
}The test suite exercises the round-trip with two one-liners — generate bytes, then read them straight back:
Uint8List generate(DocxDocument doc) => generator.generate(doc);
DocxDocument roundTrip(DocxDocument doc) => reader.read(generate(doc));Put together, a read → modify → write cycle looks like this (composed from the documented read, addParagraph and generate calls):
// Read an existing DOCX into a document model
final document = DocxReader().read(docxBytes);
// Modify it with the normal mutation API
document.addParagraph(Paragraph.heading('Appendix', level: 1));
document.addParagraph(Paragraph.text('Added after reading.'));
// Write it back out
final updated = DocxGenerator().generate(document);What the reader preserves
- All paragraph styles: headings 1-4, subtitle, caption, quote, code block, footnote
- Text formatting: bold, italic, underline, strikethrough, color, background color
- Alignment
- Lists (bullet, dash, numbered, alpha, roman) with indent levels
- Tables with borders, colspan, rowspan and cell properties
- External hyperlinks and internal bookmark references
- Page breaks and line breaks
- Mixed content order
- Document metadata (title, author) from docProps/core.xml
Parsing failures throw a sealed DocxReaderException, so you can switch on the concrete cause:
sealed class DocxReaderException implements Exception
class InvalidDocxArchiveException extends DocxReaderException // not a valid ZIP archive
class MissingDocxPartException extends DocxReaderException // Missing required DOCX part: $partName
class InvalidDocxXmlException extends DocxReaderException // Malformed XML in DOCXHeads up
The reader degrades gracefully: a missing styles.xml or numbering.xml falls back to default mappings, and unknown styles fall back to normal. Some content is skipped, however:
- Images (
<w:drawing>) are skipped - Charts and embedded objects are skipped
- Complex fields (TOC) are skipped
- Column widths are not preserved
Document
DocxDocument (alias Document) is the root container. Add content with addParagraph, addParagraphs and addTable; read it back via the content getter, which returns paragraphs and tables in insertion order.
| Parameter | Type | Default |
|---|---|---|
paragraphs | List<DocxParagraph>? | — |
title | String? | — |
author | String? | — |
includeTableOfContents | bool | false |
tocTitle | String | 'Table of Contents' |
tocMaxLevel | int | 3 |
Paragraph & TextRun
DocxParagraph (alias Paragraph) holds a list of runs plus block-level properties. The named factories — .text, .heading, .subtitle, .caption, .quote, .codeBlock, .footnote, .bulletItem, .dashItem, .numberedItem, .alphaItem, .romanItem and .empty — wrap this constructor. plainText joins the run texts.
| Parameter | Type | Default |
|---|---|---|
runs | List<DocxRun> | required |
style | DocxParagraphStyle | normal |
alignment | DocxAlignment | left |
pageBreakBefore | bool | false |
indentLevel | int | 0 |
bookmarkName | String? | — |
DocxRun (alias TextRun) is a span of text with inline formatting. TextRun.lineBreak() is a convenience for a soft return; getters isLink and hasFormatting and a copyWith method round it out.
| Parameter | Type | Default |
|---|---|---|
text | String | required |
bold | bool | false |
italic | bool | false |
underline | bool | false |
strikethrough | bool | false |
color | String? | — |
backgroundColor | String? | — |
hyperlink | String? | — |
bookmarkRef | String? | — |
isLineBreak | bool | false |
Table, TableRow & TableCell
DocxTable takes rows and table-level borders; columnCount and rowCount getters account for spans. Factories DocxTable.simple and DocxTable.fromHeaders build tables from plain data.
| Parameter | Type | Default |
|---|---|---|
rows | List<DocxTableRow> | required |
borders | DocxTableBorders | DocxTableBorders.all() |
columnWidths | List<double>? | — |
DocxTableRow is a thin wrapper around its cells:
| Parameter | Type | Default |
|---|---|---|
cells | List<DocxTableCell> | required |
DocxTableCell carries paragraphs, alignment, backgrounds, per-cell borders and merge spans. DocxTableCell.text is a shorthand for a single-string cell, and DocxTableCell.merged() is the continuation placeholder for a rowSpan merge.
| Parameter | Type | Default |
|---|---|---|
paragraphs | List<DocxParagraph> | const [] |
alignment | DocxAlignment | left |
verticalAlignment | DocxVerticalAlignment | top |
backgroundColor | String? | — |
borders | DocxCellBorders? | — |
colSpan | int | 1 |
rowSpan | int | 1 |
isMergedContinuation | bool | false |
Borders share the DocxBorder model (width in eighths of a point), and the alignment, vertical-alignment and style enums are:
const DocxBorder({
this.color = '000000',
this.size = 4,
this.style = DocxBorderStyle.single,
});enum DocxAlignment { left, center, right, justify } // justify -> OOXML 'both'
enum DocxVerticalAlignment { top, center, bottom }
enum DocxBorderStyle { single, double, dashed, dotted }
enum DocxParagraphStyle {
normal, heading1, heading2, heading3, heading4,
subtitle, caption, quote, codeBlock, footnote,
listBullet, listDash, listNumber, listNumberAlpha, listNumberRoman,
}Generators & PDF options
Both generators implement DocumentGenerator and return Uint8List bytes.
abstract class DocumentGenerator {
Uint8List generate(DocxDocument document);
}DocxGenerator defaults to Times New Roman at 24 half-points (12pt). DOCX font sizes are half-points:
DocxGenerator({
this.fontName = 'Times New Roman',
this.fontSize = 24, // half-points (24 = 12pt, 28 = 14pt)
})| Value | Point size | Typical use |
|---|---|---|
20 | 10pt | Footnotes |
22 | 11pt | Compact body |
24 | 12pt | Standard body |
28 | 14pt | Subheadings |
32 | 16pt | Section headings |
48 | 24pt | Titles |
PdfGenerator works in points and exposes page size and margins. Its font must be one of the PDF base-14 fonts (Helvetica, Times-Roman, Courier).
| Parameter | Type | Default |
|---|---|---|
fontName | String | 'Helvetica' |
fontSize | int | 12 |
pageWidth | int | 612 |
pageHeight | int | 792 |
marginTop | int | 72 |
marginBottom | int | 72 |
marginLeft | int | 72 |
marginRight | int | 72 |
Source vs doc/api.md
Where the published doc/api.md disagrees with the source, the source above is authoritative: fontSize is an int (not a double) and PdfGenerator carries the page and margin parameters; Table defaults to DocxTableBorders.all() (not none()); and DocxBorderStyle has no thick value.
Type aliases
The Docx-prefixed classes are exported under format-agnostic aliases, which is why the examples use Document, Paragraph and TextRun rather than their full names. Both spellings refer to the same class.
| Alias | Original class |
|---|---|
Document | DocxDocument |
Paragraph | DocxParagraph |
TextRun | DocxRun |
Alignment | DocxAlignment |
ParagraphStyle | DocxParagraphStyle |
Table | DocxTable |
TableRow | DocxTableRow |
TableCell | DocxTableCell |
TableBorders | DocxTableBorders |
Border | DocxBorder |
BorderStyle | DocxBorderStyle |
CellBorders | DocxCellBorders |
VerticalAlignment | DocxVerticalAlignment |
DocumentReader | DocxReader |
