1

I have a set codes, 0075, 0062 etc saved as a string in my database and declared as string in my model. However, when I am exporting my details in CSV using CSV Helper, the codes are not saved as text but as number. That is, 0075 saved as 75. I have tried adding "=" in front of the string, but this does not work. Or tried it as below. But in vain. Below is my code:

streamWriter.WriteLine("Code;");
streamWriter.WriteLine(string.Join(";", "\""+result.Code+"\""));

Any idea how to saved result.Code which is declared as a string, as a text in my CSV?

Code as declared in the model:

public string Code { get; set; }
user3762810
  • 143
  • 1
  • 3
  • 13
  • What is the type of `result.Code`? If it's a `string` your problem is deeper in your code. If it's an `int` then try `result.Code.ToString("0000")`. – Enigmativity Dec 02 '15 at 04:31
  • I feel its default excel behavior.. You have some settings to make in excel sheet to display that value.. Usually in columns it will not display but when you focus on that column, you can see the actual result at the top, if am not wrong. – Guruprasad J Rao Dec 02 '15 at 04:31
  • What do you use to open your csv file? MsExcel? Open the file in notepad++ and see whether those 0s are there or not. – Kosala W Dec 02 '15 at 04:31
  • I missed the line where you said `result.Code` was a `string`. You need to show us the code that assigns `result.Code` as that's where your problem is. – Enigmativity Dec 02 '15 at 04:32
  • @Enigmativity: I have added the code in the question. – user3762810 Dec 02 '15 at 04:44
  • @KosalaW: When I open the CSV file, it is an MSExcel which is opened and the leading 0s are not there. – user3762810 Dec 02 '15 at 04:45
  • @GuruprasadRao: I know we have some setting in excel which can change the format, but I want the string here, 0075 to be saved as a text instead as a number. – user3762810 Dec 02 '15 at 04:46
  • @user3762810: That's the default behaviour of Excel. Do you know how to open a file in notepad++. I know it sounds silly.. But let us know if you do not know. – Kosala W Dec 02 '15 at 04:46
  • **[This might help you](http://stackoverflow.com/a/2068060/2065039)** – Guruprasad J Rao Dec 02 '15 at 04:53
  • @KosalaW: In notepad++, it is saved as a string. But I want it to be saved as a text in CSV, not in notepad++. – user3762810 Dec 02 '15 at 04:53
  • @user3762810: I am sorry, but no one in this forum will be able to help you beyond this. Please read more about what's csv before trying to develop something to create a csv file. – Kosala W Dec 02 '15 at 05:04
  • CSV is data separated by commas. You are using semicolons. – jdweng Dec 02 '15 at 05:05
  • Looks like this works: [Formatting a comma-delimited CSV to force Excel to interpret value as a string](http://superuser.com/questions/318420/formatting-a-comma-delimited-csv-to-force-excel-to-interpret-value-as-a-string) – dbc Dec 02 '15 at 05:58
  • @jdweng - Excel uses `;` in CSV files when `,` is the decimal separator. See [excel ignores system list separator](http://superuser.com/questions/408191/excel-ignores-system-list-separator). – dbc Dec 02 '15 at 06:01
  • @user3762810 - Sorry, but I asked for the code where `result.Code` was **asssigned**, not where is it **defined**. Can you provide that? – Enigmativity Dec 02 '15 at 10:23
  • @Enigmativity: It is just assigned as code="0075" – user3762810 Dec 02 '15 at 12:07
  • @user3762810 - Have you looked at the output CSV using notepad? Does it show `"0075";` or `"75";`? If it's the former then your CSV is fine and what you're opening it with normally is converting it. If it's the latter then the assignment isn't happening as expected. – Enigmativity Dec 02 '15 at 12:41

1 Answers1

0

Looks like the method suggested by Formatting a comma-delimited CSV to force Excel to interpret value as a string works (on Excel 2010 at least), which is to format each cell as

"=""String Value"""

Here's a static helper class that does the necessary work. Since you used ; for a delimiter I reckon you are in a region where , is the decimal separator; to generalize my answer I'm using System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator as the list separator.

public static class CsvWriter
{
    public static void WriteToCsv(IEnumerable<string> cells, TextWriter writer, CultureInfo cultureInfo = null)
    {
        if (cells == null || writer == null)
            throw new ArgumentNullException();
        string listSeparator = (cultureInfo ?? System.Globalization.CultureInfo.CurrentCulture).TextInfo.ListSeparator;
        bool first = true;
        foreach (var cell in cells)
        {
            if (!first)
                writer.Write(listSeparator);
            writer.Write(ToCsvCell(cell));
            first = false;
        }
        writer.Write("\r\n");
    }

    public static void WriteToCsv<TEnumerable>(IEnumerable<TEnumerable> lines, TextWriter writer, CultureInfo cultureInfo = null) where TEnumerable : IEnumerable<string>
    {
        if (lines == null || writer == null)
            throw new ArgumentNullException();
        cultureInfo = cultureInfo ?? System.Globalization.CultureInfo.CurrentCulture;
        foreach (var cells in lines)
            WriteToCsv(cells, writer, cultureInfo);
    }

    public static string ToCsv<TEnumerable>(IEnumerable<TEnumerable> lines, CultureInfo cultureInfo = null) where TEnumerable : IEnumerable<string>
    {
        using (var writer = new StringWriter())
        {
            WriteToCsv(lines, writer, cultureInfo);
            return writer.ToString();
        }
    }

    static string ToCsvCell(string s)
    {
        if (s == null)
            return "";
        s = s.Replace("\"", "\"\"\"\"");
        return string.Format("\"=\"\"{0}\"\"\"", s);
    }
}

Then, to test:

        var lines = new[] 
        {
            new [] { "0075", "0062", "abc", DateTime.Today.ToShortDateString() },
            new [] { "I said \"this is a quote\"" },
            new [] { "Embedded new line: \r\nSecond Line",  string.Concat(Enumerable.Repeat(System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator, 5).ToArray()) },
        };
        var path = Path.Combine(Path.GetTempPath(), "TestQuestion34034950.csv");
        using (var writer = new StreamWriter(path))
        {
            CsvWriter.WriteToCsv(lines, writer);
        }
        Console.WriteLine("Wrote " + path);

Excel will interpret all the CSV cells created by the above as string literals.

dbc
  • 104,963
  • 20
  • 228
  • 340