[英]How to control the order in which CSV file headers are written by CsvHelper without using a class a mapping?
I have the following method to write dynamic CSV file records:我有以下方法写动态CSV文件记录:
public byte[] BuildProductsFile(List<object> records)
{
var firstRow = records.FirstOrDefault();
var columnHeaders = ((IDictionary<string, object>) firstRow).Keys.ToList();
using var memoryStream = new MemoryStream();
using (var streamWriter = new StreamWriter(memoryStream))
{
using var csvWriter = new CsvWriter(streamWriter);
csvWriter.WriteRecords(records);
}
return memoryStream.ToArray();
}
When I do WriteRecords, it changes header names to alphabetic order which I don't want since afterwards my rows correspond to incorrect headers.当我执行 WriteRecords 时,它会将 header 名称更改为我不想要的字母顺序,因为之后我的行对应于不正确的标题。 I can't use a class to specify header names because they will be different depending on different tables which user would like to get.
我不能使用 class 来指定 header 名称,因为它们会根据用户想要获得的不同表而有所不同。
My question is can I write the header names in the correct sequence, which I can get from我的问题是我可以按正确的顺序编写 header 名称吗,我可以从中得到
var columnHeaders = ((IDictionary<string, object>) firstRow).Keys.ToList();
Alternatively, is there a way to disable alphabetical order header placing?或者,有没有办法禁用字母顺序 header 放置?
You must be using a version of CsvHelper
between 10.0.0 and 12.0.0 .您必须使用10.0.0和12.0.0之间的
CsvHelper
版本。 Between these two versions, CsvWriter.WriteRecords()
would write ExpandoObject
properties in alphabetical order.在这两个版本之间,
CsvWriter.WriteRecords()
将按字母顺序写入ExpandoObject
属性。 Upgrade to a later version (or downgrade to an earlier version) to eliminate this behavior.升级到更高版本(或降级到更早版本)以消除此行为。
For confirmation, see the change log :如需确认,请参阅更改日志:
10.0.0
10.0.0
Features:
特征:
- Write ExpandoObject and IDynamicMetaObjectProvider object properties in ascending order to ensure order of property creation doesn't matter.
按升序编写 ExpandoObject 和 IDynamicMetaObjectProvider object 属性,以确保属性创建顺序无关紧要。
12.0.0
12.0.0
Features
特征
- Added config option for sorting dynamic object properties when writing.
添加了用于在写入时对动态 object 属性进行排序的配置选项。 Defaults to property value set order.
默认为属性值设置顺序。
Breaking Changes
重大变化
- Added
IComparer<string> IWriterConfiguration.DynamicPropertySort
.添加
IComparer<string> IWriterConfiguration.DynamicPropertySort
。- Added
IComparer<string> Configuration.DynamicPropertySort
.添加
IComparer<string> Configuration.DynamicPropertySort
。
See When writing dynamic object order of property assignments is significant #1037 for a discussion of why this happened.请参阅When writing dynamic object order of property assignment is Significant #1037讨论为什么会发生这种情况。
A demo of CsvHelper
failing in version 11 can be found here: demo #1 .可以在此处找到版本 11 中失败的
CsvHelper
演示:演示 #1 。
A demo of CsvHelper
working as desired in the most recent version, version 26, can be found here: demo #2 .可以在此处找到在最新版本 26 中按需要工作的
CsvHelper
演示:演示 #2 。
And if you really need to write your CSV columns in an order specified by a sequence of strings, you can use CsvConfiguration.DynamicPropertySort
mentioned above:如果您确实需要按照字符串序列指定的顺序编写 CSV 列,则可以使用上面提到的
CsvConfiguration.DynamicPropertySort
:
class OrderComparer : IComparer<string>
{
// Note this comparer assumes that all strings to be compared are present in the incoming collection of strings, and will throw an exception if not.
// If this is not desired, enhance as required.
readonly Dictionary<string, int> orders;
public OrderComparer(IEnumerable<string> orderedHeaders) => orders = orderedHeaders.Select((i, s) => (i, s)).ToDictionary(p => p.i, p => p.s);
public int Compare(string x, string y) => orders[x] - orders[y];
}
public static byte[] BuildProductsFile(List<object> records, IEnumerable<string> orderedHeaders) =>
BuildProductsFile(records, new OrderComparer(orderedHeaders));
public static byte[] BuildProductsFile(List<object> records, IComparer<string> dynamicPropertySort)
{
using var memoryStream = new MemoryStream();
using (var streamWriter = new StreamWriter(memoryStream))
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
DynamicPropertySort = dynamicPropertySort,
};
using var csvWriter = new CsvWriter(streamWriter, config);
csvWriter.WriteRecords(records);
}
return memoryStream.ToArray();
}
Demo of DynamicPropertySort
here: demo #3 . DynamicPropertySort
的演示在这里:演示 #3 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.