【云驻共创】盘点C#几个经典的Excel开源项目

举报
IT技术分享社区 发表于 2024/04/09 09:27:02 2024/04/09
【摘要】 Excel导入导出套件,支持百万级(几百万亦可)数据 导出 和 读取 (格式仅限xlsx)而不占用多少内存,方便易用的方法让导入导出更易使用 支持.Net Core,docker,Windows。


C#作为目前最流行的后端开发语言之一,其中也有不少的经典开源项目,使用它们可以避免我们重复造轮子,大大提高开发效率和系统的稳定性,今天来给大家分享C#几个经典的Excel开源项目,希望对大家日常选项能够提供一些帮助!


一、ClosedXML

1.1、类库介绍

ClosedXML是一个用于读取、操作和写入Excel 2007+ (.xlsx, .xlsm)文件的.NET第三方库。它基于OpenXML,但与OpenXML相比,ClosedXML具有更高的性能和更易于使用的API接口。



ClosedXML支持XML文档的解析和生成,可以处理复杂的XML结构。同时,它还提供了丰富的API,可以方便地进行XML文档的查询、修改、添加和删除操作。此外,ClosedXML还支持XPath和XSLT查询,可以进行高效的XML数据检索和转换。

在使用ClosedXML时,您需要将ClosedXML.dll添加到您的项目中,并使用相关的API进行Excel文件的读取和写入。ClosedXML支持多种数据类型,包括字符串、数字、日期、布尔值等,并支持单元格格式设置。此外,您还可以使用ClosedXML进行样式设置,包括字体、边框、颜色等。

除了基本的Excel文件操作,ClosedXML还支持图表、公式、数据验证、条件格式等高级功能。同时,ClosedXML还提供了多种异常处理机制,可以帮助您更好地处理异常情况。

https://docs.closedxml.io/en/latest/

https://github.com/ClosedXML/ClosedXML

1.2、安装方式

1.2.1 直接nuget搜索安装


1.2.2 命令行安装方式

工具→Nuget包管理器→程序包管理器控制台


输入如下命令:


Install-Package ClosedXML

1.3、测试Demo

  /// <summary>
        /// 插入DataTable
        /// </summary>
        private static void InsertDataTable()
        {
            // 创建一个新的 DataTable 对象
            DataTable dataTable = new DataTable();

            // 定义表的列
            dataTable.Columns.Add("ID", typeof(int));
            dataTable.Columns.Add("Name", typeof(string));
            dataTable.Columns.Add("Age", typeof(int));

            // 添加数据行
            dataTable.Rows.Add(1, "John", 25);
            dataTable.Rows.Add(2, "Alice", 30);
            dataTable.Rows.Add(3, "Bob", 40);
            using (var workbook = new XLWorkbook())
            {
                var worksheet = workbook.Worksheets.Add("Sheet1");
                worksheet.FirstCell().InsertTable(dataTable);
                workbook.SaveAs("D:\\tableDemo.xlsx");
            }

        }

二、MiniExcel 

2.1、框架介绍

MiniExcel简单、高效避免OOM的.NET处理Excel查、写、填充数据工具。

目前主流框架大多需要将数据全载入到内存方便操作,但这会导致内存消耗问题,MiniExcel 尝试以 Stream 角度写底层算法逻辑,能让原本1000多MB占用降低到几MB,避免内存不够情况。

官网:https://github.com/mini-software/MiniExcel

2.2、框架特点

低内存耗用,避免OOM、频繁 Full GC 情况

支持即时操作每行数据

兼具搭配 LINQ 延迟查询特性,能办到低消耗、快速分页等复杂查询

轻量,不需要安装 Microsoft OfficeCOM+DLL小于150KB

简便操作的 API 风格

 

2.3、示例

2.3.1 安装

nuget官网

https://www.nuget.org/packages/MiniExcel

NuGet\Install-Package MiniExcel -Version 1.31.0

2.3.2 通过模板导出

首先创建模板,模板内容如下:

单个记录模板

 

多条记录模板

列表名称:users

 

 

然后编写代码,通过模板导出的实现方式有两种:实体方式填充、字典方式填充

 

