Format an Excel column (or cell) as Text in C#? - c#

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?

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

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();
}
}

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:
I am not using SpreadsheetGear. I was interested in regular Excel
communication thru Excel interop without any 3rdparty libraries,
I was searching for the way to format column by number, not using
ranges like "A:A".

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

I've recently battled with this problem as well, and I've learned two things about the above suggestions.
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.
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.

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 = "#";

if (dtCustomers.Columns[j - 1].DataType != typeof(decimal) && dtCustomers.Columns[j - 1].DataType != typeof(int))
{
myWorksheet.Cells[i + 2, j].NumberFormat = "#";
}

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

//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);

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

Related

Change data type of excel Cell using Aspose?

We are to show data with Currency symbol ("TRL") in Excel cell with Currency type and we write the excel cell using this data "TRL 100.00" then that cell automatically converted in to General type instead of Currency type although we have changed the format of the particular cell using (styleFlag's property NumberFormat=true)
Please see the following sample code, its comments and the screenshot showing the output Excel file. The code first formats the cell A1 with TRL currency format. Then it formats the entire column C with TRL currency format.
C#
//Create workbook
Workbook wb = new Workbook();
//Access first worksheet
Worksheet ws = wb.Worksheets[0];
//Add some value in cell A1
Cell cell = ws.Cells["A1"];
cell.PutValue(22);
//Format cell A1 with TRL formatting
Style st = cell.GetStyle();
st.Custom = "[$TRL]\\ #,##0.00";
cell.SetStyle(st);
//Make the entire column C with TRL formatting
StyleFlag flg = new StyleFlag();
flg.NumberFormat = true;
ws.Cells.Columns[2].ApplyStyle(st, flg);
//Now enter data in column C cells
ws.Cells["C5"].PutValue(31);
ws.Cells["C6"].PutValue(32);
ws.Cells["C7"].PutValue(33);
ws.Cells["C8"].PutValue(34);
//Save the workbook
wb.Save("output.xlsx");
Screenshot:
Update - I
Screenshot showing the result of this following line.
st.Custom = "[$฿-41E]#,##0.00";
Note: I am working as Developer Evangelist at Aspose
Most easy way is set style number for the cells.
//$1,234.56
ws.Cells[1,1].Value = 1234.56;
var style=ws.Cells[1.1].GetStyle();
style.Number=5; // 5 is build-in style for currency
ws.Cells[1,1].SetStyle(style);
You can find all build-in styles here: https://docs.aspose.com/cells/net/list-of-supported-number-formats/

How to disable autoformat, when writing to Excel-Cell from C#

I have written an application which writes content into an Excelsheet. So far so good. But in some cases the autoformat function from Excel changed my values.
For example, I write 'true'/'false' to a cell, but Excel interprets it and translate it.
Second example, I write a telephonenumber to Excel and Excel cuts the leading '0', so '012345' changed to '12345'.
How can I say, that a cell is just a text/string cell?
This is a samplecode, how I write to Excel:
ws.get_Range("A1", "A1").Value = "true";
ws.get_Range("A1", "A1").Cells.WrapText = true;
ws.get_Range("A1", "A1").Rows.AutoFit();
best regards
Another way to make Excel treat values as text is to add ' in front of the values:
ws.get_Range("A1").Value = "'0123";
The ' will be visible only in the cell formula but not in it's value/text.
You can also set multiple cells at once:
object[,] values = { { "true", "0123" }, { "false", "0125" } };
var range = ws.get_Range("A1:B2")
range.NumberFormat = "#"; // Text format to treat the values as Text
range.Value = values
or
Clipboard.SetText("'true\t'01234\n'false\t'01235");
ws.get_Range("A1").PasteSpecial(); // or just ws.Paste();
Try this for leading zero
ws.get_Range("A1", "A1").NumberFormat = "#";
ws.get_Range("A1", "A1").Value = "012345";
For boolean value
ws.get_Range("B1", "B1").Value = "True/False";

Get the last cell (column, row) of a Excel range object

I have a Microsoft.Office.Interop.Excel.Range object and want to estimate the end-coordinates of that range ie (last column, last row).
There are no properties like LastCol, LastRow. The only properties are Column and Row, which specify the first cell. But how can I get the last cell of the range?
there is two way to do this :
Using Worksheet.UsedRange to determine the range. This will give you a range like A1:F10, or use Worksheet.UsedRange.SpecialCells(IExcel.XlCellType.xlCellTypeLastCell) to obtain F10.
With Range.End[IExcel.XlDirection] property, it returns the last continuous no-empty cell in the specified direction. Note that if the Range is empty, it will return the first no-empty cell or last cell(when excel reach its boundaries) in the given direction. Ex: the whole column A is empty, Range["A1"].End[IExcel.XlDirection.xlDown] will be A65535(last row in excel 97-2003, A1048576 for excel 2007)
//Just In case if you are wondering what IExcel is
using IExcel = Microsoft.Office.Interop.Excel;
This should get the first first and last cell of the range:
Initiate Excel.
Open workbook.
Select your range, in this case I got the used range of the active sheet.
Call the get_address method of the range.
Split the result of get_address on the colon.
The first value of the array resulting from the split will have the beginning cell.
The second value of the array resulting from the split will have the ending cell.
Replace the dollar signs with nothing and you will have the beginning and ending cells for the range.
Microsoft.Office.Interop.Excel.Application excel = new Application();
Microsoft.Office.Interop.Excel.Workbook workBook =
excel.Workbooks.Open(fileLocation);
Microsoft.Office.Interop.Excel.Worksheet sheet = workBook.ActiveSheet;
Microsoft.Office.Interop.Excel.Range range = sheet.UsedRange;
string address = range.get_Address();
string[] cells = address.Split(new char[] {':'});
string beginCell = cells[0].Replace("$", "");
string endCell = cells[1].Replace("$", "");
workBook.Close(true);
excel.Quit();
If you want the last column and last row relative to the beginning of the range you can do the following:
int lastColumn = range.Columns.Count;
int lastRow = range.Rows.Count;
Using Excel 2013, we've had lots of cases where UsedRange and xlCellTypeLastCell simply gave horribly wrong values.
For example, we'd have a worksheet containing just 7 columns, and sometimes these two functions would tell our C# code that there were 16,000+ columns of data.
The only method I found which truly worked out the bottom-right cell containing data was to use the tips in this suggestion:
sheet.Cells.Find()

How to enter data with leading zero into the excel using c# excel application

I want to enter data into the excel. Here i am having a problem while entering a data which is having some leading zero es.
For ex:
I want to enter 024[zero two four] into the excel and this data i am having in my datatable.
But in the excel generating it is being shown as 24.
You can set the cell format to TEXT before you do that. Since you are after all trying to store the text "024". In the same vein, if all your data is meant to be 3-digits, you can use a specific number format, such as "000".
cellReference.NumberFormat = "#";
cellReference.Value = "024";
or
cellReference.NumberFormat = "000";
cellReference.Value = "024";
Adding a Apostrophe before will solve this problem.
This will direct excel to treat cell as a text rather than number.
'024
will output
024
If you are using a DataTable you need to Take another DataTable and then you need to iterate through entire cells in the datatable and prepend the cells text with space i.e with '&nbsp';.We cannot modify the rows in the same table because it will throw an exception saying "Collection was Modified".We have to take a new datatable.
Consider the following code.
//To get the result with leading zero's in excel this code is written.
DataTable dtUpdated=new DataTable();
//This gives similar schema to the new datatable
dtUpdated = dtReports.Clone();
foreach (DataRow row in dtReports.Rows)
{
for (int i = 0; i < dtReports.Columns.Count; i++)
{
string oldVal = row[i].ToString();
string newVal = " "+oldVal;
row[i] = newVal;
}
dtUpdated.ImportRow(row);
}
We can bind this updated table to datagrid so that it can be useful for Excel Conversion.
I have found a way for this.
Instead of doing anything in the SQL query or to the value we can give a Excel formula of whatever we want to achieve.
For ex.
here i want to have 024 in excel. What i did is i edited the query and change the value so that it now looks like a formula in excel. So that when it will be entered in excel it will be treated as excel formula
string strf = "=CONCATENATE(" + 024 + ")";

How to convert Text values to number values in Excel 2003 (Number stored as Text), using C#

There appear to be a number of suggestions to do this, non of which appear to work.
Effectively, I'm wanting to change a text value in an Excel sheet to a number (this is a cell that has been set as a number stored as text, and has a green diamond next to it).
This webpage details how to resolve the issue in Excel, through the UI, and I've recorded this as a macro below (but that's VBA)...
Including setting the value to itself:
Range allCellsRng;
string lowerRightCell = "AZ500";
allCellsRng = wSheet.get_Range("A1", lowerRightCell).Cells;
foreach (Range cell in allCellsRng)
{
if (cell.Value2.ToString().Length > 0)
{
cell.Value2 = cell.Value2;
}
}
This is a recorded VB Macro, that shows what will resolve the issue, but I'm having problems representing this in C#:
ActiveCell.FormulaR1C1 = "0"
Range("A1").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlAdd, SkipBlanks _
:=False, Transpose:=False
Range("A1").Select
With Clear Office, the code is very easy:
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName);
foreach (Worksheet worksheet in spreadsheetDocument.Workbook.Sheets.OfType<Worksheet>())
{
foreach (Cell cell in worksheet.GetRange("A1:AZ500"))
{
string s = cell.Value as string;
if (s == null)
continue;
double d;
if (double.TryParse(s, out d))
cell.Value = d;
}
}
spreadsheetDocument.Save();
Would it not be better to change the format of the cell instead? I believe you should be able to grab the format using
range.NumberFormat
and change that to the actual format you want... You could then set the range for an entire column, or whole sheet.
Ok, so raising it as a question on here triggered a brainwave. This looks to work:
Range cellA1 = wSheet.get_Range("A1", System.Type.Missing);
cellA1.Value2 = "0";
cellA1.Copy(System.Type.Missing);
Range cellAll = wSheet.get_Range("A1:AZ500", System.Type.Missing);
cellAll.PasteSpecial(XlPasteType.xlPasteAll, XlPasteSpecialOperation.xlPasteSpecialOperationAdd,
false, false);

Categories

Resources