I want to read an unformatted contents of the numeric cells (e.g. 0.05 instead of 5% and 123456 instead of 123,456.000).
I thought the easiest way to do it would be to change the format of the cell:
ICell cell = ...;
string s = cell.SetCellType(<ICell.CELL_TYPE_STRING-doesn't compile>).ToString();
but I do not know how to set string/numeric format.
All examples I have googled are either from POI or HSSF universes, they won't do for me (I am reading Excel 2007 spreadsheet using NPOI)
This worked for me:
string formatProofCellReading(ICell cell)
{
if (cell == null)
{
return "";
}
if (cell.CellType == CellType.NUMERIC)
{
double d = cell.NumericCellValue;
return (d.ToString());
}
return cell.ToString();
}
Related
C#, NPOI
Good evening, i'm trying to fill in an empty template with values(numbers, but in string variable), that needs to be in cells.
So, when it came to formatting, i've stuck with styling. That means, when i wrote the value inside(in pre-formatted cell) i get just the string value, that was in array.
But, when i open file, click "edit cell", then apply without any changes, then cell is formatted, with the format, which was in a template
I tried to apply previous style in cell(basically just copy style in var, before setting a value, then re-apply style), but, it didnt help.
Here is the video of my doings
var cr = new CellReference(cellAndValue[i, 0]);
var row = sheet?.GetRow(cr.Row);
var cell = row?.GetCell(cr.Col);
var prevtype = cell.CellType;
var prevstyle = cell.CellStyle;
var dataformat = cell.CellStyle.DataFormat;
CellType type = cell.CellType;
cell.SetCellValue(cellAndValue[i, 0]);
How to resolve that?)
It was required to convert incoming data to int, before inserting it XD
int n;
if (Int32.TryParse(cellAndValue[i, 1], out n))
{
cell.SetCellValue(n);
}
else
{
cell.SetCellValue(cellAndValue[i, 1]);
}
I am trying to create Excel file by reading data from the database. One of the columns contains Japanese text. While writing that column to excel cell and saving workbook gives following error (which makes sense as the characters are not valid xml chars ) :'', hexadecimal value 0x0B, is an invalid character.
I am writing the string as following to the excel cell using DocumentFormat.OpenXml package.
var excelCell = new Cell();
var cellValue = dtRow[col.Name].ToString();
var inlineStr = new InlineString(new Text(cellValue));
excelCell.DataType = CellValues.InlineString;
excelCell.InlineString = inlineStr;
What needs to be done to write Japanese characters to the excel using OpenXml in C#
Ok. Found the right way. Putting it as answer so that it can be helpful.
To add text to excel which is not allowed as valid xml, add the text as SharedString to the SharedStringTable
var index = InsertSharedStringItem(text, shareStringPart);
excelCell.CellValue = new CellValue(index.ToString());
excelCell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
private static int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart)
{
// If the part does not contain a SharedStringTable, create one.
if (shareStringPart.SharedStringTable == null)
{
shareStringPart.SharedStringTable = new SharedStringTable();
}
int i = 0;
// Iterate through all the items in the SharedStringTable. If the text already exists, return its index.
foreach (SharedStringItem item in shareStringPart.SharedStringTable.Elements<SharedStringItem>())
{
if (item.InnerText == text)
{
return i;
}
i++;
}
// The text does not exist in the part. Create the SharedStringItem and return its index.
shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text)));
shareStringPart.SharedStringTable.Save();
return i;
}
Full documentation for adding text as shared string to excel using OpenXml
https://msdn.microsoft.com/en-us/library/office/cc861607.aspx
I have a scenario in an MVC application where I cam using OPEN XML for real excel file and then display list in a table view, The decimal values with precision point do not get read and formatted correctly, I have tried multiple conversions but seem to not work. I am attempting to format it to a 2 decimal places, I attempted using Math.Round but it doesn't seem to work. Please see my code below: This is on the Total Claim column value in my excel sheet.
private static CleanSupplierClaim MappExcelOpenXMLtoGenericList(IList<string> rowData, IList<string> columnNames)
{
var cleanSupplierClaims = new CleanSupplierClaim()
{
Action = rowData[columnNames.IndexFor("Action")],
Line_Number = rowData[columnNames.IndexFor("Lineno")],
Total_Claim = rowData[columnNames.IndexFor("TotalClaim")].ToDecimalNullable(), //Convert.ToDecimal(Math.Round(Convert.ToDouble(rowData[columnNames.IndexFor("TotalClaim")].ToDoubleNullable()),2)),
Currency = rowData[columnNames.IndexFor("Currency")],
ClaimReference = rowData[columnNames.IndexFor("ClaimReference")]
};
return cleanSupplierClaims;
}
Here is my generic class to read cell values:
private static string GetCellValue(SpreadsheetDocument document, Cell cell)
{
if (cell == null) return null;
string value = cell.InnerText;
//Process values particularly for those data types.
if (cell.DataType != null)
{
switch (cell.DataType.Value)
{
//Obtain values from shared string table.
case CellValues.SharedString:
var sstPart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
value = sstPart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText.Trim();
break;
//Optional boolean conversion.
case CellValues.Boolean:
var booleanToBit = ConfigurationManager.AppSettings["BooleanToBit"];
if (booleanToBit != "Y")
{
value = value == "0" ? "FALSE" : "TRUE";
}
break;
case CellValues.Number:
return Convert.ToDecimal(cell.CellValue.Text).ToString();
default:
if (cell.CellValue != null)
return cell.CellValue.Text;
return string.Empty;
}
}
return value;
}
All the formatting I have attempted either skips the value with decimals or it returns the value as 0, it works fine for whole numbers, please assist.
This is in MVC Application using VS 2013 and OPEN XML
This seems silly, but I haven't been able to get my values in the format of #/#### to write as the literal string rather than becoming formatted as a date within excel.
I'm using ClosedXML to write to excel, and using the following:
// snip
IXLRangeRow tableRow = tableRowRange.Row(1);
tableRow.Cell(1).DataType = XLCellValues.Text;
tableRow.Cell(1).Value = "2/1997";
// snip
Looking at the output excel sheet I get in the cell 2/1/1997 - even though I'm setting the format as text in code, I'm getting it as a "Date" in the excel sheet - I checked this by right clicking the cell, format cell, seeing "date" as the format.
If I change things up to:
// snip
IXLRangeRow tableRow = tableRowRange.Row(1);
tableRow.Cell(1).Value = "2/1997";
tableRow.Cell(1).DataType = XLCellValues.Text;
// snip
I instead get 35462 as my output.
I just want my literal value of 2/1997 to be displayed on the worksheet. Please advise on how to correct.
try this
ws.Cell(rowCounter, colCounter).SetValue<string>(Convert.ToString(fieldValue));
Not sure about from ClosedXML, but maybe try Range.NumberFormat (MSDN Link)
For example...
Range("A1").NumberFormat = "#"
Or
Selection.NumberFormat = "#/####"
Consider:
tableRow.Cell(1).Value = "'2/1997";
Note the single quote.
ws.Cell(rowCounter, colCounter).Value="'"+Convert.ToString(fieldValue));
Formatting has to be done before you write values to the cells.
I had following mechanism, run after I make worksheet, right before I save it:
private void SetColumnFormatToText(IXLWorksheet worksheet)
{
var wholeSheet = worksheet.Range(FirstDataRowIndexInExcel, StartCellIndex, RowCount, HeaderCount);
wholeSheet.Style.NumberFormat.Format = "#";
}
which didn't do squat.
Doing it before I write values to the cells in a row did it.
worksheet.Range(RowIndex, StartCellIndex, RowIndex, EndCellIndex).Style.NumberFormat.Format = "#";
with cell value assignments following immediately after.
So i'm using EPPlus to read and write excel documents.
Workflow
User generates populated excel document
Opens document and adds a row
Uploaded and read
The dates that are generated when I create the document using EPPlus show correctly when I'm reading the value back but the row the user changes the date one or adds is showing as an INT value not something I can use as a real date.
When I enter the date 1/01/2014 and write it, the output when I open the file up shows 41640
I'm reading it as follows
sheet.Cells[i, "AE".ConvertExcelColumnIndex()].Value != null
? sheet.Cells[i, "AE".ConvertExcelColumnIndex()].Value.ToString().Trim()
: string.Empty
Update
When exporting the file I have added the following
DateTime testDate;
if (DateTime.TryParse(split[i], out testDate))
{
sheet.Cells[row, i + 1].Style.Numberformat.Format = "MM/dd/yyyy";
sheet.Cells[row, i + 1].Value = testDate.ToString("MM/dd/yyyy");
}
Also when reading the value back I have tried
sheet.Cells[i, "AE".ConvertExcelColumnIndex()].Style.Numberformat.Format = "MM/dd/yyy";
I still get an INT back
...when I need to read that excel file, the only dates that are
incorrect are the ones the user has changed
So when you read the modified excel-sheet, the modified dates are numbers whereas the unchanged values are strings in your date-format?
You could get the DateTime via DateTime.FromOADate:
long dateNum = long.Parse(worksheet.Cells[row, column].Value.ToString());
DateTime result = DateTime.FromOADate(dateNum);
With your sample-number:
Console.Write(DateTime.FromOADate(41640)); // -> 01/01/2014
I stumbled upon this issue today when trying to generate some Excel documents from some ASP.NET DataTables: I had no problem with strings, but ran into few issues with numeric types (int, doubles, decimals) and DataTables, which were formatted as string or as numeric representations (OADate).
Here's the solution I eventually managed to pull off:
if (dc.DataType == typeof(DateTime))
{
if (!r.IsNull(dc))
{
ws.SetValue(row, col, (DateTime)r[dc]);
// Change the following line if you need a different DateTime format
var dtFormat = "dd/MM/yyyy";
ws.Cells[row, col].Style.Numberformat.Format = dtFormat;
}
else ws.SetValue(row, col, null);
}
Apparently, the trick was to set the value as DateTime and then configure the proper Style.Numberformat.Formataccordingly.
I published the full code sample (DataTable to Excel file with EPPlus) in this post on my blog.
You should try using
string dateFromExcel = workSheet.Cells[row, col].Text.ToString();
DateTime localdt;
if (DateTime.TryParse(dateFromExcel, out localdt))
{
dateFromExcel = localdt.ToString("MM/dd/yyyy");
};
the Value reads the value in the general formatting while Text reads the value as it is from the excel with applied formatting.
you could check if the cell format is in date format,
then parse it to date
var cell = worksheet.Cells[row, col];
value = cell.Value.ToString();
if (cell.Style.Numberformat.Format == "[$-409]d\\-mmm\\-yy;#")
{
string inputString = DateTime.FromOADate(long.Parse(value.ToString())).ToString("dd-MMM-yyyy");
}
You can also change the 'NumberFormatLocal' property. This worked for me. If you format the Excel file before improting it using EPPLUS.
The following basic example of code formats column A in a typical excel file.
Sub ChangeExcelColumnFormat()
Dim ExcelApp As Excel.Application
Dim ExcelWB As Excel.Workbook
Dim ExcelWS As Excel.Worksheet
Dim formatRange As Excel.Range
Dim strFile As String = "C:\Test.xlsx"
Dim strSheetname As String = "Sheet1"
ExcelApp = New Excel.Application
ExcelWB = ExcelApp.Workbooks.Open(strFile)
strColSelect = "A:A"
strFormat = "dd/mm/yyyy"
formatRange = ExcelWS.Range(strColSelect)
formatRange.NumberFormatLocal = strFormat
ExcelWB.Save()
ExcelWB.Close()
ExcelApp.Quit()
ExcelWS = Nothing
ExcelWB = Nothing
ExcelApp = Nothing
End Sub