.NET - Excel file generated via data table - where to add formatting? - c#

We have a process to return results of a search, and export the data to Excel. It's converting the results to a data table, and adding the data table to a blank worksheet:
var wb = new XLWorkbook();
wb.Worksheets.Add(ds);
return wb;
The users want some formatting added to the sheet - setting date fields to display as MM/DD/YYYY, for example.
Can't find the right reference to get to the worksheet in the new workbook, however.
Also unsure if one can set a format to a column, as opposed to the code below which I think is converting it to a string,
((Excel.Range)sheet.Cells[i, 2]).EntireColumn.NumberFormat = "yyyy-MM-dd";
sheet.Cells[i, 2].Value2 = Convert.ToDateTime(dr["date"].ToString());
Anyone?
EDIT - #ScottHannen identified the library I should be investigating, and I've made more progress. I have drilled into the worksheets and successfully added the formatting, but it's not reflecting as such in the final document.
Here's the code:
var wb = new XLWorkbook();
wb.Worksheets.Add(ds);
foreach (IXLWorksheet ws in wb.Worksheets)
{
if (value == 1)
{
ws.Column(16).Style.DateFormat.Format = "yyyy-MM-dd";
ws.Column(17).Style.DateFormat.Format = "yyyy-MM-dd";
}
else
{ }
}
return wb;
When I look at the final document, the dates are still displaying as verbose - 12/7/2017 12:00:00 AM - but the formatting IS in the document. If I do the manual "hit enter in the cell and exit" thing, the formatting updates, as does doing Text to Columns.
Of course, I don't WANT to do that, I want the formatting to take straight away.
I assume the issue is that I'm adding the data first and formatting it after, just like a regular sheet. But is there a command in there to refresh/apply/what have you the formatting?

Related

C#: Finding exact string in excel sheet doesn't work with xlWhole

In my excel sheet I'm looking with my program for a key word like "Tescase". The parameter xlWhole dosen't find any range, but xlPart finds the key word. The problem with xlPart ist that it finds all the words in my excel sheet that contains the word "Testcase". But I would like to search only for the exact key word "Testcase".
Hear is my code:
var app = new Application();
var workbook = app.Workbooks.Open(pExcelFile);
var worksheet = (Worksheet)workbook.Worksheets.get_Item(1);
Range range = worksheet.UsedRange;
Range findTestcaseColumn = range.Find(What: "Testcase", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole);
if (findTestcaseColumn != null ) {
// found
} else {
//not found
}
But xlPart finds the key word "Testcase":
Range findTestcaseColumn = range.Find(What: "Testcase", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlPart);
Thanks for suggetions.
Same problem here from VBA inside Excel: I fill a cell with a text, then come back later with .find to add something in the cell next to it. With xlPart I find the cell, with xlWhole it fails. Very strange behaviour. Resetting the style of the search column back to standard is a solution, but that's insane of course. It should ignore the style or have an option to do so.
Please join me giving feedback to Microsoft.
https://learn.microsoft.com/nl-nl/office/vba/api/excel.range.find

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 add a Data validation for a cell in excel using Spreadsheetgear - C# .NET

I would like to add a data validation for a cell in an excel to allow ONLY numeric values.
My code does the following,
SpreadSheetGearHelper hlpr = new SpreadSheetGearHelper(excelFilePath);
cells = workbook.Worksheets[0].Cells;
hlpr.WorkSheet(0).Cells[string.Format("{0}:{0}", colName)].Validation.Add(SpreadsheetGear.ValidationType.WholeNumber, ValidationAlertStyle.Stop,
ValidationOperator.Between, "-9999999", "9999999");
hlpr.WorkSheet(0).Cells[string.Format("{0}:{0}", colName)].NumberFormat = "#";
hlpr.WorkSheet(0).Cells[string.Format("{0}:{0}", colName)].Validation.ErrorMessage = "Please enter a number";
But when I enter valid number within the range in excel it still says "Please enter a number".
Can someone please help me out with this
You're currently using the ValidationType.WholeNumber, which will only allow whole numbers such as 1, 2, 3 and not decimals such as 1.23. If you need to allow all numeric values and not just whole numbers you need to specify ValidationType.Decimal. Example:
using SpreadsheetGear;
...
IWorkbook workbook = Factory.GetWorkbook();
IWorksheet worksheet = workbook.ActiveWorksheet;
IRange cells = worksheet.Cells;
cells["A1"].Validation.Add(ValidationType.Decimal, ValidationAlertStyle.Stop,
ValidationOperator.Between, "-9999999", "9999999");
Take a look at this: Apply-Data-Validation-to-Excel-Cells-in-Csharp - CodeProject
sheet.Range["C9"].DataValidation.AllowType = CellDataType.Decimal;
sheet.Range["C9"].DataValidation.Formula1 = "-9999999";
sheet.Range["C9"].DataValidation.Formula2 = "9999999";
sheet.Range["C9"].DataValidation.CompareOperator = ValidationComparisonOperator.Between;
sheet.Range["C9"].DataValidation.InputMessage = "Type a number between -9999999-9999999 in this cell.";
I am not familar with SpreadsheetGear but the solution in this article works fine at my side.
Fixed it.
The Number Format of the cell was set to text, and that was why it was giving me an error every time I had entered a number (Even though the data validation was set correctly). Hence I added the below line of code to change it to "General"
hlpr.WorkSheet(0).Cells[string.Format("{0}:{0}", colName)].NumberFormat = "General";
Thank you guys for your time and responses.

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 + ")";

Format an Excel column (or cell) as Text in 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

Categories

Resources