1

I am exporting a gridview full of data to a CSV file, one of the columns contains a coupon number that is up to 18 digits long, non floating point. The number needs to be displayed as their full number the csv file in Excel. When I open the csv file in Excel, for example, 720137994699937608 and the others display as:

enter image description here

Then when I resize the column or change the column type to number the coupon number gets displayed as:

enter image description here


You'll notice that excel changed the coupon number into a floating point number and now the numbers within the coupon number have been replaced with zeros at the end. This is bad.

Here is my export code:

protected void btnExport_Click(object sender, EventArgs e)
        {
            Response.Clear();
            Response.Buffer = true;
            Response.AddHeader("content-disposition",
             "attachment;filename=Reports All Prizes.csv");
            Response.Charset = "";
            Response.ContentType = "csv";

            StringBuilder sb = new StringBuilder();

            sb.Append("FirstName" + ',');
            sb.Append("LastName" + ',');
            sb.Append("CouponNumber" + ',');
            string[] splitColumns = sb.ToString().Split(new Char[] { ',' });
            //append new line
            sb.Append("\r\n");

            for (int i = 0; i < gvReportsAllPrizes.Rows.Count; i++)
            {
                foreach (string column in splitColumns)
                {
                    if (column == "FirstName")
                    {
                        //capatilize first letter.
                        string first = Globals.ReplaceHTML(gvReportsAllPrizes.Rows[i].Cells[1].Text.Trim());
                        if (string.IsNullOrEmpty(first))
                        {
                            first = "";
                        }
                        if (!string.IsNullOrEmpty(first))
                        {
                            first = first.ToLower();//convert to lowercase before uppercasing the first letter.
                            first = "\"" + first.First().ToString().ToUpper() + String.Join("", first.Skip(1)) +
                                "\"";
                        }
                        sb.Append(first + ',');
                    }
                    else if (column == "LastName")
                    {
                        //capatilize first letter.
                        string last = Globals.ReplaceHTML(gvReportsAllPrizes.Rows[i].Cells[2].Text.Trim());
                        if (string.IsNullOrEmpty(last))
                        {
                            last = "";
                        }
                        if (!string.IsNullOrEmpty(last))
                        {
                            last = last.ToLower();//convert to lowercase before uppercasing the first letter.
                            last = "\"" + last.First().ToString().ToUpper() + String.Join("", last.Skip(1)) +
                                "\"";
                        }
                        sb.Append(last + ',');
                    }
                    else if (column == "CouponNumber")
                    {
                        string cn = Globals.ReplaceHTML(gvReportsAllPrizes.Rows[i].Cells[8].Text.Trim());
                        if (string.IsNullOrEmpty(cn))
                        {
                            cn = "";
                        }
                        if (!string.IsNullOrEmpty(cn))
                        {
                            sb.Append("\"" + cn + "\"" + ',');
                        }
                        else
                        {
                            sb.Append(cn + ',');
                        }
                    }

                }
                //append new line
                sb.Append("\r\n");
            }
            Response.Output.Write(sb.ToString());
            Response.Flush();
            Response.End();
        }

public static string ReplaceHTML(string strInput)
{
    strInput = strInput.Replace("&quot;", "\"" + "\"");
    strInput = strInput.Replace("&amp;",  "&");
    strInput = strInput.Replace("&nbsp;", string.Empty);
    strInput = strInput.Replace("''", "'");
    return strInput.Replace("&#39;", "'").Trim();
}

Raw txt file csv:

FirstName,LastName,CouponNumber, "first","last","720137994699937608"

EdSF
  • 11,753
  • 6
  • 42
  • 83
