| name |
project-mtp-excel-csv-stack |
| description |
Excel and CSV library choices for reports, import, export. Layered by use case. EPPlus banned. |
| metadata |
|
Native-library-only policy ([[feedback-reports-native-libs]]) — no HTML→XLSX, no Puppeteer. Picks below are layered by use case.
| Use case |
Library |
Reason |
| Large export (>50k rows), bulk, server under load |
DocumentFormat.OpenXml |
Streaming SAX API (OpenXmlReader/OpenXmlWriter), fastest, lowest memory. Verbose — wrap with helpers. |
| Rich-formatted small/medium files (invoices, mark sheets, formatted summaries) |
ClosedXML |
DOM API over OpenXml SDK. Easy styles/formulas. Memory-heavy above ~100k rows. |
Read legacy .xls (BIFF8) — read + write |
NPOI |
Apache POI port. Supports HSSF (.xls) and XSSF (.xlsx). Apache-2.0. |
Read-only ingest (.xls or .xlsx) |
ExcelDataReader |
Fast read-only, handles both formats + CSV. MIT. |
Banned: EPPlus. Dual-license trap (commercial license for business use since v5). Also no .xls support.
| Use case |
Library |
Reason |
| Default — import/export, mapping, type converters |
CsvHelper (Josh Close) |
De facto standard. Attribute + fluent mapping. RFC 4180. Apache-2.0. Mature, well-documented. |
| Hot path — millions of rows, ETL, profiling shows CSV is bottleneck |
Sep or Sylvan.Data.Csv |
Sep = SIMD, fastest published benchmarks. Sylvan = DbDataReader API, drops into NpgsqlBinaryImporter / bulk copy. Both MIT. |
How to apply:
- Reach for CsvHelper first. Only swap to Sep/Sylvan after profiler points at CSV.
- For Postgres bulk load, Sylvan's
DbDataReader pairs cleanly with NpgsqlBinaryImporter — preferred for million-row ingest.
- Excel renderer in report layer should pick OpenXml vs ClosedXML based on row count + formatting need, not preference.