CsvHelper写入CSV时添加动态常量列及按指定字段排序问题
CsvHelper 动态加列与排序实现方案
1. 动态添加运行时确定的常量额外列
你可以通过改造ClassMap构造函数传入运行时常量,无需硬编码列值,适配实体类已有对应属性的场景:
改造映射类
public class TestMap<T> : ClassMap<MyTest> { // 构造函数接收运行时确定的常量值 public TestMap(string runtimeExtraValue) { AutoMap(CultureInfo.InvariantCulture); // 固定Extra列的值为传入的运行时常量 Map(m => m.Extra).Constant(runtimeExtraValue); // 如果需要自定义列顺序,可在此处设置Index,例:Map(m=>m.Name).Index(0) } }
如果你的实体类没有预留Extra属性,逐行写入时可以直接手动加列:
写完每行的原有字段后调用csv.WriteField("Extra", 运行时常量值)即可。
2. CSV内容排序实现
首先澄清配置项作用:
注意:DynamicPropertySort的作用是控制列的展示顺序,不是对CSV的行记录内容进行排序,该配置对批量写入和逐行写入场景均生效。
行记录内容排序
因为CSV是流式写入格式,无法在写入过程中动态调整前面的行顺序,所以不管是批量写入还是逐行写入,都需要先把所有记录加载到内存完成排序后再写入:
// 按指定字段排序,例:按Name升序排序 var sortedRecords = records.OrderBy(r => r.Name).ToList();
排序完成后再调用WriteRecords批量写入,或者遍历逐行写入都可以。
列顺序调整
如果需要调整列的展示顺序,有两种实现方式:
- 在
ClassMap中给每个映射字段设置Index属性,数值越小列越靠前 - 在
CsvConfiguration中配置DynamicPropertySort,传入自定义的排序规则,动态属性会按照该规则排序
完整可用示例代码
static void Main(string[] args) { // 模拟运行时才确定的Extra常量值 string runtimeExtraValue = $"batch_{DateTime.Now:yyyyMMddHHmmss}"; var records = new List<MyTest> { new MyTest { Id = 1, Name = "John" }, new MyTest { Id = 2, Name = "Jack" }, }; // 先按Name字段排序所有记录 var sortedRecords = records.OrderBy(r => r.Name).ToList(); // 可选:配置列排序规则 var config = new CsvConfiguration(CultureInfo.InvariantCulture) { // 按属性名升序排列列顺序 DynamicPropertySort = (prop1, prop2) => string.Compare(prop1.Name, prop2.Name) }; using (var writer = new StreamWriter(@"C:\Users\machina\AppData\Local\Temp\file.csv")) using (var csv = new CsvWriter(writer, config)) { // 传入运行时的Extra值注册映射 csv.Context.RegisterClassMap(new TestMap<MyTest>(runtimeExtraValue)); // 写入排序后的记录 csv.WriteRecords(sortedRecords); } } public interface IData { public int Id { get; set; } public string Name { get; set; } } public abstract class AbTest : IData { public abstract int Id { get; set; } public abstract string Name { get; set; } public abstract string Extra { get; set; } } public class MyTest : AbTest { public override int Id { get; set; } public override string Name { get; set; } public override string Extra { get; set; } }
内容的提问来源于stack exchange,提问作者Amol
相关产品推荐
相关产品推荐

