49

I am losing the leading zeros when I copy values from a datatable to an Excel sheet. That's because probably Excel treats the values as a number instead of text.

I am copying the values like so:

myWorksheet.Cells[i + 2, j] = dtCustomers.Rows[i][j - 1].ToString();

How do I format a whole column or each cell as Text?

A related question, how to cast myWorksheet.Cells[i + 2, j] to show a style property in Intellisense?

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Tony_Henrich
  • 42,411
  • 75
  • 239
  • 374
  • Take a look here https://stackoverflow.com/questions/20648149/what-are-numberformat-options-in-excel-vba/49621979#49621979 – NoWar Apr 03 '18 at 04:13

10 Answers10

53

Below is some code to format columns A and C as text in SpreadsheetGear for .NET which has an API which is similar to Excel - except for the fact that SpreadsheetGear is frequently more strongly typed. It should not be too hard to figure out how to convert this to work with Excel / COM:

IWorkbook workbook = Factory.GetWorkbook();
IRange cells = workbook.Worksheets[0].Cells;
// Format column A as text.
cells["A:A"].NumberFormat = "@";
// Set A2 to text with a leading '0'.
cells["A2"].Value = "01234567890123456789";
// Format column C as text (SpreadsheetGear uses 0 based indexes - Excel uses 1 based indexes).
cells[0, 2].EntireColumn.NumberFormat = "@";
// Set C3 to text with a leading '0'.
cells[2, 2].Value = "01234567890123456789";
workbook.SaveAs(@"c:\tmp\TextFormat.xlsx", FileFormat.OpenXMLWorkbook);

Disclaimer: I own SpreadsheetGear LLC

Mo Patel
  • 2,321
  • 4
  • 22
  • 37
Joe Erickson
  • 7,077
  • 1
  • 31
  • 31
16

If you set the cell formatting to Text prior to adding a numeric value with a leading zero, the leading zero is retained without having to skew results by adding an apostrophe. If you try and manually add a leading zero value to a default sheet in Excel and then convert it to text, the leading zero is removed. If you convert the cell to Text first, then add your value, it is fine. Same principle applies when doing it programatically.

        // Pull in all the cells of the worksheet
        Range cells = xlWorkBook.Worksheets[1].Cells;
        // set each cell's format to Text
        cells.NumberFormat = "@";
        // reset horizontal alignment to the right
        cells.HorizontalAlignment = XlHAlign.xlHAlignRight;

        // now add values to the worksheet
        for (i = 0; i <= dataGridView1.RowCount - 1; i++)
        {
            for (j = 0; j <= dataGridView1.ColumnCount - 1; j++)
            {
                DataGridViewCell cell = dataGridView1[j, i];
                xlWorkSheet.Cells[i + 1, j + 1] = cell.Value.ToString();
            }
        }
svenGUTT
  • 399
  • 4
  • 11
13

Solution that worked for me for Excel Interop:

myWorksheet.Columns[j].NumberFormat = "@";      // column as a text
myWorksheet.Cells[i + 2, j].NumberFormat = "@"; // cell as a text

This code should run before putting data to Excel. Column and row numbers are 1-based.

A bit more details. Whereas accepted response with reference for SpreadsheetGear looks almost correct, I had two concerns about it:

  1. I am not using SpreadsheetGear. I was interested in regular Excel communication thru Excel interop without any 3rdparty libraries,
  2. I was searching for the way to format column by number, not using ranges like "A:A".
sarh
  • 6,371
  • 4
  • 25
  • 29
7

Before your write to Excel need to change the format:

xlApp = New Excel.Application
xlWorkSheet = xlWorkBook.Sheets("Sheet1")

Dim cells As Excel.Range = xlWorkSheet.Cells

'set each cell's format to Text
cells.NumberFormat = "@"

'reset horizontal alignment to the right
cells.HorizontalAlignment = Excel.XlHAlign.xlHAlignRight
Allan Pereira
  • 2,572
  • 4
  • 21
  • 28
sansalk
  • 4,595
  • 2
  • 36
  • 37
4

I've recently battled with this problem as well, and I've learned two things about the above suggestions.

  1. Setting the numberFormatting to @ causes Excel to left-align the value, and read it as if it were text, however, it still truncates the leading zero.
  2. Adding an apostrophe at the beginning results in Excel treating it as text and retains the zero, and then applies the default text format, solving both problems.

The misleading aspect of this is that you now have a different value in the cell. Fortuately, when you copy/paste or export to CSV, the apostrophe is not included.

Conclusion: use the apostrophe, not the numberFormatting in order to retain the leading zeros.

crthompson
  • 15,653
  • 6
  • 58
  • 80
