JoshClose / CsvHelper

Library to help reading and writing CSV files
http://joshclose.github.io/CsvHelper/
Other
4.74k stars 1.06k forks source link

double datatype is being written to csv with ' prepended to string #2208

Closed JackMcBride98 closed 7 months ago

JackMcBride98 commented 10 months ago

Describe the bug I have double datatypes in my MemberMap

When I write to Csv they are coming out as '48.897736484133866 or '0.1000294643384941

I could not figure out why from the documentation or googling.

Expected behavior It writes to the csv file without the prepended '

Additional context

I fixed this with this

image

and

image

but surely there is a better way?

AltruCoder commented 10 months ago

Can you provide a fully working example that outputs the double value with a prepended ' ? The following works fine for me, with no prepended '

void Main()
{
    var values = new List<Foo>{
        new Foo { Id = 1, DoubleValue = 48.897736484133866 },
        new Foo { Id = 2, DoubleValue = 0.1000294643384941 },
    };
    var csv = new CsvWriter(Console.Out, CultureInfo.InvariantCulture);
    csv.WriteRecords(values);
}

public class Foo
{
    public int Id { get; set; }
    public double DoubleValue { get; set; }
}
JackMcBride98 commented 10 months ago
void Main()
{
    await using var memoryStream = new MemoryStream();
    await using var streamWriter = new StreamWriter(memoryStream);
    using var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture);
    csvWriter.Configuration.RegisterClassMap<RowMap>();

    var csvRows = new List<Row>() { new Double(1076.5525217894019), new Double(37071.25726283525) } 

    csvWriter.WriteRecords(csvRows);
    await streamWriter.FlushAsync();

     var csvArray = memoryStream.ToArray();
     return new Response(csvArray, "heat-loss.csv");
}

public class Row
{
    public double Double { get; }

    public Row(double double){
        Double = double;
    }
}

public sealed class RowMap : ClassMap<Row>
{
    Map(m => m.Double).Name("Double")
}

I'm sorry if this not quite working (I've got a lot of work to be getting on with today), but this is roughly how it is in our system. We are using v 30.0.1

AltruCoder commented 10 months ago

I wasn't setup to return new Response so I just wrote the MemoryStream to a FileStream. I still can't recreate the prepended ' that you are getting. There has to be something else going on here.

async void Main()
{
    await using var memoryStream = new MemoryStream();
    await using var streamWriter = new StreamWriter(memoryStream);
    using var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture);
    csvWriter.Context.RegisterClassMap<RowMap>();

    var csvRows = new List<Row>() { new Row(1076.5525217894019), new Row(37071.25726283525) };

    csvWriter.WriteRecords(csvRows);
    await streamWriter.FlushAsync();

    using (FileStream file = new FileStream(@"C:\Temp\heat-loss.csv", FileMode.Create, FileAccess.Write))
    {
        memoryStream.WriteTo(file);
    }
}

public class Row
{
    public double Double { get; }

    public Row(double value)
    {
        Double = value;
    }
}

public sealed class RowMap : ClassMap<Row>
{
    public RowMap()
    {
        Map(m => m.Double).Name("Double");
    }   
}
ajorkowski commented 10 months ago

@AltruCoder Try using a negative value - it is adding the escape character ' because the negative value starts with - (I have a feeling they may be using InjectionOptions = InjectionOptions.Escape)

AltruCoder commented 10 months ago

@ajorkowski I do see where you can get the ' character if the value is negative and you set InjectionOptions = InjectionOptions.Escape. The problem is @JackMcBride98 made no mention of either of those things being the case.

JoshClose commented 7 months ago

Is this still an issue?

JackMcBride98 commented 7 months ago

Not as far as I'm aware