Filling templates
Design the report in Excel (logo, colours, a styled header row, totals, charts, print settings) and let SheetStream pour the data in. Everything you do not touch is copied from the template unchanged.
using SheetStream;
using var package = ExcelPackage.OpenTemplate("invoice-template.xlsx", "invoice-1042.xlsx");
var sheet = package.Workbook.Worksheets.Open("Lines");
// Reuse the formatting the designer gave the first data row.
var money = sheet.TemplateStyle("D5");
var row = 5;
foreach (var line in invoice.Lines)
sheet.Row(row++).WriteCell(line.Sku).WriteCell(line.Description).WriteCell(line.Qty).WriteCell(line.Amount, money);
package.Save();
How rows merge with the template
- Template rows above your first row are kept: titles, logos, the header row.
- Each row you write replaces the template row with the same number. A formatted but empty row (the usual "first data row") is simply replaced.
- Template rows below your last row are kept, so leave room for footers.
sheet.ReplacedTemplateRowstells you how many template rows that held values were overwritten, so you can detect a footer that the data ran into. - Rows stream, so a template can receive a million rows with flat memory.
What stretches automatically
When a template range starts in the header row or the first data row and ends before your last row, SheetStream extends it to cover the data:
| In the template | After filling 100 rows from row 5 |
|---|---|
Table A4:D5 |
A4:D104 |
Table filter A4:D5 |
A4:D104 |
Data validation on C5 |
C5:C104 |
Conditional format on D5 |
D5:D104 |
Formulas such as =SUM(Lines[Amount]) follow the table, and the workbook is set to recalculate when opened, so totals are correct immediately. Tables with a totals row are left as they are, because the data would run into it.
What comes from the template
Column widths, frozen panes, sheet protection, merged cells, validation and formatting rules, charts and pictures belong to the template. Changing them on a template sheet throws NotSupportedException with a message pointing you back to Excel. New sheets cannot be added either; add them to the template.
New cell styles are fine: package.Workbook.Styles.Create(...) appends to the template's style table without disturbing the existing styles.
Untrusted templates
Templates are parsed with DTD processing and external entities disabled. The template file is never modified: OpenTemplate refuses to write to the same path it reads.