Issue with NumberFormat in ExportAsFixedFormat - c#

I have a table of data (calculation results) that the user should be able to export to different formats. I use Interop.Excel to prepare a table with the data and use the data and format it using visual formatting (fonts, colors etc.) and NumberFormat. Example:
cellRange.NumberFormat = "#,##0";
When I save the table as an Excel file all formatting is ok when exporting to .xlsx and .xls:
excelWorkBook.SaveAs(exportFileName, Excel.XlFileFormat.xlOpenXMLWorkbook); // for .xlsx
excelWorkBook.SaveAs(exportFileName, Excel.XlFileFormat.xlExcel8); // for .xls
I also want to give the user the possibility to export this table to .pdf and .xps from the application without having to open the Excel file. As I have prepared the tables in Interop.Excel, I tried exporting the same table to those file formats:
excelWorkBook.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypePDF,exportFileName); // for .pdf
excelWorkBook.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypeXPS,exportFileName); // for .xps
Both of these result in good documents except that all NumberFormats are lost resulting in long decimal values of doubles. This is not appropriate for the customer's summary of the data. (Colors and fonts remain as defined in .pdf and .xps.)
I have tried setting .Styleand .Styles to "Number" or the like. This does not solve the problem.
I have also tried to protect the Range of cells or the excelWorkSheet. This does not solve the problem either.
Someone suggested calling a VBA macro / sub through C# but after some looking into that, I get the impression that it's not a very straight forward (or stable) path.
I am looking for any help in resolving this issue through Interop.Excel or in another way.
lucn

After some testing it seems clear that the property I named in my comment must be set to false:
Microsoft.Office.Interop.Excel.Application.ActiveWindow.DisplayFormulas = false;
It is not evident why this influences the export to other formats such as *.pdfbut this is clearly the case and setting the .DisplayFormulas = false solves the issue.
Hope this helps somebody.

Related

I Help and Advice on using Oledb for large excel Files

So I am new to Oledb and I a have project that requires me to grab data from an excel file using a Console Application. The excel file has around 500 columns and 55 rows. How could I possibly get data from columns past 255?
In order to read columns 256 -> you just need to modify the Select statement. By default both the Microsoft.ACE.OLEDB.12.0 and the Microsoft.Jet.OLEDB.4.0 drivers will read from Column 1-255 (A->IU) but you can ask it to read the remaining columns by specifying them on the Select statement.
To read the next 255 columns and taking "Sheet1" as your sheet name you would specify...
Select * From [Sheet1$IV:SP]
This will work even if there aren't another 255 columns. It will simply return the next chunk of columns if there are 1...255 additional columns.
Incidentally, the Microsoft.ACE.OLEDB.12.0 driver will read both .xls and any variant of .xlsx, .xlsm etc without changing the extended properties from "Excel 12.0". There is no need to if...then...else the connection string depending on the file type.
The OLEDB driver is pretty good for the most part but it really does rely on well formed sheets. Mixed data types aren't handled terribly well and it does weird things if the first columns/rows are empty but aside from that it's fine. I use it a lot.

reading excel with oledb not displaying correct values

This is old question I posted:
Reading one & Update some other Excel with c#
As suggested I created schema.ini file. My excel files have so many columns (many of them are not fixed) with mixed data. Even a cell contains numbers along with text. I observed that NOT ALL values are shown when I read excel using OLEDB and populate into a DataTable.
I can't assume ALL columns are put them into .ini file. Columns in my excel will go up to "DX". I observed that only 1st row which has number+text value are shown but similar text appears somewhere down aren't shown. It's shows as blank.
Here is connection string:
string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + FilePath+ "';Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text\"";
Is there any solution so it reads all types of data?
This comes up a lot and it's very understandable because the documentation is somewhat lacking
Microsoft.ACE.OLEDB.12.0 does not handle columns of mixed data types very well. So what happens is that the driver will always read the first n values in each column and assign a datatype depending on what it finds in the first n cells of the column. n is determined by the setting of a registry key. It moves around depending on whether you have a 64 bit implementation or a 32 bit one but the 64 bit key is in...
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\12.0\Access Connectivity Engine\Engines\Excel\TypeGuessRows
Sadly it's not always convenient to go around modifying registry keys and it would have been much better to leave this setting on the connection string but it is what it is. The default value for this is 8 rows.
If the driver finds mixed data types then and only then does the setting of IMEX come into play. If IMEX=1 is included then a column of mixed data types is returned as text. If it is not specified then any values which do not correspond to the assigned data type are returned as null.
This is where HDR=No is useful. If you have a header then specify HDR=No and read it. This will help ensure that the column is returned as text as long as your headers are all text as well of course. You can then discard the header before processing the data. It won't help if you have a majority numeric/date time data types in the first n cells of the column.
As an aside the driver will read all types of Excel files including .xls, .xlsm and .xlsx - there is no need to change the extended properties away from Excel 12.0 to do so. This is a considerable advantage.
The older Microsoft.Jet.OLEDB.4.0 was good in that you could specify TypeGuessRows and ImportMixedTypes in the connection string but Microsoft.ACE.OLEDB.12.0 completely ignores them so you can remove them from your connection string as their presence is misleading. The older driver can only read .xls files.
Both drivers will only read 255 columns without amending the SELECT statement. To read more than 255 columns you specify a range. E.g.
Select * From [Sheet1$IV:SP]
will read columns 256-510. If your sheet ends on DX it is well within the 255 column limit.
Hidden columns are always returned.
There are a couple of nasties with this driver. Firstly leading empty rows or columns are ignored completely. This can really mess things up if you are expecting data in a specific rows/columns. Secondly Excel incorrectly treats 29/Feb/1900 as a valid date but OLEDB does not. You can stick 29/Feb/1900 into an Excel spreadsheet just fine but OLEDB will return it as 28/Feb/1900. I can't see anything else it could do really.
The driver is a very handy and cheap way of reading well formatted Excel spreadsheets as long as you are aware of the limitations and can code around them.
Good luck.

