Table of Contents

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);
}
inspection.docx, rendered
The created document: a title with italic suffix, a two-column table, links and an inserted thumbnail image
Download: inspection.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 CharacterFormat or ParagraphFormat only 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.Count is 0), so ApplyStyle("Heading1") fails until you add the style. See Styles and formatting, or start from a template .docx that 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. AppendImage stores the bytes in the document, so the source file can go away.
  • The same methods work everywhere. AppendParagraph and AppendTable exist on WordDocument, Section, TableCell, HeaderFooter and Note, 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.