如何用C#高效将混合类型List<object[]>集合写入Excel工作表?
快速将List<object[]>(或自定义类集合)写入Excel的方案
核心思路
Excel Interop的Range.Value2支持直接接收二维object数组,通过将你的List<object[]>(或自定义类集合)转换为这种格式,仅需一次工作表I/O操作即可完成数据写入,彻底避免逐单元格赋值的性能损耗。
方案1:直接转换List<object[]>为二维数组
假设你已持有数据集合List<object[]> dataList,以及目标起始区域xl.Range rng:
// 空数据直接返回,避免无效操作 if (dataList.Count == 0) return; int rowCount = dataList.Count; int colCount = dataList[0].Length; // 创建与数据匹配的二维数组(Excel兼容的行优先结构) object[,] excelData = new object[rowCount, colCount]; // 填充二维数组 for (int rowIdx = 0; rowIdx < rowCount; rowIdx++) { object[] currentRow = dataList[rowIdx]; for (int colIdx = 0; colIdx < colCount; colIdx++) { excelData[rowIdx, colIdx] = currentRow[colIdx]; } } // 调整目标区域大小以匹配数据尺寸 xl.Range targetRange = rng.Resize[rowCount, colCount]; // 一次性写入数据,仅一次COM跨进程调用 targetRange.Value2 = excelData;
方案2:使用自定义类存储数据(类型更安全)
如果用自定义类替代object[],不仅能提升代码可读性,还能避免类型错误。例如定义一个代表泵的类:
public class Pump { public string PumpName { get; set; } // 固定字符串类型 public double FlowRate { get; set; } // 固定数值类型 public int RunHours { get; set; } // 固定数值类型 }
转换并写入的代码如下:
List<Pump> pumpData = GetPumpDataFromThirdParty(); // 从第三方采集的数据 if (pumpData.Count == 0) return; int rowCount = pumpData.Count; int colCount = 3; // 对应Pump类的3个属性 object[,] excelData = new object[rowCount, colCount]; // 填充数组(硬编码属性,性能最优) for (int rowIdx = 0; rowIdx < rowCount; rowIdx++) { Pump pump = pumpData[rowIdx]; excelData[rowIdx, 0] = pump.PumpName; excelData[rowIdx, 1] = pump.FlowRate; excelData[rowIdx, 2] = pump.RunHours; } // 写入Excel xl.Range targetRange = rng.Resize[rowCount, colCount]; targetRange.Value2 = excelData;
可选:反射自动映射自定义类属性
如果类的属性较多,不想硬编码列索引,可以用反射自动遍历属性:
using System.Reflection; // ... List<Pump> pumpData = GetPumpDataFromThirdParty(); if (pumpData.Count == 0) return; PropertyInfo[] properties = typeof(Pump).GetProperties(BindingFlags.Public | BindingFlags.Instance); int rowCount = pumpData.Count; int colCount = properties.Length; object[,] excelData = new object[rowCount, colCount]; for (int rowIdx = 0; rowIdx < rowCount; rowIdx++) { Pump pump = pumpData[rowIdx]; for (int colIdx = 0; colIdx < colCount; colIdx++) { excelData[rowIdx, colIdx] = properties[colIdx].GetValue(pump); } } xl.Range targetRange = rng.Resize[rowCount, colCount]; targetRange.Value2 = excelData;
注意:反射会带来轻微性能损耗,数据量极大时建议优先使用硬编码方式。
内容的提问来源于stack exchange,提问作者RobBaker
相关产品推荐
相关产品推荐

