当前位置:

首页 > 编程开发 > C#中使用MiniExcel读写.xlsx文件的代码实现

C#中使用MiniExcel读写.xlsx文件的代码实现

MiniExcel是一款轻量级、无Office依赖的.NET库,直接操作.xlsx文件。提供基础读写、分批写入优化、模板生成报表、样式设置及合并单元格读取等功能,性能高效,内存占用低,易于集成,支持导出数据表,适合中小数据量的Excel处理场景。

不得不说,在报表这件事上,Excel几乎是个绕不过去的坎儿。以前很多人处理Excel文件,第一反应就是Microsoft.Office.Interop——那套方案你得先装Office,而且进程管理稍有不慎就容易出幺蛾子,算是历史遗留的“老办法”了。今天聊的MiniExcel就清爽很多,库文件不到1MB,核心思路是不依赖Office环境,直接操作.xlsx文件底层的ZIP压缩包,读写都在.NET Core或.NET Framework上跑得挺溜。

C#中使用MiniExcel读写.xlsx文件的代码实现

接下来,我们从最基础的读写开始,再到写入优化、样式设置,一步步把常见的操作场景串起来。

代码实现

1. 安装与基础读写

安装方式就是一行命令的事:

dotnet add package MiniExcel

读取Excel文件,MiniExcel提供了几种很直观的方式。可以直接把整个sheet读成List,也可以指定sheet名称,还可以读成DataTable方便后面做筛选。

using MiniExcelLibs;
// ===== 读 Excel =====
public void ReadExcel()
{
    // 读取整个 sheet
    var rows = MiniExcel.Query("report.xlsx").ToList();
    // 读取指定 sheet
    var rows2 = MiniExcel.Query("report.xlsx", sheetName: "Sheet2").ToList();
    // 读取为 DataTable(便于筛选)
    var dt = MiniExcel.QueryAsDataTable("report.xlsx");
    foreach (DataRow row in dt.Rows)
    {
        Console.WriteLine($"{row["DeviceId"]} - {row["Value"]}");
    }
}

写Excel也一样简洁,直接把List丢进去就行,连表头都会自动映射。

// ===== 写 Excel =====
public void WriteSimpleExcel()
{
    var devices = new[]
    {
        new { DeviceId = "INJ001", Temperature = 85.5, Pressure = 1.2 },
        new { DeviceId = "INJ002", Temperature = 82.3, Pressure = 1.1 }
    };
    // 最简单写法:List 直接写
    MiniExcel.Sa veAs("output.xlsx", devices);
    // 指定 sheet 名
    MiniExcel.Sa veAs("output.xlsx", devices, sheetName: "生产数据");
}

2. 写入优化:分批写入大文件

这里有个常见的坑——MiniExcel默认会把所有数据一股脑加载到内存里。数据量小的时候没什么感觉,但一旦到了几十万行,内存就有点吃不消了。

解决办法也不复杂:分批写入。每次处理5000条,第一批负责创建文件并写入表头,后面批次通过AppendExcel追加数据即可。

public void WriteLargeFile(string filePath, IEnumerable rows)
{
    var batchSize = 5000;
    var batch = new List();

    using (var stream = File.Create(filePath))
    {
        bool firstBatch = true;

        foreach (var row in rows)
        {
            batch.Add(row);

            if (batch.Count >= batchSize)
            {
                if (firstBatch)
                {
                    // 第一批:创建文件 + 写入表头
                    stream.Seek(0, SeekOrigin.Begin);
                    MiniExcel.Sa veAs(stream, batch, printHeader: true);
                    firstBatch = false;
                }
                else
                {
                    // 后续批次:追加到已有 sheet(通过 sheetName)
                    MiniExcel.AppendExcel(stream, batch, sheetName: "Data");
                }
                batch.Clear();
            }
        }

        // 处理剩余数据
        if (batch.Count > 0)
        {
            if (firstBatch)
                MiniExcel.Sa veAs(stream, batch, printHeader: true);
            else
                MiniExcel.AppendExcel(stream, batch, sheetName: "Data");
        }
    }
}

