Create a document with the DOM
The DocWright.Dom.Editing namespace adds extension methods that create content in a WordDocument. Add one using and every section, paragraph, table cell, header and note gains Append… methods. Each returns the node it created, so calls chain.
Tip
Which API should I use? Use this one to add content to a document you loaded, or when you need Word's exact structure. Use Composition to lay out a whole document from scratch with a fluent, high-level API. Composition produces the same WordDocument underneath.
Build a document
using DocWright;
using DocWright.Core.Document;
using DocWright.Core.Primitives;
using DocWright.Dom;
using DocWright.Dom.Editing;
using var document = new WordDocument();
Section section = document.AppendSection();
// Text, with direct formatting on one run.
Paragraph title = section.AppendParagraph("Site inspection report");
title.ApplyFormatting(new ParagraphFormat { KeepNext = true });
title.AppendText(" (draft)", new CharacterFormat { Italic = true });
// A table. The column width is required: Word's table grid needs it. Every new cell
// already holds one empty paragraph, so write into it rather than appending another.
Table table = section.AppendTable(rowCount: 3, columnCount: 2, columnWidth: Twips.FromInches(2.5));
string[,] cells = { { "Site", "Wharf Street depot" }, { "Inspector", "R. Ngata" }, { "Result", "Passed" } };
for (int r = 0; r < 3; r++)
{
((Paragraph)table.Rows[r].Cells[0].Blocks[0]).AppendText(cells[r, 0], new CharacterFormat { Bold = true });
((Paragraph)table.Rows[r].Cells[1].Blocks[0]).AppendText(cells[r, 1]);
}
// A bookmark, a link to it, an external link, a tab and an image.
Paragraph links = section.AppendParagraph();
links.AppendBookmark("summary");
links.AppendText("Summary");
links.AppendTab();
links.AppendHyperlink("docs.albahadly.com", "https://docs.albahadly.com");
Paragraph back = section.AppendParagraph();
back.AppendInternalHyperlink("Back to the summary", anchor: "summary");
Paragraph picture = section.AppendParagraph();
picture.AppendImage(File.ReadAllBytes("thumbnail.png"), "image/png",
Emu.FromInches(1.6), Emu.FromInches(2.07), name: "Letter", description: "Thumbnail of the letter");
// A page break, then more content on page 2.
section.AppendParagraph().AppendBreak(BreakKind.Page);
section.AppendParagraph("Appendix");
using (FileStream docx = File.Create("inspection.docx"))
{
converter.Save(document, docx);
}

What to know
- Nothing is filled in for you. A new paragraph has no formatting of its own, so it inherits from its style and the document defaults, just as Word's own content does. Pass a
CharacterFormatorParagraphFormatonly for what you want to change. A helper that wrote concrete defaults would cut that inheritance. - A new document has no styles.
new WordDocument()starts with an empty style table (document.Styles.Countis 0), soApplyStyle("Heading1")fails until you add the style. See Styles and formatting, or start from a template.docxthat already has the styles you want. - A tab is an element. Use
AppendTab(). A'\t'inside text is only whitespace to Word, and the tab stop is lost. - Tables need a column width. Word's table grid requires one, so it's a parameter rather than a hidden default.
- Images are copied in.
AppendImagestores the bytes in the document, so the source file can go away. - The same methods work everywhere.
AppendParagraphandAppendTableexist onWordDocument,Section,TableCell,HeaderFooterandNote, so the same calls build body text, headers, footnotes and nested tables. - Tables get a guide of their own: Work with tables covers borders, header rows, merged cells, and inserting, moving and deleting rows and columns.
- One thread per document. The document model is not thread-safe. Different documents can be edited on different threads.
Units
| Type | Unit | Create with |
|---|---|---|
Twips |
1/20 of a point, used for lengths, indents and spacing | Twips.FromPoints(12), Twips.FromInches(1), Twips.FromCentimeters(2.5) |
Emu |
1/914,400 of an inch, used for images and shapes | Emu.FromInches(2), Emu.FromCentimeters(5) |
Both live in DocWright.Core.Primitives. See Units and measurements.