Why is the Date in Row being transformed automatically? - c#

I'm using Miscrosoft Office Interop Excel to sort and manage a ".csv" file and create an excel file.
When I copy one cell that contains a date for example :
"04/05/2018 18:55"
I substring that into
"04/05/2018"
and paste it into another cell, it transforms it into this weird number
43195
Why is this happening? How can I prevent or modify this? I'm currently passing the info. like this:
String date = worksheet.Cells[1, 1].Value2.ToString();
worksheet.Cells[1, 2].Value2 = date; //this shows up as 43195

It’s not being transformed really. Excel actually stores all dates as a number representing the number of days since 1/0/1900 (really!). What you are seeing in your cell is the raw numeric value representing the date. If you open your result spreadsheet, highlight your column, right click and select formatting, and select “Date”, you’ll see it display the date you expect.
So you are going to want to do this in your code. Assuming your date is in column “B” and your worksheet is “ws”:
ws.Range[“B:B”].NumberFormat = “mm/dd/yyyy”;
This assumes a US date format.

Related

ExcelDataReader in C# - How to reference an individual Cell using row and column cordinates

I'm reading an .xlsx spreadsheet into a C# console app with a view to outputting the content as a formatted xml file (to be picked up by another part of the system further down the line).
The problem with the the .xslx file is that it's a pro-forma input document based on, and replacing, an old paper-based order form we used to provide to customers, and the input fields aren't organised as a series of similar rows (except in the lower part of the document which consists of up to 99 rows of order detail lines). Some of the rows in the header part of the form/sheet are a mixture of label text AND data; same with the columns.
Effectively, what I need to do is to be able to cherry pick data from the initial dozen or so rows in order to poke data into the xml structure; the latter part of the document I can process by iterating over the rows for the order detail lines.
I can't use Interop as this will end up as an Azure function - so I've used ExcelDataReader to convert the spreadsheet to a dataset, then convert that dataset to a new dataset entirely composed of string values. But I haven't been able to successfully point to individual cells as I had expected to be using syntax something like
var cellValue = MyDataSet.Cell[10, 2];
I'd be grateful for any advice as to how I might get the result I need.
A Dataset has Tables and those have Rows which hold ColumnValues
A WorkSheet transforms into a Table (with Columns) and the Cells transform to Rows and column values.
To find the cell value at [10,2] on the first Worksheet do:
var cellValue = MyDataSet.Tables[0].Rows[10][2];
Remember that cellValue will be of type object. Cast accordingly.

C# EPPlus multiple cell formatting not applying

I am using EPPlus to generate excel file from data table. i have only two rows. i am applying % formatting on first row and $ formatting on second row but my two row has getting same % formatting for first two row which is wrong. i am not being able to capture the reason why this is happening. why second formatting not being applied on second row which is $ formatting.
See this line where i use range to apply formatting.
ws.Cells["C0:P0"].Style.Numberformat.Format = "#,###,##0.0%;(#,###,##0.0%)";
ws.Cells["C1:P1"].Style.Numberformat.Format = "$##,##0.0;($##,##0.0)";
in the above code i mention cell range with formatting but my two row getting only first formatting and second formatting not consider...not clear why this is happening?
Sample Code
using (OfficeOpenXml.ExcelPackage obj = new OfficeOpenXml.ExcelPackage(FileLoc))
{
// creating work sheet object
OfficeOpenXml.ExcelWorksheet ws = obj.Workbook.Worksheets.Add("Vertical");
// freezing work sheet columns and rows
ws.View.FreezePanes(2, 3);
// exporting data to excel
ws.Cells["A1"].LoadFromDataTable(selected, true);
// setting calumns as autofit
ws.Cells[ws.Dimension.Address].AutoFitColumns();
//fixing height of column
ws.Row(1).Height = 16;
ws.Row(1).Style.Fill.PatternType = ExcelFillStyle.Solid;
ws.Row(1).Style.Fill.BackgroundColor.SetColor(Color.LightGray);
obj.Save();
ws.Cells["C0:P0"].Style.Numberformat.Format = "#,###,##0.0%;(#,###,##0.0%)";
ws.Cells["C1:P1"].Style.Numberformat.Format = "$##,##0.0;($##,##0.0)";
}
screen shot of excel data. see first two line in picture and definitely understand #,###,##0.0%;(#,###,##0.0%) this format is applying on first two row but in my code i have given different format for second records.
please help me to find the wrong things in my code. thanks
Well, there are a couple of errors. First, you're saving before setting the formatting, so it's not being applied.
Second, Excel addresses are base 1, it doesn't exist "C0" and "P0". Also note that in the first row is the columns titles, so you probably want rows 2 and 3. Try the following:
ws.Cells["C2:P2"].Style.Numberformat.Format = "#,###,##0.0%;(#,###,##0.0%)";
ws.Cells["C3:P3"].Style.Numberformat.Format = "$##,##0.0;($##,##0.0)";
obj.Save();

oledb excel some date-columns return null