3. 使用模板生成报表

很多业务场景下,报表的格式是固定的,只是每次往里面填数据。MiniExcel支持基于模板生成报表——你先把模板Excel准备好,包括标题、列头、合并单元格等格式信息,然后通过Sa veAsByTemplate把数据注入进去。

// 报表模板(template.xlsx)包含:
// - A1: 标题(已合并单元格)
// - A3: 列头(DeviceId, Timestamp, Temperature...)
// - A4 以下:数据区(空着,等我们填充)

public void GenerateFromTemplate()
{
    string templatePath = "template.xlsx";
    string outputPath = "report_20240421.xlsx";

    // 1. 复制模板
    File.Copy(templatePath, outputPath, overwrite: true);

    // 2. 读取模板内容(不覆盖格式)
    var template = MiniExcel.QueryAsDataTable(outputPath);

    // 3. 准备数据
    var data = GetProductionData(); // List

    // 4. 写入数据(从 A4 开始)
    MiniExcel.Sa veAsByTemplate(outputPath, new
    {
        Title = "2024年4月21日 生产报表",
        GenerateDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm"),
        Data = data  // 这个 key 会对应模板中的 Data 区域
    });
}

4. 样式设置

样式的控制上,MiniExcel提供了一些基础能力,比如设置列宽、列名、数字格式。如果需要更深入的样式控制(比如行高、背景色、字体),那就得借助底层操作了。

public void WriteWithStyle()
{
    var rows = new List>
    {
        new Dictionary { ["DeviceId"] = "INJ001", ["Value"] = 85.5 },
        new Dictionary { ["DeviceId"] = "INJ002", ["Value"] = 82.3 }
    };

    // 设置列配置
    var columns = new Dictionary
    {
        ["DeviceId"] = new MiniExcelColumnAttribute { Name = "设备编号", Width = 15 },
        ["Value"] = new MiniExcelColumnAttribute { Name = "测量值", Width = 12, Format = "0.00" }
    };

    // 写入并设置列宽
    MiniExcel.Sa veAs("styled.xlsx", rows, configurations: columns);
}

如果确实需要更精细的样式控制,技术判断是:直接用MiniExcel做简单的样式配置,遇到复杂场景时果断引入ClosedXML或EPPlus来配合使用。

// 自定义样式(需要底层操作)
public void WriteWithCustomStyle(string filePath)
{
    var config = new MiniExcelConfiguration
    {
        SheetName = "Report"
    };

    using var stream = File.Create(filePath);
    stream.Seek(0, SeekOrigin.Begin);

    // MiniExcel 支持通过 .xlsx 的 shared strings 和 styles.xml
    // 完整样式控制建议用 ClosedXML 或 EPPlus
}

5. 读取时处理合并单元格

合并单元格在真实业务数据中很常见,但读取起来有点麻烦。MiniExcel默认会把合并单元格的值复制到每一行,如果你想精准识别哪些区域是合并的,需要手动解析单元格的MergeCount信息。

public void ReadMergedCells()
{
    var cells = MiniExcel.GetCells("merged.xlsx").ToList();

    var mergedRanges = cells
        .Where(c => c.MergeCount > 0)
        .Select(c => new
        {
            c.Value,
            StartRow = c.Row,
            EndRow = c.Row + c.MergeCount - 1,
            StartCol = c.Column,
            EndCol = c.Column + 1  // 简化:默认横向合并
        })
        .ToList();

    foreach (var m in mergedRanges)
    {
        Console.WriteLine($"合并区域: {m.Value} ({m.StartRow}-{m.EndRow})");
    }
}

总的来说,MiniExcel在轻量级、无Office依赖的Excel处理场景里,确实是值得考虑的选择。如果数据量不大、不需要复杂样式,用它就够了;如果需要更精致的报表设计,那配合ClosedXML或EPPlus做样式的深层控制,才是更成熟的实践路径。

