编辑
2025-10-16
C#
00

目录

什么是Magicodes.IE?
Excel导出功能详解
安装Magicodes.IE
基础Excel导出
使用特性增强导出效果
导出Excel表头
数据分片导出
使用表头筛选器
动态导出
Magicodes.IE主要特性总结
导出特性(ExporterAttribute)
表头特性(ExporterHeaderAttribute)
总结

在C#开发中,数据的导入导出是一项常见但又繁琐的工作。特别是在企业应用中,经常需要处理Excel、Word、PDF等格式的文件导入导出。今天我要向大家介绍一个强大的开源库——Magicodes.IE,它能让这些工作变得简单高效。

什么是Magicodes.IE

Magicodes.IE是一个功能丰富的.NET导入导出通用库,支持:

  • Dto模型导入导出
  • 动态导出
  • 多种格式支持:Excel、Word、PDF和HTML

这个库的核心优势在于其简洁的API和丰富的特性,让开发人员几行代码就能完成复杂的导入导出需求。

Excel导出功能详解

安装Magicodes.IE

首先,需要通过NuGet包管理器安装Magicodes.IE.Excel:

C#
Install-Package Magicodes.IE.Excel

基础Excel导出

最简单的导出方式是直接使用模型列表导出:

C#
using Magicodes.ExporterAndImporter.Core; using Magicodes.ExporterAndImporter.Excel; namespace AppMagicodesIE { // 定义实体类 public class Student { /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 年龄 /// </summary> public int Age { get; set; } } internal class Program { static async Task Main(string[] args) { // 创建导出器实例 IExporter exporter = new ExcelExporter(); // 准备数据并导出 var result = await exporter.Export("students.xlsx", new List<Student>() { new Student { Name = "张三", Age = 18 }, new Student { Name = "李四", Age = 19 }, new Student { Name = "王五", Age = 20 } }); // result包含导出文件的路径信息 Console.WriteLine($"导出成功,文件路径:{result.FileName}"); Console.ReadKey(); } } }

image.png

这种方式会使用属性名作为表头,生成一个简单的Excel文件。

使用特性增强导出效果

Magicodes.IE提供了丰富的特性(Attribute)来控制导出效果:

C#
// 使用特性增强的学生类 [ExcelExporter(Name = "学生信息表", TableStyle = "Light10", AutoFitAllColumn = true, MaxRowNumberOnASheet = 1000)] public class StudentEnhanced { /// <summary> /// 学号 /// </summary> [ExporterHeader(DisplayName = "学号", IsBold = true)] public string StudentId { get; set; } /// <summary> /// 姓名 /// </summary> [ExporterHeader(DisplayName = "姓名", FontSize = 12)] public string Name { get; set; } /// <summary> /// 年龄 /// </summary> [ExporterHeader(DisplayName = "年龄", Format = "#,##0")] public int Age { get; set; } /// <summary> /// 出生日期 /// </summary> [ExporterHeader(DisplayName = "出生日期", Format = "yyyy-MM-dd")] public DateTime Birthday { get; set; } /// <summary> /// 成绩 /// </summary> [ExporterHeader(DisplayName = "成绩", Format = "0.00")] public double Score { get; set; } /// <summary> /// 备注 /// </summary> [ExporterHeader(IsIgnore = true)] // 此字段将被忽略,不导出 public string Remarks { get; set; } }

导出代码与基础导出相同,但结果会更加美观和定制化:

  • 自定义表头名称
  • 设置单元格格式
  • 控制字体大小和样式
  • 自适应列宽
  • 应用表格样式

导出Excel表头

有时我们只需要导出表头,不需要数据:

C#
internal class Program { static async Task Main(string[] args) { await ExportHeader(); Console.ReadKey(); } public static async Task ExportHeader() { IExcelExporter exporter = new ExcelExporter(); var filePath = "h.xlsx"; var arr = new[] { "学号", "姓名", "年龄", "班级", "成绩", "备注" }; var sheetName = "Test"; var result = await exporter.ExportHeaderAsByteArray(arr, sheetName); result.ToExcelExportFileInfo(filePath); } }

image.png

C#
using Magicodes.ExporterAndImporter.Core; using Magicodes.ExporterAndImporter.Core.Extension; using Magicodes.ExporterAndImporter.Excel; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Threading.Tasks; namespace AppMagicodesIE { // 使用特性增强的学生类 [ExcelExporter(Name = "学生信息表", TableStyle = OfficeOpenXml.Table.TableStyles.Dark11, AutoFitAllColumn = true, MaxRowNumberOnASheet = 1000)] public class StudentEnhanced { /// <summary> /// 学号 /// </summary> [ExporterHeader(DisplayName = "学号", IsBold = true)] public string StudentId { get; set; } /// <summary> /// 姓名 /// </summary> [ExporterHeader(DisplayName = "姓名", FontSize = 12)] public string Name { get; set; } /// <summary> /// 年龄 /// </summary> [ExporterHeader(DisplayName = "年龄", Format = "#,##0")] public int Age { get; set; } /// <summary> /// 出生日期 /// </summary> [ExporterHeader(DisplayName = "出生日期", Format = "yyyy-MM-dd")] public DateTime Birthday { get; set; } /// <summary> /// 成绩 /// </summary> [ExporterHeader(DisplayName = "成绩", Format = "0.00")] public double Score { get; set; } /// <summary> /// 备注 /// </summary> [ExporterHeader(IsIgnore = true)] // 此字段将被忽略,不导出 public string Remarks { get; set; } } internal class Program { static async Task Main(string[] args) { await ExportHeader(); Console.ReadKey(); } public static async Task ExportHeader() { IExporter exporter = new ExcelExporter(); var filePath = "h1.xlsx"; var result = await exporter.ExportHeaderAsByteArray<StudentEnhanced>(new StudentEnhanced()); result.ToExcelExportFileInfo(filePath); } } }

image.png

数据分片导出

对于大量数据,Magicodes.IE支持自动分片导出到多个Sheet:

C#
using Magicodes.ExporterAndImporter.Core; using Magicodes.ExporterAndImporter.Excel; using System; using System.Collections.Generic; using System.Threading.Tasks; using System.ComponentModel; using System.ComponentModel.DataAnnotations; namespace AppMagicodesIE { class Program { static async Task Main(string[] args) { Console.WriteLine("开始导出大量数据..."); await ExportLargeData(); Console.WriteLine("导出完成!"); Console.ReadKey(); } // 导出1000条数据,将自动分为2个Sheet public static async Task ExportLargeData() { IExporter exporter = new ExcelExporter(); var students = GenerateStudentData(1000); var result = await exporter.Export("LargeData.xlsx", students); Console.WriteLine($"文件已导出至: {result.FileName}"); } private static List<Student> GenerateStudentData(int count) { var students = new List<Student>(); for (int i = 0; i < count; i++) { students.Add(new Student { StudentId = i + 1, Name = $"学生{i + 1}", Age = 18 + (i % 10), Gender = i % 2 == 0 ? "男" : "女", Class = $"{(i % 4) + 1}年级{(i % 6) + 1}班", Score = 60 + (i % 40), IsActive = true, EnrollmentDate = DateTime.Now.AddDays(-i % 365) }); } return students; } } // 定义Student类,并设置Excel导出相关特性 [ExcelExporter(Name = "大量学生数据", MaxRowNumberOnASheet = 500)] public class Student { [ExporterHeader(DisplayName = "学号")] public int StudentId { get; set; } [ExporterHeader(DisplayName = "姓名")] [Required] public string Name { get; set; } [ExporterHeader(DisplayName = "年龄")] public int Age { get; set; } [ExporterHeader(DisplayName = "性别")] public string Gender { get; set; } [ExporterHeader(DisplayName = "班级")] public string Class { get; set; } [ExporterHeader(DisplayName = "分数")] public double Score { get; set; } [ExporterHeader(DisplayName = "是否在校")] public bool IsActive { get; set; } [ExporterHeader(DisplayName = "入学时间")] [DisplayFormat(DataFormatString = "yyyy-MM-dd")] public DateTime EnrollmentDate { get; set; } } }

image.png

image.png

使用表头筛选器

表头筛选器允许您在运行时动态修改表头信息,非常适合多语言或动态列显示控制:

C#
using Magicodes.ExporterAndImporter.Core; using Magicodes.ExporterAndImporter.Excel; using System; using System.Collections.Generic; using System.Threading.Tasks; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using Magicodes.ExporterAndImporter.Core.Filters; using Magicodes.ExporterAndImporter.Core.Models; namespace AppMagicodesIE { class Program { static async Task Main(string[] args) { // 创建学生数据 var students = new List<StudentWithFilter> { new StudentWithFilter { Name = "张三", Age = 18, Gender = "男", Score = 85.5 }, new StudentWithFilter { Name = "李四", Age = 20, Gender = "男", Score = 90.0 }, new StudentWithFilter { Name = "王五", Age = 19, Gender = "女", Score = 92.5 } }; // 创建Excel导出器 var exporter = new ExcelExporter(); // 导出Excel文件 var result = await exporter.ExportAsByteArray(students); // 保存到文件 await System.IO.File.WriteAllBytesAsync("学生数据.xlsx", result); Console.WriteLine("Excel文件导出成功!"); } } // 定义表头筛选器 public class StudentHeaderFilter : IExporterHeaderFilter { public ExporterHeaderInfo Filter(ExporterHeaderInfo headerInfo) { // 可以根据需要修改表头 if (headerInfo.DisplayName == "姓名") { headerInfo.DisplayName = "Student Name"; } else if (headerInfo.DisplayName == "年龄") { headerInfo.DisplayName = "Age"; } else if (headerInfo.DisplayName == "性别") { headerInfo.DisplayName = "Gender"; } else if (headerInfo.DisplayName == "分数") { headerInfo.DisplayName = "Score"; } return headerInfo; } } // 在模型中应用筛选器 [ExcelExporter(Name = "学生信息", TableStyle = OfficeOpenXml.Table.TableStyles.Dark11 , AutoFitAllColumn = true , MaxRowNumberOnASheet = 2, ExporterHeaderFilter = typeof(StudentHeaderFilter))] public class StudentWithFilter { [ExporterHeader(DisplayName = "姓名")] public string Name { get; set; } [ExporterHeader(DisplayName = "年龄")] public int Age { get; set; } [ExporterHeader(DisplayName = "性别")] public string Gender { get; set; } [ExporterHeader(DisplayName = "分数")] public double Score { get; set; } } }

image.png

动态导出

C#
using Magicodes.ExporterAndImporter.Core; using Magicodes.ExporterAndImporter.Excel; using System; using System.Collections.Generic; using System.Threading.Tasks; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using Magicodes.ExporterAndImporter.Core.Filters; using Magicodes.ExporterAndImporter.Core.Models; using System.Dynamic; using System.Reflection; using System.IO; namespace AppMagicodesIE { public class Program { static async Task Main(string[] args) { try { // 创建导出器实例 - 使用库提供的ExcelExporter IExporter exporter = new ExcelExporter(); // 生成测试数据 var personList = GenFu.GenFu.ListOf<Person>(20); // 指定生成20条数据 // 指定要导出的字段 string fields = "FirstName,LastName"; // 导出数据到Excel var exportedData = await ExportData(personList, fields, exporter); // 保存Excel文件 string filePath = Path.Combine(Directory.GetCurrentDirectory(), "dynamicExportExcel.xlsx"); File.WriteAllBytes(filePath, exportedData); Console.WriteLine($"Excel文件已成功导出到: {filePath}"); } catch (Exception ex) { Console.WriteLine($"导出过程中发生错误: {ex.Message}"); Console.WriteLine(ex.StackTrace); } } /// <summary> /// 根据指定字段导出数据 /// </summary> private static async Task<byte[]> ExportData<T>(List<T> dataList, string fields, IExporter exporter) where T : class { if (dataList == null || dataList.Count == 0) { throw new ArgumentException("数据列表不能为空"); } if (string.IsNullOrWhiteSpace(fields)) { throw new ArgumentException("导出字段不能为空"); } // 解析要导出的属性 var propertyInfoList = GetPropertiesFromFields<T>(fields); // 转换为动态对象列表 var expandoObjectList = ConvertToExpandoObjects(dataList, propertyInfoList); // 导出为Excel return await exporter.ExportAsByteArray(expandoObjectList); } /// <summary> /// 从字段字符串中获取属性信息列表 /// </summary> private static List<PropertyInfo> GetPropertiesFromFields<T>(string fields) where T : class { var propertyInfoList = new List<PropertyInfo>(); var fieldsAfterSplit = fields.Split(',', StringSplitOptions.RemoveEmptyEntries); foreach (var field in fieldsAfterSplit) { var propertyName = field.Trim(); var propertyInfo = typeof(T).GetProperty(propertyName); if (propertyInfo == null) { throw new Exception($"属性: {propertyName} 在类型 {typeof(T).Name} 中不存在"); } propertyInfoList.Add(propertyInfo); } return propertyInfoList; } /// <summary> /// 将数据转换为ExpandoObject列表 /// </summary> private static List<ExpandoObject> ConvertToExpandoObjects<T>(List<T> dataList, List<PropertyInfo> propertyInfoList) where T : class { var expandoObjectList = new List<ExpandoObject>(dataList.Count); foreach (var item in dataList) { var shapedObj = new ExpandoObject(); var expandoDict = (IDictionary<string, object>)shapedObj; foreach (var propertyInfo in propertyInfoList) { var propertyValue = propertyInfo.GetValue(item); expandoDict.Add(propertyInfo.Name, propertyValue); } expandoObjectList.Add(shapedObj); } return expandoObjectList; } } /// <summary> /// 人员信息类 /// </summary> public class Person { public string FirstName { get; set; } public string LastName { get; set; } public string Title { get; set; } public int Age { get; set; } public int NumberOfKids { get; set; } // 添加一个完整名称的属性 public string FullName => $"{FirstName} {LastName}"; } }

image.png

Magicodes.IE主要特性总结

导出特性(ExporterAttribute)

属性类型说明
Namestring当前Sheet名称
HeaderFontSizefloat头部字体大小
FontSizefloat正文字体大小
MaxRowNumberOnASheetintSheet最大允许的行数,设置后将输出多个Sheet
TableStylestring表格样式风格
AutoFitAllColumnbool自适应所有列
Authorstring作者信息
ExporterHeaderFilterType头部筛选器类型

表头特性(ExporterHeaderAttribute)

属性类型说明
DisplayNamestring显示名称
FontSizefloat字体大小
IsBoldbool是否加粗
Formatstring格式化表达式
IsAutoFitbool是否自适应
IsIgnorebool是否忽略此字段

总结

Magicodes.IE是一个功能强大且易用的C#导入导出库,通过简单的API和丰富的特性,能够显著提高开发效率。它的主要优势包括:

  1. 简单易用:几行代码即可完成复杂导出
  2. 功能丰富:支持多种格式、数据分片、自定义样式等
  3. 高度可定制:通过特性和筛选器满足各种需求
  4. 开箱即用:无需复杂配置,安装即可使用

在实际项目中,Magicodes.IE可以应用于报表导出、数据交换、模板生成等多种场景,大大提高了开发效率和用户体验。

希望本文对你了解和使用Magicodes.IE有所帮助。如果你有数据导入导出的需求,不妨试试这个优秀的开源库!

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!