Tengo el siguiente código:
class Dto { public string Data1 { get; set; } public string DataN { get; set; } public string DataN1 { get; set; } } class DtoMap : ClassMap<Dto> { public DtoMap() { Map(x => x.Data1).Index(0); // Note that I need to skip N columns Map(x => x.DataN).Index(N); Map(x => x.DataN1).Index(N1); } } // create csv using (var memoryStream = new MemoryStream()) using (var streamWriter = new StreamWriter(memoryStream)) using (var csvWriter = new CsvWriter(streamWriter, csvConfiguration)) { csvWriter.Configuration.RegisterClassMap<TMap>(); csvWriter.WriteRecords(records); streamWriter.Flush(); return memoryStream.ToArray(); }El resultado esperado es la siguiente tabla CSV:
| encabezado 1 | encabezado... | encabezado m | encabezado n + 1 |
|---|---|---|---|
| Datos 1 | ... | N de datos | Datos N + 1 |
| Datos 2 | ... | N de datos | Datos N + 1 |
Parece que los índices se ignoran durante la escritura del archivo csv. El problema ocurrió en las versiones 15.0.6 y 26.0.0. ¿Alguna sugerencia?
CsvHelper generará columnas en el orden especificado por los índices, pero no agregará columnas vacías para los índices faltantes. Si necesita hacer eso, puede usar Map().Index(i).Constant(""); para indicar un valor constante debe usarse en un índice específico i . Úselo para completar un valor vacío constante para las columnas que desea dejar vacías:
class DtoMap : ClassMap<Dto> { const int N = 12; public DtoMap() : this(true) { } public DtoMap(bool includeEmptyColumns) { Map(x => x.Data1).Index(0); if (includeEmptyColumns) { for (int i = 1; i < N; i++) { Map().Index(i).Constant(""); } } // Note that I need to skip N columns Map(x => x.DataN).Index(N); Map(x => x.DataN1).Index(N + 1); } }Ver: Valor constante .
Esto deja los títulos de las columnas vacíos. Si necesita proporcionar algún título de columna predeterminado, puede especificar uno con .Name(string) :
Map().Index(i).Constant("").Name($"Column {i}"); Sin embargo, no podrá usar este mapa de clase para leer su CSV porque (al menos a partir de CsvHelper 26.1.0) el lector generará un error cuando una columna no esté asignada a un miembro de clase, incluso si es constante . Para evitar el error, use el new DtoMap(false) al leer, es decir:
var newRecords = ReadCSV(csv, new DtoMap(false), config); static List<TRecords> ReadCSV<TRecords>(byte [] data, ClassMap<TRecords> map, CsvConfiguration csvConfiguration) { using (var memoryStream = new MemoryStream(data)) using (var streamWriter = new StreamReader(memoryStream)) using (var csvReader = new CsvReader(streamWriter, csvConfiguration)) { csvReader.Context.RegisterClassMap(map); return csvReader.GetRecords<TRecords>().ToList(); } }