本文内容来源于网友投稿,如有侵权请联系删除。
作者最新文章
编程开发 Excel
相关文章 更多
解决PHP递归报错:max_nesting_level限制与内存溢出处理
解决PHP递归报错:max_nesting_level限制与内存溢出处理

遇到PHP递归报错时,不要盲目调大max_nesting_level。本文教你区分Xdebug限制、内存耗尽和正则递归错误,提供代码级的终止条件优化与迭代替代方案,彻底解决栈溢出问题。

PHP递归中static变量与引用传递的常见陷阱及调试
PHP递归中static变量与引用传递的常见陷阱及调试

本文分析PHP递归中static变量导致的状态污染及引用传递引发的共享数据修改问题。提供具体的代码复现、缓存键设计建议及调试打印技巧,帮助开发者避免隐蔽的逻辑错误。

PHP递归性能优化技巧与迭代替代方案
PHP递归性能优化技巧与迭代替代方案

解析PHP递归函数在树形数据处理中的性能瓶颈,提供预加载数据消除I/O、使用显式栈替代深层递归的实战方案,帮助开发者在代码可读性与执行效率间做出合理取舍。

Java测试中怎么使用Mockito模拟依赖对象
Java测试中怎么使用Mockito模拟依赖对象

详细讲解在Java单元测试中如何使用Mockito模拟依赖对象,包括引入依赖、创建Mock、打桩返回值、行为验证以及Mock与Spy的核心差异和常见陷阱排查。

链表删除节点的时间复杂度是多少及其详细分析
链表删除节点的时间复杂度是多少及其详细分析

详细分析链表删除节点的时间复杂度,深入探讨单链表与双向链表在不同已知前提下的查找与删除开销,并结合完整代码与清晰图解进行对比总结。

codex如何配置模型参数及文件设置教程
codex如何配置模型参数及文件设置教程

想知道如何让AI写出的代码更贴合你的习惯?本文手把手教你在VS Code中调整Codex相关模型参数,通过修改配置文件优化温度值和令牌限制,解决代码建议不准确或响应慢的问题。

Claude Code AI编程工具实力揭秘与编程助手实测
Claude Code AI编程工具实力揭秘与编程助手实测

通过实测展示Claude Code在终端中如何理解自然语言指令、自动修改代码文件并处理复杂编程任务,帮助开发者评估其实际辅助能力。

winforms教程自学入门与基础开发步骤详解
winforms教程自学入门与基础开发步骤详解

本教程详细讲解如何使用Visual Studio创建WinForms项目,通过添加按钮和标签控件并编写点击事件代码,实现一个基础的计数器功能,适合C#初学者快速上手Windows窗体应用开发。

Cursor自动补全设置教程教你快速开启代码补全功能
Cursor自动补全设置教程教你快速开启代码补全功能

详解Cursor编辑器中自动补全功能的开启与优化设置,涵盖Tab触发机制、上下文窗口调整及模型切换,帮助开发者解决补全延迟、干扰大等问题,提升编码流畅度。

pandas的数据格式怎么转换和设置方法教程
pandas的数据格式怎么转换和设置方法教程

详解Pandas中数据格式转换的核心方法,包括astype强制转换、to_numeric容错处理及日期解析技巧,解决常见类型错误并提升数据处理效率。

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

macOS软件
macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

Mac软件 更多
photoshop
photoshop
Windows、macOS 、 iPad

Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

Blender
Blender
Windows、macOS 和 Linux

Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。

灵活计算器
灵活计算器
macOS/iOS/Android

灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

WINDOWS 更多
3dmax(3ds max)
3dmax(3ds max)
Windows

Autodesk 3ds Max 是一款专业的三维建模、动画与渲染软件,广泛应用于建筑可视化、游戏开发、影视动画、广告设计和产品展示等领域。

photoshop
photoshop
Windows、macOS 、 iPad

Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

Blender
Blender
Windows、macOS 和 Linux

Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。