/// <summary>
        /// 基于模板导出
        /// </summary>
        private static void ExportTemplete()
        {
            // 1. 通过实体方式填充
            var valueByModel = new
            {
                Name = "小明",
                Age = 35,
                Address = "北京"
            };
            MiniExcel.SaveAsByTemplate("D:\\test0614实体方式.xlsx", "templete.xlsx", valueByModel);

            // 2. 通过字典方式填充
            var value = new Dictionary<string, object>()
            {
                ["Name"] = "小明",
                ["Age"] = 30,
                ["Address"] = "苏州"
            };
            MiniExcel.SaveAsByTemplate("D:\\test0614字典方式.xlsx", "templete.xlsx", value);

            // 3 通过实体list方式
            var value3 = new
            {
                users = new[] {
                    new {Name="小明",Age=30,Address="苏州"},
                    new {Name="小李",Age=25,Address="上海"},
                    new {Name="小张",Age=32,Address="南京"},
                    new {Name="小孙",Age=36,Address="常州"},
                    new {Name="小王",Age=27,Address="徐州"},
                }
            };

            MiniExcel.SaveAsByTemplate("D:\\test0614_实体list方式.xlsx", "templete2.xlsx", value3);

            // 4 通过字典list方式
            var value4 = new Dictionary<string, object>()
            {
                ["users"] = new[] {
                    new {Name="小明",Age=30,Address="苏州2"},
                    new {Name="小李",Age=25,Address="上海2"},
                    new {Name="小张",Age=32,Address="南京2"},
                    new {Name="小孙",Age=36,Address="常州2"},
                    new {Name="小王",Age=27,Address="徐州2"}
                }
            };

            MiniExcel.SaveAsByTemplate("D:\\test0614_字典list方式.xlsx", "templete2.xlsx", value4);
        }

 

三、ExcelKit

 

3.1ExcelKit介绍

Excel导入导出套件,支持百万级(几百万亦可)数据 导出  读取 (格式仅限xlsx)而不占用多少内存,方便易用的方法让导入导出更易使用 支持.Net CoredockerWindows

依赖项:.Net Standard2.1 + NPOI2.4.1以上版本

3.2 安装方式

通过命令安装

Install-Package ExcelKit

直接通过nuget包管理器搜索安装

直接搜索ExcelKit关键字,选择最新的版本安装。

 

3.3、示例

3.1 首先新建一个Person.cs 实体类 

public class Person
    {
        [ExcelKit(Desc = "用户名", Width = 20, IsIgnore = false, Sort = 10, Align = TextAlign.Center, FontColor = DefineColor.LightBlue)]
        public string UserName { get; set; }
        [ExcelKit(Desc = "密码", Width = 20, Sort = 20, FontColor = DefineColor.Rose)]
        public string Pwd { get; set; }
        [ExcelKit(Desc = "住址", Width = 30, Sort = 30, FontColor = DefineColor.Rose, ForegroundColor = DefineColor.LemonChiffon)]
        public string Address { get; set; }
        [ExcelKit(Desc = "年龄", Width = 10, Sort = 40)]
        public int  Age { get; set; }
        [ExcelKit(Desc = "兴趣爱好", Width = 30, Sort = 50, FontColor = DefineColor.Rose, ForegroundColor = DefineColor.LemonChiffon)]
        public string Hobby { get; set; }

    }

3.2 泛型类方式导出代码示例

操作步骤

  • 获取GetWriteContext并指定导出文件名
  • 创建Sheet并制定Sheet名(Sheet名作为后期追加数据区分是哪个Sheet的依据)
  • AppendDataSheet中追加数据
  • 调用Save保存(默认保存到程序运行目录)或Generate生成Excel信息,web环境调用Generate生成的信息,调用return File(Excel信息)后,可直接用于下载

特别提示,当单个Sheet数据量超过1048200后,后续追加的数据会自动拆分到新的Sheet,使用者不需要自己处理,只管追加数据。

