Как заменить символы / символы в процессе записи строки / файла csv в CsvHelper? - PullRequest
0 голосов
/ 06 февраля 2020

Мне нужно избавиться от некоторых символов из каждого столбца подряд в процессе написания строки CSV, но я не могу найти такую ​​функцию ни в CsvHelper.CsvWriter.Configuration, ни в CsvHelper.CsvWriter.Context, ни где-либо еще.

В качестве приемлемого для меня обходного пути, я попытался переопределить метод ConvertUsing класса MemberMap<TClass, TMember>, и он не работал правильно:

 public class CustomMemberMap < TClass, TMember >: MemberMap < TClass, TMember > {
     public CustomMemberMap(MemberInfo member): base(member) {}

     public override MemberMap < TClass, TMember > ConvertUsing(Func < TClass, string > convertExpression) => base.ConvertUsing(row => convertExpression(row).Replace("\r", "").Replace("\n", ""));
 }

 public class CustomClassMap < TClass >: ClassMap < TClass > where TClass: new() {
     public override MemberMap < TClass, TMember > Map < TMember > (Expression < Func < TClass, TMember >> expression, bool useExistingMap = true) => new CustomMemberMap < TClass, TMember > (base.Map(expression, useExistingMap).Data.Member);
 }

 public sealed class CsvFileMapperAccommodation: CustomClassMap < Accommodation > {
     public CsvFileMapperAccommodation() {
         Map(m => m.Name).Name($ "AccommodationName").ConvertUsing(x => $ "{x.Name}");
         Map(m => m.ExternalKey).Name($ "AccommodationExternalKey").ConvertUsing(x => $ "{x.ExternalKey}");
         Map(m => m.Pension).Name($ "AccommodationPension").ConvertUsing(x => $ "{x.Pension}");
         Map(m => m.Category).Name($ "AccommodationCategory").ConvertUsing(x => $ "{x.Category}");
         Map(m => m.BuyingPrice).Name($ "AccommodationBuyingPrice").ConvertUsing(x => $ "{x.BuyingPrice}");
         Map(m => m.Margin).Name($ "AccommodationMargin").ConvertUsing(x => $ "{x.Margin}");
         Map(m => m.Price).Name($ "AccommodationPrice").ConvertUsing(x => $ "{x.Price}");
         Map(m => m.Quantity).Name($ "AccommodationQuantity").ConvertUsing(x => $ "{x.Quantity}");
         Map(m => m.Supplier).Name($ "AccommodationSupplier").ConvertUsing(x => $ "{x.Supplier}");
     }
 }

Объект (который я пытаюсь отобразить) содержит много свойства, поэтому в выводе у меня около 300 полей в строке, поэтому слишком сложно и не элегантно вручную изменить данные объекта в начале и значение для каждого из полей в конце. Поэтому я только пытаюсь отобразить этот объект в строку CSV, надеясь, что это можно изменить на лету.

1 Ответ

0 голосов
/ 06 февраля 2020

Я думаю, что создание пользовательского StringConverter может удовлетворить ваши потребности.

public class Program
{
    public static void Main(string[] args)
    {    
        var records = new List<Foo>()
        {
            new Foo {Property1 = "Property 1 with \r\n \\r\\n", Property2 = "Property2 with \n \\n"}
        };

        using (var csv = new CsvWriter(Console.Out, CultureInfo.InvariantCulture))
        {
            csv.Configuration.TypeConverterCache.AddConverter<string>(new FooStringConverter());

            csv.WriteRecords(records);
        }

        Console.ReadKey();
    }
}

public class Foo
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }
}

public class FooStringConverter: StringConverter
{
    public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
    {
        var stringValue = (string)value;

        if (stringValue != null)
        {
            stringValue = stringValue.Replace("\r", "").Replace("\n", "");
        }

        return base.ConvertToString(stringValue, row, memberMapData);
    }
}
...