夜雨聆风学习资料网

ARTICLE · 986306

Excel打不开20万行怎么办?C#流式读取实战

Excel打不开20万行怎么办?C#流式读取实战

上个月帮朋友处理一批销售数据,文件打开那一刻 Excel 直接闪退了。

文件多大?70万行,47MB。行数超了 Excel 的上限(1,048,576行),而且字段类型混乱——日期有的是"2023-01-01",有的是"2023/1/1",有的是"2023年1月1日"。

他说"以前用 Access 能跑,后来 Access 也崩了"。

这种文件,一般程序员会说"拆成多个文件处理"。但我不想每次手动拆、每次合并——这个工作以后每个月都要跑一次。

我决定写一套数据处理框架。


第一层:流式读取

第一步是读文件。传统方式是把整个文件加载到内存再处理,70万行直接爆掉。

我用的方案是 ZipArchive + XmlReader SAX 解析——不需要把整个 Excel 加载到内存,每次只读一行,处理完就丢掉。读取70万行,内存峰值不超过 10MB。

关键代码长这样:

using var reader = new StreamingExcelReader(”sales.xlsx”);reader.Accumulate = false; // 关闭内存累积,纯流式reader.OnRow = (rowIdx, cells) =>{    // 边读边处理,读完一行处理一行    ProcessRow(cells);};reader.Open();

Accumulate = false 是关键。打开后内部不会维护任何行集合,每读一行触发一次 OnRow 回调,数据处理完就直接丢弃,内存始终保持恒定。


第二层:SQLite in-memory 做查询引擎

读完的数据不能一直放内存——下次查询还要用。传统方案是写回数据库文件,但频繁读写磁盘也慢。

我的方案是直接用 SQLite in-memory 模式:数据进内存后立即导入一张临时表,用 SQL 做过滤、分组、聚合。查询完了数据还在内存,下一次查询直接复用,不需要重新读文件。

await DataConverter.ImportToSqliteAsync(data, engine);var result = await DataConverter.ExportFromSqliteAsync(    engine,    ”SELECT region, SUM(amount) FROM sales GROUP BY region”);

整个流水线:流式读取 → 内存表 → SQLite 查询 → 结果返回,不需要写磁盘,不需要维护数据库服务。


第三层:MessagePack 序列化

有时候数据需要缓存,或者跨进程传输。最直接的方案是 JSON,但 JSON 对二进制数据和中文支持都不算友好,而且体积偏大。

我用的是 MessagePack——二进制序列化格式,比 JSON 小 30-50%,序列化速度也更快。最关键的是它支持零反射的 IL 生成,不需要用 Newtonsoft.Json 那种反射方案,GC 压力小很多。

// 序列化(RsData → byte[])var bytes = RsDataSerializer.Serialize(result);// 反序列化(byte[] → RsData)var restored = RsDataSerializer.Deserialize(bytes);

完整流水线

这套组合拳打下来,处理 70万行 Excel 的完整流程:

  1. 流式读取:内存峰值 < 10MB,不崩盘
  2. SQLite in-memory:查询直接在内存跑,不用磁盘 IO
  3. MessagePack:缓存和传输都用二进制,体积小速度快
.xlsx 文件  │  ▼ 流式读取(内存 < 10MB)RsData 内存表  │  ├──► SQLite in-memory 查询(直接 SQL,不需要磁盘)  │       │  │       ▼  │     结果 RsData  │  └──► MessagePack 序列化(缓存/传输用二进制)

这套架构不是专门给 Excel 用的——DBF 文件、CSV、任何结构化数据源,只要符合"大文件+需要反复查询"这个特征,都能用这套思路处理。


副业视角

说完技术说钱。

这套东西能接的活,大致两类:

一是帮小工厂/小公司处理历史数据。很多小公司有十几年积累的 Excel/CSV 数据,老板想查某个供应商5年的供货记录,业务员说"查不了"——Excel 根本打不开。这种活儿报价 2000-4000 一次,月跑一次的话月费 800-1200。

二是帮别人做数据迁移。有些公司要从旧的 Access/FoxPro 系统迁移到新的 ERP,数据格式老旧没人敢碰,用这套流式处理方案反而比大多数方案都稳。


往期相关:

  • 《技术文档中文化渠道清单:我靠这5个地方接到单》
  • 《技术文档中文化,这3个坑我劝你别踩》

你平时处理大文件时,有没有被 Excel 崩过?用的什么办法?评论区聊聊。

如果这篇对你有用,点个「在看」让更多同行看到 👇

关注我,每周分享程序员可落地的副业方向。

相关学习资料