Scott
  • 41
  • 1
  • 4
    Both setting the NumberFormat = "@" and prefixing the value with an apostrophe retained leading zeros for me. When using the NumberFormat method, to retain right alignment in the column, you can simply add the following: `rng.NumberFormat = "@"; rng.HorizontalAlignment = Excel.XlHAlign.xlHAlignRight`; Or one of the other alignment methods found here: [link]http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(MICROSOFT.OFFICE.INTEROP.EXCEL.RANGE.HORIZONTALALIGNMENT);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true – Ted Jul 24 '12 at 10:31
3

Use your WorkSheet.Columns.NumberFormat, and set it to string "@", here is the sample:

Excel._Worksheet workSheet = (Excel._Worksheet)_Excel.Worksheets.Add();
//set columns format to text format
workSheet.Columns.NumberFormat = "@";

Note: this text format will apply for your hole excel sheet!

If you want a particular column to apply the text format, for example, the first column, you can do this:

workSheet.Columns[0].NumberFormat = "@";

or this will apply the specified range of woorkSheet to text format:

workSheet.get_Range("A1", "D1").NumberFormat = "@";
Lester
  • 1,112
  • 2
  • 15
  • 22
2
   if (dtCustomers.Columns[j - 1].DataType != typeof(decimal) && dtCustomers.Columns[j - 1].DataType != typeof(int))
   {
      myWorksheet.Cells[i + 2, j].NumberFormat = "@";
   }
Arsac
  • 55
  • 1
  • 2
  • 7
2

I know this question is aged, still, I would like to contribute.

Applying Range.NumberFormat = "@" just partially solve the problem:

  • Yes, if you place the focus on a cell of the range, you will read text in the format menu
  • Yes, it align the data to the left
  • But if you use the type formula to check the type of the value in the cell, it will return 1 meaning number

Applying the apostroph behave better. It sets the format to text, it align data to left and if you check the format of the value in the cell using the type formula, it will return 2 meaning text

Patrik
  • 401
  • 1
  • 6
  • 23
0
//where [1] - column number which you want to make text

ExcelWorksheet.Columns[1].NumberFormat = "@";


//If you want to format a particular column in all sheets in a workbook - use below code. Remove loop for single sheet along with slight changes.

  //path were excel file is kept


     string ResultsFilePath = @"C:\\Users\\krakhil\\Desktop\\TGUW EXCEL\\TEST";

            Excel.Application ExcelApp = new Excel.Application();
            Excel.Workbook ExcelWorkbook = ExcelApp.Workbooks.Open(ResultsFilePath);
            ExcelApp.Visible = true;

            //Looping through all available sheets
            foreach (Excel.Worksheet ExcelWorksheet in ExcelWorkbook.Sheets)
            {                
                //Selecting the worksheet where we want to perform action
                ExcelWorksheet.Select(Type.Missing);
                ExcelWorksheet.Columns[1].NumberFormat = "@";
            }

            //saving excel file using Interop
            ExcelWorkbook.Save();

            //closing file and releasing resources
            ExcelWorkbook.Close(Type.Missing, Type.Missing, Type.Missing);
            Marshal.FinalReleaseComObject(ExcelWorkbook);
            ExcelApp.Quit();
            Marshal.FinalReleaseComObject(ExcelApp);
KR Akhil
  • 877
  • 3
  • 15
  • 32
  • 1
    i am having problem with comma seprator data like this 12345,1234,1234,3456 will it solve my problem ? –  Feb 21 '18 at 04:30
  • 2
    @DeepakJain - Did your problem solve? If not, update me, i will help – KR Akhil Feb 21 '18 at 07:03
  • nope.i am importing dataset to excel and one of the excel sheet cantains a column which has Data like this 123,124,12534,123450,876 and Excel not able to show the data properly. –  Feb 22 '18 at 04:17
  • my code https://stackoverflow.com/questions/48891182/garbage-data-coming-while-importing-dataset-to-excel-for-number-with –  Feb 22 '18 at 04:18
  • 1
    **You just have to change the format of that column or cell to text.** '//Format to text ExcelWorksheet.Columns[1].NumberFormat = "@";' if you are still having trouble let me know. As i was able to solve this on my end. – KR Akhil Feb 22 '18 at 07:19
  • ` ExcelWorksheet.Columns[1].NumberFormat = "@";` – KR Akhil Feb 22 '18 at 07:25
0

You need to format the column to be a string.

You can use the link https://supportcenter.devexpress.com/ticket/details/t679279/import-from-excel-to-gridview

For converting the ExcelDataSource, you can also refer to https://supportcenter.devexpress.com/ticket/details/t468253/how-to-convert-exceldatasource-to-datatable

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 05 '22 at 10:14