cpeterson
  • 63
  • 1
  • 9
  • 1
    Can you post some of the raw text from the CSV. The `"` around the CouponNumber column should have fixed that problem. – CodingGorilla Jul 24 '14 at 21:16
  • FirstName,LastName,CouponNumber, "first","last","720137994699937608" – cpeterson Jul 24 '14 at 21:19
  • @CodingGorilla The quotes don't make a difference to Excel; it just makes its best guess at what everything is unless you tell it differently. – Casey Jul 24 '14 at 21:20
  • @emodendroket I thought that putting into quotes made it treat the value as a string, if that's not the case, how do you indicate the data type with a CSV? – CodingGorilla Jul 24 '14 at 21:22
  • possible duplicate of [Format an Excel column (or cell) as Text in C#?](http://stackoverflow.com/questions/2067926/format-an-excel-column-or-cell-as-text-in-c) – crthompson Jul 24 '14 at 21:22
  • 1
    @CodingGorilla You can't. All putting things in quotes does is escape commas and line breaks, basically. – Casey Jul 24 '14 at 21:23
  • 2
    if you put a single quote in front of your number value in excel, it will be automatically formatted as text. Obviously, OP's question has nothing to do with CSV's, only viewing them in Excel. – crthompson Jul 24 '14 at 21:24
  • 2
    @CodingGorilla You *can* use the "import data" option in Excel to explicitly say what type of date is expected in each column though. But you have to do that each time you open a file. – Casey Jul 24 '14 at 21:24
  • The only other possible idea I'd have is to use the `Microsoft.VisualBasic.FileIO.TextFieldParser` (yes, in the VB namespace!!); whether if the CSV is created with that (and you can tell it that fields will be enclosed in quotes using the `HasFieldsEnclosedInQuotes` property), this imbues it with some metadata that Excel can interpret and display the values correctly, but a) it's a long shot and b) I don't have a copy of Excel handy to check. – dyson Jul 24 '14 at 21:30
  • 1
    @barrick, that wont work. Plus, you dont want to put metadata in a CSV. If you want an Excel file, write and Excel file, not a CSV. – crthompson Jul 24 '14 at 21:38
  • @paqogomez Fair point. Had I had Excel on this machine, I'd have given it a whirl and found the same thing myself. Of course there's going to be no header or the like in a CSV. – dyson Jul 24 '14 at 21:39
  • 2
    Dear OP, there is a lot of information flying around. Most of it nonsense. The bottom line is that you are creating a CSV, but want to display it in Excel. Import wizard is a good idea, so is putting a single quote in front of your coupon name. The real answer is however to write an Excel file rather than a CSV. – crthompson Jul 24 '14 at 21:44

4 Answers4

4

You can wrap each value like this:

"=""DATA HERE"""

For example:

Column1,Column2
"=""1231231231231323121321""","=""123"""

Obviously it isn't pretty in the csv file, but it imports into excel as you want.

crthompson
  • 15,653
  • 6
  • 58
  • 80
Moop
  • 3,414
  • 2
  • 23
  • 37
  • A single quote ie. `'123123123` does the same thing. – crthompson Jul 24 '14 at 21:39
  • @paqogomez No it doesn't, the single quote shows up in the field in excel. This doesn't show any additional characters in the cell – Moop Jul 24 '14 at 21:40
  • I'll give you that it works, but i'm opposed to putting metadata in a CSV. If you want an excel file, write an excel file IMO. – crthompson Jul 24 '14 at 21:50
  • 2
    @paqogomez Agreed, but sometimes writing an excel file for a simple output is too much work. At least there is some way, albeit ugly looking, to do what he wants without too much effort – Moop Jul 24 '14 at 21:51
  • This work for me. I write like this : writer.Write("\"=\"\"" + item.COUPON + "\"\"\""); – Hayu Rahiza Oct 01 '19 at 09:23
3

You can't do anything about it if you're using a CSV file. As others have mentioned, this is an Excel formatting issue. I would suggest using an Excel library of some sort if you want to manage your document's formatting.

Bruno
  • 533
  • 1
  • 6
  • 27
0

Excel's maximum precision is 15 digits. Would it be anathema to display these as strings?

dyson
  • 866
  • 6
  • 12
  • He is already putting quotes around the number in the CSV file, or at least that's what his code shows. – CodingGorilla Jul 24 '14 at 21:17
  • Just looking above, I'd presumed that preprending a ' to the number would have it rendered as a string in Excel, but perhaps that's not the case. – dyson Jul 24 '14 at 21:26
  • 1
    For those playing at home: Anathema - a formal curse by a pope or a council of the Church, excommunicating a person or denouncing a doctrine. Or... something someone doesnt like. – crthompson Jul 24 '14 at 21:35
  • A perfect summary of my experiences of integrating with Excel, especially via COM. – dyson Jul 24 '14 at 21:37
0

If there's no need for the CSV file you can directly export the gridview to excel. However, if you still need the csv file the easiest way to display the long number in excel column is to convert that column to text prior to importing csv to excel.

Here're the steps.

  1. Open excel. Click on open, locate the file. Once you open you will get the following screen. enter image description here

  2. Choose Delimited and click next. Select Other add (,) and then click next.

enter image description here

  1. On the next screen highlight the column and press text. enter image description here

Here's the final result:

enter image description here

smr5
  • 2,593
  • 6
  • 39
  • 66
  • The idea of "converting to text" is meaningless when you're talking about a CSV. *Everything* is text. Only Excel is trying to impose greater meaning on the file. – Casey Jul 24 '14 at 21:50
  • Unless there're some reasons why the person is going from grid to csv to excel why not just go straight from csv to excel? Or use the Text Import Wizard of excel to convert that CouponNumber column to text before exporting the csv to excel. – smr5 Jul 24 '14 at 21:54
  • I'm not opposed to that at all, but your code doesn't do anything to achieve that? – Casey Jul 24 '14 at 21:55