EPPlus excel sheet with script text in a cell

I'm coming across an issue that I'm not sure there's a good answer for.
We have a bulk-insert spreadsheet template to allow people to define certain components of an online ad. They then upload the document, we process it, and set it up in the database.
Recently there was a feature request to change bulk-insert into bulk-edit; IOW, people will download an excel sheet with information about the current ad prepopulated in the fields on the sheet. They would make changes as a set, then re-upload and we'd process the changes and update the database.
The problem is, one of the pieces of information is an HTML snippet with a <script> tag, and it seems like Excel pretty much deletes that automatically, so that column is never being populated when pulling down the sheet. It makes sense, in a way; it resembles executable code and could be a serious virus threat under some conditions, but even if I specify the column as pure text (using the Style.NumberFormat = "#" in EPPlus), Excel just makes the entire piece of data go away. It also skews the columns, looks like... shifts the subsequent cells to the left by one cell.
Is there any way to (safely) make this work without requiring changes to the downloader's security settings?
I dont have time to check into this, but What if you saved the workbook as a macro workbook, to enable some of the less secure behavior within the workbook?
One other thing may be to escape the content with a single quote ' in the beginning of the cell, or wrap the entire "script" content with quotes.
What version of excel do you expect to encounter in the wild? I tested this with Excel 2013, and was able to save the following to a workbook, and parse it into a Datatable using EPP Plus 4.1.0.0:
<script type="text/javascript">$(document).ready(function() {var I =0; console.info(I+100);});</script>
'<script type="text/javascript">$(document).ready(function() {var I =0; console.info(I+100);});</script>
"<script type='text/javascript'>$(document).ready(function() {var I =0; console.info(I+100);});</script>"
Nothing fancy, just iterating each cell in the workbook, pulling in the value and converted to string:
object obj = Worksheets[WorkSheetIndex].Cells[k, l].Value;

Is Open XML SDK 2.5 able to recalculate Excel formulas?

I am struggling with the Open XML SDK and I've already read a lot of posts on this topic but cannot figure it out. My goal is to have a locally created Excel file which contains a formula and edit the input online and retrieve the calculated value online.
I don't know if this is possible since Open XML may only change the data and I wonder if it is also able to perform Excels calculations.
For example, my local file contains three cells:
A1: 1
A2: 2
A3: =(A1+A2)
Using Open XML I adjust A2 to the value of 3, however the result of A3 remains 3 instead of 4.
I have already read about Excel having to recalculate, but my goal is to have an Excel file as some sort of calculation engine instead of transfering all calculations to C#.
All tips and advice are welcome.
Kind regards, Patrick
First of all thanks for all responses.
Second I guess the response answered my question and the open XML SDK is only able to adjust the file and won't do anything regarding recaculating existing formulas in the file. This will only occur when opened in Excel. I will take a look at EPPlus.
You can use something like this.
Cell cell; //supposing this is your cell referencing A3
CellFormula cellformula = new CellFormula();
cellformula.Text = "SUM(A1, A2)";
CellValue cellValue = new CellValue();
cellValue.Text = "0";
cell.Append(cellformula);
cell.Append(cellValue);
A similar example can be found at this link: Formula cells in excel using openXML
I feel there could be some ambiguity captured in the question. OpenXML is way of storing documents, therefore it is not possible to do calculations with OpenXML SDK. It is spread sheet engine (Excel application) which performs the calculations.
When inputs are updated, spreadsheet saved, calculated values should get updated.

Output table from excel using xslt

I would like to output a table to a webpage. The table is stored in an excel sheet (xls).
Is it possible to use xslt for this? The table is the cells are in this range:
A26 - P36 (16 columns and 11 rows)
If an exmaple file is need here is a link:
http://finans.opengate.dk/media/6704/2010-01-13.xls
Update: A daily file is uploaded. And I would like to automatically show a table from the latest xls-file using xslt. If some C# is needed to convert it from excel to something else (XML?) that is fine. It is done in the CMS Umbraco and that is why I hope to use XSLT since that is the way to show things in Umbraco, through xslt makroes.
BR. Anders
UPDATE with answer (based on answers below): No, it is not possible to read xls-files using xslt. If needed then one has to save excel sheet in another format xml or html. Or one will need a real programming language to read the excel file.
XSLT is mostly used to convert XML from one dialect to another, not to convert xls files to html.
If you just want to do this manually, you can save your worksheet as HTML directly in excel.
It is not clear from your question if you want to do this programmatically, and if so using what programming language.
You can use ADO.net to access cells in an excel file, similar to a DB query. This is a bit lighter than trying to use Excel automation objects.
http://support.microsoft.com/kb/316934
SpreadsheetGear for .NET can read Excel files and display them in a DataGrid as shown in the Excel to DataGrid sample on this page:
// Create a workbook from an Excel file
String ssFile = Server.MapPath("files/spiceorder.xls");
SpreadsheetGear.IWorkbook workbook = SpreadsheetGear.Factory.GetWorkbook(ssFile);
// Get a DataSet from an existing defined name
DataSet dataSet = workbook.GetDataSet("orderrange", SpreadsheetGear.Data.GetDataFlags.FormattedText);
// Bind a DataGrid to the DataSet
DataGrid1.DataSource = dataSet;
DataGrid1.DataBind();
SpreadsheetGear can also render png/gif/jpg images from cell ranges or charts as demonstrated here.
You can download the free trial here if you want to try it yourself.
Disclaimer: I own SpreadsheetGear LLC

Categories

Resources