I am reading a xlsx-file via oledb. There are some rows where a column (containing a date-string) returns null and some rows where the column (also containing a date-string) returns the date-string. In excel the column-type is set to "date".
Here is my connection-string:
$"Provider=Microsoft.ACE.OLEDB.12.0;Data
Source={PATH_TO_FILE};Extended Properties=\"Excel 12.0
Xml;HDR=NO\""
Here is the command-text to query the data:
$"SELECT * FROM [SHEET_NAME$A4:BC] WHERE
F1 IS NOT NULL"
Here is how i read the data from the data-record:
var test = dataRecord.GetValue(dataRecord.GetOrdinal("F39"));
Her are some examples what the inspector shows me when test contains the date-string:
{07.01.1975 00:00:00}
{03.08.1987 00:00:00}
{03.10.1988 00:00:00}
{01.05.1969 00:00:00}
{20.12.2016 00:00:00}
{18.07.2011 00:00:00}
In other cases the inspector only show:
{}
Here is a screenshot from the xlsx-document where i have marked a line in red where the return-value is empty and green where the actual date-string is returned:
The date-strings are formatted like dd.mm.yyyy
Why do these rows return an empty value instead of the date-string?
As suggested by AndyG i have checked if the date-string values might fail in dependece of the format ("dd.mm.yyyy" vs. "mm.dd.yyyy"). But there are cases which are invalid for "mm.dd.yyyy" that dont fail.
I was not able to solve the problem, but was able to bypass it, by changing the column-type in Excel to text.
I had to copy the whole xls-file, delete the content of the copy, set the column-type to text, copy the content from the first file and paste it into the second file. Otherwise Excel was changing the date-strings to the numbers which are used to store the date.
Now I can read the cells correctly.
Two years too late but after struggling with this for the better part of several hours I hope this might help someone:
It sounds likely the first row in your excel document contains column names and not actual data, which means they are of a different Excel data type (General/Text + DateTime).
The fix to handle is pretty simple - adjust your connection string to reflect this using the HDR property in Extended Properties:
$"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={PATH_TO_FILE};Extended Properties=\"Excel 12.0 Xml;HDR=YES\""
HDR = true means the first row contains field names
You can read more about it here:
https://www.connectionstrings.com/ace-oledb-12-0/
Additionally, if you are encountering this on odd lines in your document like OP, ensure that the data type is identical for the entire column, except your column titles if using HDR=true
Excel can sometimes flip DateTime fields to General fields which would cause this behavior

C# writing text serial numbers as dates in Excel file

I wrote a parser that takes some information from Excel sheets using the Spire.xls library and then writes the information to another Excel file.
I'm running into a weird problem. For some reason the program is taking serial numbers such as
03-02281
03-02282
03-01975
And writing them into the Excel sheet as
3/1/2281
3/1/2282
3/1/1975
This only happens with some values.
Others such as
30-04761
03-00613
03-00614
are transcribed unchanged.
I checked in the excel file, the fields are set as text format. So they were either stored that way originally or Excel is interpreting the serial numbers to be dates. Other possibility is that it doesn't happen in the original file and the text is not automatically corrected/changed if I manually type in the correct values.
Does anyone know why this is happening and how I can tell Excel to just treat these as text and nothing else?
I though about appending a ' to them in the beginning of each value, but these have to then be read by other parsers so it's not the most convenient option.
Edit:
Here's some ofthe code I use for this, hopefulyl it can give you guys an idea of where I'm going wrong.
This is the code that adds all the values:
Workbook workbook = new Workbook();
workbook.LoadFromFile(templateExcelFileUri);
Worksheet sheet = workbook.Worksheets[0];
int ColumnIndex = 0; //for the datatable columns iteration
int columnCounter = 1; //for the excel sheet columns iteration
int ColumnsToAdd = 6; //(Seccion, seccion desc, marca, marca desc, **IdArticulo**, articulo desc)
//get the data of the new column
DataColumn DescriptionsDataColumn;
//First, add the suggestions.
for (; ColumnIndex < ColumnsToAdd; ColumnIndex++,
columnCounter++)
{
sheet.InsertColumn(columnCounter);
if(columnCounter==5)
sheet.Columns[5].NumberFormat = "#";// the column with the serial numbers.
DescriptionsDataColumn = AutomatController.DescriptionsTable.Columns[ColumnIndex];
//insert the data into the new column
sheet.InsertDataColumn(DescriptionsDataColumn, true, 2, columnCounter);
}
And for references, the table the values of which I add:
public static void SetDescriptionsTable()
{
DescriptionsTable.Columns.Add("Seccion", typeof(string));
DescriptionsTable.Columns.Add("SeccionDescripcion", typeof(string));
DescriptionsTable.Columns.Add("Marca", typeof(string));
DescriptionsTable.Columns.Add("MarcaDescripcion", typeof(string));
DescriptionsTable.Columns.Add("IdArticulo", typeof(string)); //Serial numbers
DescriptionsTable.Columns.Add("ArticuloDescripcion", typeof(string));
}
Thanks for the edits to the format of my question and the title. I'm still a little new here and I'm learning how to do that better.
The reason why some values do not map to dates is because they fall outside of the format MM-dyyyy format. for example there is no month 30 (30-02281) or day 0 (03-01975).
I think the only thing you need to do is set the format of the target column and cell prior to setting its value through the API. Sometimes cloning a column or a cell defaults the formatting to "Auto" and Excel tries to be too smart.
If you can share a bit of your code the community may be able to more accurately diagnose the problem.
You should set the columns format to general before setting the value.

How to copy format of one row to another row in Excel with c#

I am inserting data to Excel using C#. Whenever I add a new row to Excel using C# I want the same format as above row i.e, color, font and background color everything by programmatically.
It's an OLEDB insert.
Post insert, I want to apply the format of first row to the second row. With format painter from UI it's a straightforward job, I can't find a way to do the same with C#.
1) First you Need to get the Range you want to copy for e.g. RngToCopy
2) Then Set the Range where you want to insert.
3) use the below mentioned code snippet.
Range RngToCopy = ws.get_Range(StartCell, EndCell).EntireRow;
Range RngToInsert = ws.get_Range(StartCell, Type.Missing).EntireRow;
oRngToInsert.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftDown, oRngToCopy.Copy(Type.Missing));
//ws is the worksheet object, set StartCell and EndCell as per your requirement

Categories