You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用OpenXML将任意泛型List<T>填充至Excel工作表(无需映射)

使用OpenXML将泛型集合List导出为带类型的Excel工作表

以下是实现任意泛型集合导出为符合要求的Excel文件的完整方案,包含类型映射、列标题格式化功能:

核心实现代码

首先引入必要的命名空间:

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;
using System.Reflection;

通用导出方法

public static void ExportListToExcel<T>(List<T> dataList, string filePath)
{
    using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook))
    {
        // 初始化工作簿和工作表
        WorkbookPart workbookPart = spreadsheetDocument.AddWorkbookPart();
        workbookPart.Workbook = new Workbook();

        WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
        worksheetPart.Worksheet = new Worksheet(new SheetData());

        // 关联工作表到工作簿
        Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
        sheets.Append(new Sheet
        {
            Id = workbookPart.GetIdOfPart(worksheetPart),
            SheetId = 1,
            Name = "数据列表"
        });

        SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
        PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

        // 写入列标题行
        Row headerRow = new Row();
        foreach (var prop in properties)
        {
            string headerText = prop.Name.Replace("_", " ");
            headerRow.Append(CreateCell(headerText, CellValues.String));
        }
        sheetData.Append(headerRow);

        // 写入数据行
        foreach (var item in dataList)
        {
            Row dataRow = new Row();
            foreach (var prop in properties)
            {
                object value = prop.GetValue(item);
                CellValues cellType = GetCellValueType(prop.PropertyType);
                dataRow.Append(CreateCell(value, cellType));
            }
            sheetData.Append(dataRow);
        }

        workbookPart.Workbook.Save();
    }
}

辅助方法

// 创建指定类型的单元格
private static Cell CreateCell(object value, CellValues cellType)
{
    Cell cell = new Cell
    {
        DataType = new EnumValue<CellValues>(cellType),
        CellValue = new CellValue(value?.ToString() ?? string.Empty)
    };
    return cell;
}

// 映射.NET类型到Excel单元格类型
private static CellValues GetCellValueType(Type type)
{
    Type baseType = Nullable.GetUnderlyingType(type) ?? type;

    return baseType switch
    {
        Type t when t == typeof(string) => CellValues.String,
        Type t when t == typeof(int) || t == typeof(long) || t == typeof(short) ||
                   t == typeof(float) || t == typeof(double) || t == typeof(decimal) => CellValues.Number,
        Type t when t == typeof(DateTime) => CellValues.Date,
        Type t when t == typeof(bool) => CellValues.Boolean,
        _ => CellValues.String
    };
}

使用示例

针对你提供的Lines类:

internal class Lines
{
    public string Tipo_de_Línea { get; set; }
    public long Total { get; set; }
}

// 构造测试数据并导出
var linesData = new List<Lines>
{
    new Lines { Tipo_de_Línea = "本地线路", Total = 500 },
    new Lines { Tipo_de_Línea = "跨境线路", Total = 1200 }
};

ExportListToExcel(linesData, @"D:\output\线路统计.xlsx");

关键特性说明

  • 泛型适配:通过反射获取任意类的属性信息,无需为每个类单独编写导出逻辑。
  • 列标题格式化:自动将属性名中的下划线替换为空格,如Tipo_de_Línea转为Tipo de Línea。
  • 类型保留:严格映射.NET数据类型到Excel单元格类型,字符串对应TEXT、数值类型对应NUMBER,确保Excel中数据类型正确。
  • 空值处理:自动处理属性值为null的情况,避免导出异常。

内容的提问来源于stack exchange,提问作者Leandro Bardelli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 23:17:17