19

Possible Duplicate:
Writing a CSV file in .net

Are there any good CSV writers for C#?

Don't need a reader, just writer.

Community
  • 1
  • 1
mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • 3
    http://stackoverflow.com/questions/1941392/are-there-any-csv-readers-writer-libs-in-c specifically, this comment: http://stackoverflow.com/questions/1941392/are-there-any-csv-readers-writer-libs-in-c/2094885#2094885 – CanSpice Jan 13 '11 at 21:55
  • sorry my bad. comment deleted – Simon Jan 14 '11 at 03:20

2 Answers2

46

There's not much to it, really... here's some code I've used for several years:

public static class Csv
{
    public static string Escape( string s )
    {
        if ( s.Contains( QUOTE ) )
            s = s.Replace( QUOTE, ESCAPED_QUOTE );

        if ( s.IndexOfAny( CHARACTERS_THAT_MUST_BE_QUOTED ) > -1 )
            s = QUOTE + s + QUOTE;

        return s;
    }

    public static string Unescape( string s )
    {
        if ( s.StartsWith( QUOTE ) && s.EndsWith( QUOTE ) )
        {
            s = s.Substring( 1, s.Length - 2 );

            if ( s.Contains( ESCAPED_QUOTE ) )
                s = s.Replace( ESCAPED_QUOTE, QUOTE );
        }

        return s;
    }


    private const string QUOTE = "\"";
    private const string ESCAPED_QUOTE = "\"\"";
    private static char[] CHARACTERS_THAT_MUST_BE_QUOTED = { ',', '"', '\n' };
}

You can use the Escape method to ensure that values are properly quoted. I use this class in conjunction with a simple reader, but you said you don't need that...

Update It's simple, but there is more to it than string.Join. However, you can still get away with something pretty simple, if you have an array of values (and are using C# 3+):

string.Join(",", values.Select(Csv.Escape));
harpo
  • 41,820
  • 13
  • 96
  • 131
  • Wouldn't it be easier to quote and escape everything? Or is this to conserve file size or something? – mpen Jan 13 '11 at 22:00
  • You could quote and escape everything, I guess, but it's not very elegant. – harpo Jan 13 '11 at 22:00
  • Long as my SQL database understand how to import it, it's all good. – mpen Jan 13 '11 at 22:02
  • Is it really faster to test for the presence of characters that need to be escaped before actually escaping them? Seems like it's going to have to read through the string no matter what and if there's nothing to escape then I wouldn't think it'd be any slower. I might test this out for myself later but if anyone knows then please enlighten me. – Brandon Moore Aug 30 '12 at 18:33
  • That is, if there's nothing to escape then I wouldn't think it'd be any slower to just run the code to escape them without testing whether you need to or not first. – Brandon Moore Aug 30 '12 at 18:34
  • 1
    @BrandonMoore, it's a good question. If `String.Replace` worked in-place, that would probably be better. I wrote it that way on the assumption that, since `string` is immutable, Replace will give you a new instance every time (even if it makes no replacements). You'd have to look at the implementation of `String.Replace` to be sure. Of course, you need a new instance when characters do require escaping, but I'm also assuming that's an exceptional case. – harpo Aug 30 '12 at 20:17
13

Writing is fairly trivial, but libraries can do a lot of nice things for you. Such as writing out custom objects.

Here is an example of CsvHelper (a library I maintain) writing objects.

// Custom object.
public class MyCustomObject
{
    public string StringProperty { get; set; }
    public int IntProperty { get; set; }
}

// Writing the CSV file.
var myCustomObjectList = new List<MyCustomObject>
{
    new MyCustomObject { StringProperty = "one", IntProperty = 1 },
    new MyCustomObject { StringProperty = "two", IntProperty = 2 }
};
var csv = new CsvHelper( File.OpenWrite( "some-file.csv" ) );
csv.Writer.WriteRecords( myCustomObjectList );

By default, conventions are used for writing the headers. This is all configurable.

// Output:
StringProperty,IntProperty
one,1
two,2
Josh Close
  • 22,935
  • 13
  • 92
  • 140
  • Good stuff. Glad that it is easily injectable and mockable too. – Ian1971 Apr 04 '14 at 12:43
  • Great library, made building a csv from an object so simple. Would recommend `using` though for IO operations. A good example of usage found [here](https://stackoverflow.com/a/38088636/692942). – user692942 Oct 09 '17 at 11:32