SFDT to PDF
This page documents the pure-Dart path used when docx_editor or a backend service converts Syncfusion Document Text (SFDT) JSON into a PDF.
High-Level Flow
text
SFDT JSON string or map
-> SfdtReader.read / readMap
-> DocxBuiltDocument
-> PdfExporter.exportToBytes
-> PdfLayoutEngine
-> PdfLayoutDocument / paginated pages
-> PdfDocumentWriter
-> PDF bytesNo Syncfusion DocumentEditor web service and no .NET process are required for this path.
Minimal Example
dart
final document = const SfdtReader().read(sfdtJson);
final pdfBytes = PdfExporter(
creationDate: DateTime.utc(2026, 6, 20),
strictFonts: true,
).exportToBytes(document);What SfdtReader Preserves
SfdtReader converts Syncfusion JSON into DocxBuiltDocument.
| SFDT area | Model result |
|---|---|
| sections and blocks | DocxSectionDef, DocxSectionBreakBlock, body nodes |
| paragraphs and runs | DocxParagraph, DocxText, tabs, breaks, fields |
| tables | DocxTable, rows, cells, borders, margins, spans, widths |
| lists | DocxList and numbering data |
| headers and footers | section furniture |
| images | inline or block image nodes with relationship-backed bytes where present |
| comments | DocxComment and comment anchors where modeled |
| revisions | DocxRunRevision and revision metadata |
| protection | protection type, hash, salt, spin count, enforcement |
| custom XML | DocxCustomXml parts |
| document defaults | default run style through DocxTheme |
What PdfExporter Does
PdfExporter.exportToBytes:
- creates a
PdfDocumentWriter; - reads
w:defaultTabStopfrom settings XML, falling back to the OOXML default; - splits the document into sections;
- appends authored footnotes to the final section using the current simplified end-of-document behavior;
- builds a
PdfLayoutEnginefor each section using page geometry, margins, headers, footers, columns, document grid, and font configuration; - paginates content into pages or builds a
PdfLayoutDocumentfor multi-column layout; - renders page content, furniture, watermarks, images, and text streams;
- writes the PDF object graph and returns bytes.
Export Configuration
| Option | Purpose |
|---|---|
pageWidth, pageHeight | Default page size when the document does not override it. |
marginTop, marginBottom, marginLeft, marginRight | Default margins. |
fontSize | Default body font size. The default is 11pt to match Word defaults. |
compressContent | Compress PDF content streams. |
watermark | Optional diagonal watermark on every page. |
watermarkColorHex | Watermark fill color. |
watermarkOpacity | Watermark alpha in the PDF graphics state. |
creationDate | Fixed PDF creation timestamp for deterministic output. |
strictFonts | Throw when a glyph cannot be represented by registered fonts. |
registerFont | Add custom font bytes for rendering. |
Deterministic Rendering
For controlled workflows, pass a trusted UTC creationDate and enable strictFonts. This avoids client-clock leaks and prevents silent glyph loss in issued PDFs.
dart
final exporter = PdfExporter(
creationDate: trustedIssuedAt,
strictFonts: true,
watermark: 'CONTROLLED',
);
exporter.registerFont('Arial', arialBytes);
final bytes = exporter.exportToBytes(document);Known Simplification
Footnotes are currently appended to the end of the document with matching markers. They are not yet laid out at the bottom of each page because that would require reserving variable page-bottom space during pagination.