Formatting cell values from OpenXML - c#

I'm opening up xlsx files as a package and reading the contents of the xml files. I'm able to get the shared strings, borders, etc that I need and it's orders of magnitude faster than when I was using Interop. The only issue I have is when it comes to pulling out numbers and formatting them properly based on what the formatting is in the Excel file.
Is there a generic function somewhere that takes a value and a format and returns the formatted string? For example, if I have the value 31502008 and the custom format "$* #,##0_);$* (#,##0)" is there a simple way to get what Excel shows (which is $31,502,008). Obviously Excel knows how to handle it, but I have some sheets that have a crazy number of custom formats and I'm wondering how best to ensure that the string I get back in code matches what is seen in Excel.
Any ideas?
Thanks a lot for any help.

Related

ClosedXML Changing Number Formats

I am doing the following in ClosedXML (standard accounting format for numbers):
ws.Column(col).Style.NumberFormat.Format = "_($* #,##0.00_);_($* (#,##0.00);_($* \" - \"??_);_(#_)";
When the output renders, it doesn't look like what I specified. If I inspect the format, it has been changed to this:
[$$-en-US]#,##0.00_);([$$-en-US]#,##0.00)
Close, and passable, but not what I input.
Anyone know what gives? Is this ClosedXml or is it Excel? I can do it manually in Excel, and it works perfectly.
Looks like Excel is doing some magic on opening a file, propably for localization compatibility. Also on editing the cell format some sort of 'assistance' happens.
Following code should work for you or at least point you in the right direction:
ws.Column(col).Style.NumberFormat.Format = "_([$$-en-US]_(#,##0.00_);_([$$-en-US]_((#,##0.00)_);_(-_);_(#_)";
Please note that on editing the format afterwards in Excel it will likely 'assist' you again and propably mess up. You will find the original format string under 'Userdefined', tho.
Help on format strings is also provided by Microsoft.

Embed file in excel worksheet/cell

I hope someone can help me. Is there a way to embed a specific file (.txt) into an excel cell? I'm currently using epplus, and I would like to embed programmatically a file into a specific excel cell. I did manage to add a hyperlink, but my goal is to have it embedded.
Worksheet.Cells[rowNumber, colNumber].Value = ....
Is there any way to do it? I couldn't find anything online.
As mentioned in the comments, you can certainly put text within a cell, but bear in mind Excel does have a limit to the number of characters it will allow in a single cell. It's pretty large, but conceivably the contents of a text file could exceed that limit -- even if future versions of Excel keep increasing what the limit is (as they have in the past).
You can also embed an OLE object in your worksheet, and a text file qualifies for that. I don't know that you can assign it to a cell, per se. You can change the location, shape and behavior to fit in a cell and behave as though it's part of a cell, but I don't know that it ever belongs to a range the way formulas do. I could be wrong.
The basic construct of how to embed an OLE object into a worksheet is as follows:
Excel.OLEObject ole = ws.OLEObjects().Add(Filename: #"C:\Users\hambone\Documents\foo.txt");
This is the equivalent of the VBA:
Set ole = sh.OLEObjects.Add(Filename:="C:\Users\hambone\Documents\foo.txt")
The method returns an OLEObject object, which you can then shape to behave the way you want:
ole.Height = 5;

Is it possible to read Dynamic Named Ranges in Excel using OpenXML?

Using OpenXML, you can get a list of the named ranges in an Excel document using something similar to:
IEnumerable<DefinedName> names = document
.WorkbookPart
.Workbook
.DefinedNames
.Cast<DefinedName>();
Each of these DefinedName's has a Text property, which defines the range that it refers to, e.g.
Sheet1!$B$3:$D$8
which we can then parse, and use to retrieve the data. At least that's how I understand the process so far.
However, with a dynamic range, the text property can contain something like:
OFFSET(Sheet1!$F$3,0,0,COUNTA(Sheet1!$F:$F),1)
This is not a range, it is a formula which returns a range, and it is the result of this formula that I need.
Is it possible to calculate this formula, or is the result already stored somewhere in the spreadsheet that I can read? Or is there some other way in which I can read a dynamic named range?
This question is specifically about OpenXML. I know that it can be done using other tools.
Excel Defined Names are really named formulas rather than named ranges. So you would need a method such as VBA Evaluate to coerce the formula to a range or a result.
AFAIK OpenXML does not have such a method, so you would have to write your own formula parser and evaluator, or use some other tool.

how to get correct format from xlsx - to interpret floating point number formated as text

i am aware of the floating point inaccurrancy, this is just how to get the correct text FORMAT!! by openxml from the xlsx and show the value like excel does. I am not able to edit the excel file and change the format or something like that, because of some reasons.
while working with numbers formated as numbers everything runs fine
formatted as text or general, the number 0.813 is saved as 0.812999.., excel shows it correct!, but via openxml i can't get the used format (0.000), anyone an idea to get the format?
maybe this is a standard format, not saved and choosen by other values?
finally I am using the ugly solution to get rid of this ..
if the cellFormat NumberFormatId is 2 I try to parse the value to double and then to string with two decimals
double.Parse(displayedValue).ToString("0.00");
not my desired solution, but for the moment this works .. of course also with all other unit tests

Excel interop. Save xls as csv without losing the precision

I want to save a worksheet as CSV file using Excel interop. Doing so by using:
sheet.SaveAs(tempfile, Microsoft.Office.Interop.Excel.XlFileFormat.xlCSVWindows);
causes losing of precision. Iterating over each cell and constructing CSV is not an option as its very slow. Getting an array of values from Range is not good as well, as I cannot obtain NumberFormat of cells this way.
I noticed that precision is lost because during the export to CSV saved value is the one displayed, not the one actually being in the cell.
Any advice?

Categories

Resources