Write Excel files
DocWright.Formats.Xlsx writes Excel workbooks: typed cells, number formats, fonts, fills, borders, merged ranges, column widths, frozen panes, outlines, autofilter and images. It has no dependencies, and the same workbook always produces the same bytes.
dotnet add package DocWright.Formats.Xlsx
A workbook
using DocWright.Core.Primitives;
using DocWright.Formats.Xlsx;
var book = new XlsxWorkbook();
var sheet = new XlsxWorksheet("Sales");
sheet.Columns.Add(new XlsxColumn(1, 1, 24m)); // column A, width in characters
sheet.Columns.Add(new XlsxColumn(2, 3, 14m)); // columns B-C
XlsxCellStyle header = XlsxCellStyle.Default.With(
bold: true,
backgroundColor: ColorRgb.FromRgb(0xEE, 0xF2, 0xFF),
bottomBorder: new XlsxBorder(XlsxBorderStyle.Thin, ColorRgb.FromRgb(0x1E, 0x3A, 0x8A)));
XlsxCellStyle money = XlsxCellStyle.Default.With(numberFormat: "#,##0.00");
XlsxCellStyle date = XlsxCellStyle.Default.With(numberFormat: "d mmm yyyy");
var heading = new XlsxRow(1);
heading.Cells.Add(new XlsxCell(1, XlsxCellValue.Text("Region"), header));
heading.Cells.Add(new XlsxCell(2, XlsxCellValue.Text("Revenue"), header));
heading.Cells.Add(new XlsxCell(3, XlsxCellValue.Text("Closed"), header));
sheet.Rows.Add(heading);
(string Region, decimal Revenue, DateTime Closed)[] data =
[
("Auckland", 182_000m, new DateTime(2026, 9, 30)),
("Wellington", 264_500m, new DateTime(2026, 9, 28)),
("Canterbury", 200_750m, new DateTime(2026, 9, 29)),
];
int r = 2;
foreach (var (region, revenue, closed) in data)
{
var row = new XlsxRow(r++);
row.Cells.Add(new XlsxCell(1, XlsxCellValue.Text(region)));
row.Cells.Add(new XlsxCell(2, XlsxCellValue.Number(revenue), money)); // a real number: it sums
row.Cells.Add(new XlsxCell(3, XlsxCellValue.Date(closed), date));
sheet.Rows.Add(row);
}
sheet.FrozenRows = 1; // keep the header visible while scrolling
book.Worksheets.Add(sheet);
using (FileStream output = File.Create("sales.xlsx"))
{
XlsxWriter.Write(book, output);
}
Download the result: sales.xlsx.
Values, not text
XlsxCellValue is Text, Number, Boolean, Date, Error or Blank. A Number with a #,##0.00 format displays like the formatted text and sums in Excel. Text that looks like a number sums to zero.
- Numbers are
decimal. Adoubleis rounded to 15 significant digits, the precision Excel displays, so output is identical on .NET Framework and .NET. Datestores Excel's serial number, including Excel's 1900 leap-year quirk, so dates agree with Excel's own. A cell displays as a date only when its style has a date format.
Rules enforced up front
Sheet names must be 1–31 characters, without : \ / ? * [ ]. XlsxWorksheet throws for an invalid name, and XlsxSheetName.Normalize(text, fallback) and XlsxSheetName.MakeUnique(name, taken) produce valid ones from any text.
XlsxWriteSettings.MaxOutputBytes caps the output size, for workbooks whose size depends on data you don't control.
Not supported
Formulas, pivot tables, charts, conditional formatting, data validation, comments and macros. There is no XLSX reader.
Tip
To export a report to Excel, with number formats, grouping outlines and charts as pictures, use ReportXlsxExporter from DocWright.Reporting.Export, which builds on this writer. See Run an SSRS report.