/// <summary>
        /// 基于实体类导出,需要在实体类配置ExcelKit的注解
        /// </summary>
        private static void Export()
        {
            string filename = "测试导出文件";
            if (IsFileInUse(filename + ".xlsx"))
            {
                Console.WriteLine("文件正在占用,请先关闭文件");
            }
            else
            {
                using (var context = ContextFactory.GetWriteContext("测试导出文件"))
                {
                    // 创建第一个sheet
                    var sheet = context.CrateSheet<Person>($"Sheet1");
                    for (int i = 0; i < 1000; i++)
                    {
                        sheet.AppendData($"Sheet1", new Person { UserName = $"1-{i}-小明", Address = $"1-{i}-苏州", Age = 30, Hobby = "读书", Pwd = "123456" });
                    }

                    // 创建第二个sheet
                    var sheet2 = context.CrateSheet<Person>($"Sheet2");
                    for (int i = 0; i < 1500; i++)
                    {
                        sheet2.AppendData($"Sheet2", new Person { UserName = $"2-{i}-小明", Address = $"2-{i}-苏州", Age = 30, Hobby = "读书", Pwd = "123456" });
                    }
                    string filePath = context.Save();
                    Console.WriteLine($"文件路径:{filePath}");
                }
            }
        }

效果

 

 

注意:泛类导出需要增加ExcelKitAttribute注解,要不然导出会有问题

ExcelKitAttribute详解

  • Code:字段编码,如NameAge; 读取时不指定Code默认使用字段名
  • Desc:字段描述[必指定],对应Excel列头中的文本,如姓名、地址,
  • AllowNull:字段是否允许为空,一般用于读取
  • Converter:转换器[导出时],组件中提供了常用的转换器,如需自定义,则继承自IExportConverter并实现方法
  • ConverterParam:转换器辅助参数[导出时],导出时使用,如日期格式化导出,导出保留的小数位等;如需自定义Converter,则ConverterParam会完全放置到Convert方法的第二个参数中
  • Sort:字段顺序[导出时],导出和读取都可能用到
  • Width:列宽[导出时],指定Excel列宽度
  • Align:对齐方式[导出时],指定Excel列中的文本对齐方式
  • FontColor:字体颜色[导出时],指定Excel列中的字体颜色,枚举项
  • ForegroundColor:前景色[导出时],指定Excel列的填充色,枚举项
  • HeadRowFrozen:是否启用表头行冻结[导出时]
  • HeadRowFilter:是否启用表头行筛选[导出时]
  • IsIgnore:是否完全忽略
  • IsOnlyIgnoreRead:是否仅读取时忽略
  • IsOnlyIgnoreWrite:是否仅导出时忽略

Converter详解

作用Converter为内置的接口IExportConverter,主要是为了导出使用;目前提供了单泛型参数,双泛型参数的版本。使用者可以根据接口实现自己的Converter 程序内部提供了常用的Converter,命名空间为:ExcelKit.Core.Infrastructure.Converter ,内置如下:

  • BoolConverter:(适用于bool类型字段,可指定ConverterParam,如ConverterParam = "|",字段定义为bool?可空时,true为男,false为女,为空则导出也为空,默认不指定ConverterParam的话,导出后显示为:是否;自定义导出文字,用|区分,左边文字为字段等于true时导出的值,右边为字段等于false时导出的值)
  • DateTimeFmtConverter:(日期格式化Converter,如需自定义日期格式,需指定ConverterParam
  • DecimalPointDigitConverter:(小数类Converter,如需指定保留几位小数,需指定ConverterParam
  • EnumConverter:(枚举Converter,需要在枚举上方打上此特性[System.ComponentModel.Description("用户类型")],导出时就会根据指定的描述展示对应的文字,如果枚举加了可空,则使用时Converter = typeof(EnumConverter<UserStatusEnum?>)
  • EnumerableConverter:(集合类Converter,如字段定义为public List SkuSellRegion { get; set; }则上方Converter = typeof(EnumerableConverter),导出后会自动拆分为字符串,以,分隔的长文本)

四、总结

以上几个Excel开源项目都是质量比较高的Excel开源项目,作为系统当中文档处理还是非常实用的,有需要的朋友可以自己下载尝试一下,有问题的话也可以和我沟通交流!

本文参与华为云社区【内容共创】活动第26期

任务18:有哪些非常经典的开源项目?


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。