Creating Documents from Scratch
Creating a Basic Document
Using OpenXML SDK
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.IO;
public static void CreateBasicDocument(string filepath)
{
using (WordprocessingDocument doc = WordprocessingDocument.Create(
filepath, WordprocessingDocumentType.Document))
{
// Add main document part
MainDocumentPart mainPart = doc.AddMainDocumentPart();
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
// Add a paragraph with text
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text("Hello World!"));
// Save
mainPart.Document.Save();
}
}
AppraiSys Pattern: Default Document
From DefaultDocument.cs:
public static void CreateDefaultDocument(MemoryStream documentStream)
{
using (var document = WordprocessingDocument.Create(
documentStream,
WordprocessingDocumentType.Document,
true))
{
// 1. Create main document part
var mainPart = document.AddMainDocumentPart();
mainPart.Document = new Document();
var body = mainPart.Document.AppendChild(new Body());
// 2. Create styles part
var styleDefinitionsPart = mainPart.AddNewPart<StyleDefinitionsPart>();
var styles = new Styles();
styleDefinitionsPart.Styles = styles;
// 3. Add document defaults
CreateDocDefaults(styles);
// 4. Add standard styles
CreateParagraphStyle(styles, "Normal", "Normal", 99);
CreateParagraphStyle(styles, "Heading1", "Heading 1", 98, "Normal");
CreateParagraphStyle(styles, "Heading2", "Heading 2", 97, "Normal");
CreateCharacterStyle(styles, "DefaultParagraphFont", "Default Paragraph Font", 0);
CreateTableStyle(styles, "NormalTable", "Normal Table", 99);
// 5. Create numbering part
var numberingDefinitionsPart = mainPart.AddNewPart<NumberingDefinitionsPart>();
numberingDefinitionsPart.Numbering = new Numbering();
mainPart.Document.Save();
}
}
Document Defaults
private static void CreateDocDefaults(Styles styles)
{
var docDefaults = new DocDefaults();
// Run defaults
var runPropertiesDefault = new RunPropertiesDefault();
var runPropertiesBaseStyle = new RunPropertiesBaseStyle();
runPropertiesBaseStyle.AppendChild(new RunFonts
{
Ascii = "Times New Roman",
HighAnsi = "Times New Roman",
EastAsia = "Times New Roman",
ComplexScript = "Times New Roman"
});
runPropertiesBaseStyle.AppendChild(new FontSize { Val = "22" }); // 11pt
runPropertiesBaseStyle.AppendChild(new FontSizeComplexScript { Val = "22" });
runPropertiesBaseStyle.AppendChild(new Languages
{
Val = "en-US",
EastAsia = "en-US",
Bidi = "ar-SA"
});
runPropertiesDefault.AppendChild(runPropertiesBaseStyle);
docDefaults.AppendChild(runPropertiesDefault);
// Paragraph defaults
var paragraphPropertiesDefault = new ParagraphPropertiesDefault();
var paragraphPropertiesBaseStyle = new ParagraphPropertiesBaseStyle();
paragraphPropertiesBaseStyle.AppendChild(new SpacingBetweenLines
{
After = "0",
Line = "276",
LineRule = LineSpacingRuleValues.Auto
});
paragraphPropertiesDefault.AppendChild(paragraphPropertiesBaseStyle);
docDefaults.AppendChild(paragraphPropertiesDefault);
styles.AppendChild(docDefaults);
}
Creating Paragraph Styles
private static void CreateParagraphStyle(
Styles styles,
string styleId,
string styleName,
int uiPriority,
string basedOn = null)
{
var style = new Style
{
Type = StyleValues.Paragraph,
StyleId = styleId
};
style.AppendChild(new Name { Val = styleName });
style.AppendChild(new UIPriority { Val = uiPriority });
if (basedOn != null)
{
style.AppendChild(new BasedOn { Val = basedOn });
}
// Style-specific properties
if (styleId == "Heading1")
{
var paragraphProperties = new ParagraphProperties();
paragraphProperties.AppendChild(new KeepNext());
paragraphProperties.AppendChild(new KeepLines());
paragraphProperties.AppendChild(new SpacingBetweenLines
{
Before = "240",
After = "120"
});
paragraphProperties.AppendChild(new OutlineLevel { Val = 0 });
style.AppendChild(paragraphProperties);
var runProperties = new RunProperties();
runProperties.AppendChild(new Bold());
runProperties.AppendChild(new FontSize { Val = "32" }); // 16pt
style.AppendChild(runProperties);
}
styles.AppendChild(style);
}
Creating Table Styles
AppraiSys NormalTable
private static void CreateTableStyle(
Styles styles,
string styleId,
string styleName,
int uiPriority)
{
var style = new Style
{
Type = StyleValues.Table,
StyleId = styleId
};
style.AppendChild(new Name { Val = styleName });
style.AppendChild(new UIPriority { Val = uiPriority });
var tableProperties = new TableProperties();
// Table indentation
tableProperties.AppendChild(new TableIndentation
{
Width = 0,
Type = TableWidthUnitValues.Dxa
});
// Cell margins
tableProperties.AppendChild(new TableCellMarginDefault(
new TopMargin { Width = "0", Type = TableWidthUnitValues.Dxa },
new TableCellLeftMargin { Width = 108, Type = TableWidthValues.Dxa },
new BottomMargin { Width = "0", Type = TableWidthUnitValues.Dxa },
new TableCellRightMargin { Width = 108, Type = TableWidthValues.Dxa }
));
style.AppendChild(tableProperties);
// Table row properties
style.AppendChild(new TableRowProperties(
new CantSplit() // Keep rows together
));
styles.AppendChild(style);
}
PropertyImagesTable Style
private static Style CreatePropertyImagesTableStyle()
{
var style = new Style
{
Type = StyleValues.Table,
StyleId = "PropertyImagesTable"
};
style.AppendChild(new Name { Val = "Property Images Table" });
style.AppendChild(new UIPriority { Val = 50 });
var tableProperties = new TableProperties();
// Center table
tableProperties.AppendChild(new TableJustification
{
Val = TableRowAlignmentValues.Center
});
// Cell spacing (gap between cells)
tableProperties.AppendChild(new TableCellSpacing
{
Width = "100",
Type = TableWidthUnitValues.Dxa
});
// No borders
tableProperties.AppendChild(new TableBorders(
new TopBorder { Val = BorderValues.None },
new BottomBorder { Val = BorderValues.None },
new LeftBorder { Val = BorderValues.None },
new RightBorder { Val = BorderValues.None },
new InsideHorizontalBorder { Val = BorderValues.None },
new InsideVerticalBorder { Val = BorderValues.None }
));
// Zero cell margins
tableProperties.AppendChild(new TableCellMarginDefault(
new TopMargin { Width = "0", Type = TableWidthUnitValues.Dxa },
new TableCellLeftMargin { Width = 0, Type = TableWidthValues.Dxa },
new BottomMargin { Width = "0", Type = TableWidthUnitValues.Dxa },
new TableCellRightMargin { Width = 0, Type = TableWidthValues.Dxa }
));
style.AppendChild(tableProperties);
// Cell properties
var tableCellProperties = new TableCellProperties();
tableCellProperties.AppendChild(new VerticalMerge
{
Val = MergedCellValues.Continue
});
tableCellProperties.AppendChild(new TableCellVerticalAlignment
{
Val = TableVerticalAlignmentValues.Top
});
style.AppendChild(tableCellProperties);
return style;
}
Creating Character Styles
private static void CreateCharacterStyle(
Styles styles,
string styleId,
string styleName,
int uiPriority)
{
var style = new Style
{
Type = StyleValues.Character,
StyleId = styleId,
Default = true
};
style.AppendChild(new Name { Val = styleName });
style.AppendChild(new UIPriority { Val = uiPriority });
styles.AppendChild(style);
}
Creating Numbering Styles
AppraiSys Bullet List
private static void CreateNumberingStyle(
Styles styles,
string styleId,
string styleName,
int abstractNumId)
{
var style = new Style
{
Type = StyleValues.Numbering,
StyleId = styleId
};
style.AppendChild(new Name { Val = styleName });
style.AppendChild(new UIPriority { Val = 99 });
style.AppendChild(new BasedOn { Val = "Normal" });
var paragraphProperties = new ParagraphProperties();
paragraphProperties.AppendChild(new NumberingProperties(
new NumberingId { Val = abstractNumId }
));
style.AppendChild(paragraphProperties);
styles.AppendChild(style);
}
Numbering Definition
public static void CreateBulletList(NumberingDefinitionsPart numberingPart)
{
// Abstract numbering definition
var abstractNum = new AbstractNum { AbstractNumberId = 0 };
abstractNum.AppendChild(new MultiLevelType { Val = MultiLevelValues.HybridMultilevel });
// Level 0 (bullet)
var level0 = new Level { LevelIndex = 0 };
level0.AppendChild(new StartNumberingValue { Val = 1 });
level0.AppendChild(new NumberingFormat { Val = NumberFormatValues.Bullet });
level0.AppendChild(new LevelText { Val = "●" });
level0.AppendChild(new LevelJustification { Val = LevelJustificationValues.Left });
var previousParagraphProperties = new PreviousParagraphProperties();
previousParagraphProperties.AppendChild(new Indentation
{
Left = "720",
Hanging = "360"
});
level0.AppendChild(previousParagraphProperties);
var numberingSymbolRunProperties = new NumberingSymbolRunProperties();
numberingSymbolRunProperties.AppendChild(new RunFonts
{
Ascii = "Symbol",
HighAnsi = "Symbol",
Hint = FontTypeHintValues.Default
});
level0.AppendChild(numberingSymbolRunProperties);
abstractNum.AppendChild(level0);
numberingPart.Numbering.AppendChild(abstractNum);
// Numbering instance
var numberingInstance = new NumberingInstance { NumberID = 1 };
numberingInstance.AppendChild(new AbstractNumId { Val = 0 });
numberingPart.Numbering.AppendChild(numberingInstance);
}
Adding Content
Add Simple Paragraph
public static Paragraph CreateParagraph(string text, string style = null)
{
var paragraph = new Paragraph();
if (style != null)
{
var paragraphProperties = new ParagraphProperties();
paragraphProperties.AppendChild(new ParagraphStyleId { Val = style });
paragraph.AppendChild(paragraphProperties);
}
var run = new Run();
run.AppendChild(new Text(text));
paragraph.AppendChild(run);
return paragraph;
}
Add Formatted Text
public static Paragraph CreateFormattedParagraph(
string text,
bool bold = false,
bool italic = false,
string color = null,
int? fontSize = null,
JustificationValues alignment = JustificationValues.Left)
{
var paragraph = new Paragraph();
// Paragraph properties
var paragraphProperties = new ParagraphProperties();
paragraphProperties.AppendChild(new Justification { Val = alignment });
paragraph.AppendChild(paragraphProperties);
// Run
var run = new Run();
// Run properties
var runProperties = new RunProperties();
if (bold)
runProperties.AppendChild(new Bold());
if (italic)
runProperties.AppendChild(new Italic());
if (color != null)
runProperties.AppendChild(new Color { Val = color });
if (fontSize.HasValue)
runProperties.AppendChild(new FontSize { Val = (fontSize.Value * 2).ToString() });
run.AppendChild(runProperties);
run.AppendChild(new Text(text));
paragraph.AppendChild(run);
return paragraph;
}
Complete Example: AppraiSys Report Template
public static MemoryStream CreateReportTemplate()
{
var stream = new MemoryStream();
using (var document = WordprocessingDocument.Create(
stream, WordprocessingDocumentType.Document, true))
{
var mainPart = document.AddMainDocumentPart();
mainPart.Document = new Document();
var body = mainPart.Document.AppendChild(new Body());
// Add styles
var stylesPart = mainPart.AddNewPart<StyleDefinitionsPart>();
var styles = new Styles();
CreateDocDefaults(styles);
CreateParagraphStyle(styles, "Normal", "Normal", 99);
CreateParagraphStyle(styles, "Heading1", "Heading 1", 98, "Normal");
CreateParagraphStyle(styles, "Heading2", "Heading 2", 97, "Normal");
CreateTableStyle(styles, "NormalTable", "Normal Table", 99);
stylesPart.Styles = styles;
// Add content
body.AppendChild(CreateParagraph("Appraisal Report", "Heading1"));
body.AppendChild(CreateParagraph("")); // Empty paragraph
// Property information section
body.AppendChild(CreateParagraph("Property Information", "Heading2"));
// Add content control for address
var sdt = CreateContentControl("PropertyAddress", "Property Address");
body.AppendChild(sdt);
// Add table
var table = CreatePropertyInfoTable();
body.AppendChild(table);
mainPart.Document.Save();
}
stream.Position = 0;
return stream;
}
Helper: Create Content Control
public static SdtBlock CreateContentControl(string tag, string alias)
{
var sdtBlock = new SdtBlock();
// Properties
var sdtProperties = new SdtProperties();
sdtProperties.AppendChild(new Tag { Val = tag });
sdtProperties.AppendChild(new Alias { Val = alias });
sdtProperties.AppendChild(new SdtId { Val = GenerateUniqueId() });
sdtBlock.AppendChild(sdtProperties);
// Content
var sdtContent = new SdtContentBlock();
var paragraph = new Paragraph();
var run = new Run();
run.AppendChild(new Text("[" + alias + "]"));
paragraph.AppendChild(run);
sdtContent.AppendChild(paragraph);
sdtBlock.AppendChild(sdtContent);
return sdtBlock;
}
private static int GenerateUniqueId()
{
return new Random().Next(100000, 999999);
}
Next Steps
➡️ Next: Table Creation
Related:
💡 Remember: Always create styles part before adding styled content. Default document setup is critical for consistency!