In the past, I have created a component to pass and retrieve values to/from excel using the excel libraries. The good thing is that once you have your workbook in memory and modify a cell (let's call it the origin cell) all the other cells with formulas that take this origin cell value are automatically refreshed.
Is this possible in OpenXml?
As far as I see, apparently this doesn't happen in OpenXml because the excel engine is not really executed in the background, OpenXml is just a group of classes to serialize, deserialize, read etc xml files right?
That's correct, Office Open XML SDK is just a set of libraries to read/write XML files. It does not have any functionality for performing calculations.
You can specify that Excel should recalculate everything upon load by setting the following attribute, but if you need to read the new values in code (prior to re-opening in Excel) this won't help.
<workbook>
<calcPr fullCalcOnLoad="1"/>
</workbook>
Or in code with the Office Open XML SDK..
using (var doc = SpreadsheetDocument.Open(path, false))
{
doc.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
.
.
.
}
Related
I am creating a series of Excel Workbooks using EPPlus v3.1.3. When I open the newly created files, if I close it without touching anything it asks me if I want to save my changes. The only thing I've noticed changes if I say "yes" is that the app.xml file is slightly altered - there is no visible difference in the workbook, and the rest of the XML files are the same. I have tried both of these approaches:
ExcelPackage p = new ExcelPackage(new FileInfo(filename));
p.Save();
as well as
ExcelPackage p = new ExcelPackage();
p.SaveAs(new FileInfo(filename));
and both have the same problem. Is there a way to have the app.xml file output in its final form?
The reason this is an issue is because we use a SAS program to QC, and when the SAS program opens the files as they have been directly output from the EPPlus program it doesn't pick up the values from cells that have formulas in them. If it is opened and "yes" is chosen for "do you want to save changes", it works fine. However, as we are creating several hundred of these, that is not practical.
Also, I am using a template. The template appears normal.
What is particularly strange is that we have been using this system for well over a year, and this is the first time we have encountered this issue.
Is there any way around this? On either the C# or SAS side?
What you are seeing is not unusual actually. Epplus does not actually generate a full XLSX file - rather it creates the raw XML content (all office 2007 document formats are xml-based) and places it in the zip file which is renamed to XLSX. Since it has not been ran through the Excel engine it has not be fully formatted to excels liking.
If it is a simple data sheet then chances are Excel does not have to do much calculation - just basic formatting. So in that case it will not prompt you to save. But even then if you do you will see it change the XLSX file a little. If you really want to see what it is doing behind the scenes rename the file to .zip and look at the xml files inside before and after.
The problem you are running in to is because it is not just a simple table export Excel has to run calculations when opened for the first time. This could be many things - formulas, autofilters, auto column/row height adustments, outlining, etc. Basically, anything that will make the sheet look a little "different" after excel gets done with it.
Unfortunately, there is no easy fix for this. Running it through excel's DOM somehow would be simplest which of course defeats the purpose of using EPPlus. The other thing you could do is see the difference between the before and after of the xml files (and there are a bunch in there you would have to look at) and mimic what excel would change/add in the "after" file version by manually editing the XML content. This is not a very pretty option depending on how extensive the changes would be. You can see how I have done it in other situations here:
Create Pivot Table Filters With EPPLUS
Adding a specific autofilter on a column
Set Gridline Color Using EPPlus?
I ran into this same issue using EPPlus (version 4.1.0, fyi) and found adding the following code before closing fixed the problem:
p.Workbook.Calculate();
p.Workbook.FullCalcOnLoad = false;
I do have an XML file which contains several calculated values along with a list of items such as:
<?xml version="1.0" encoding="utf-8"?>
<XmlContent>
<Elements>
<CreationDate>...</CreationDate>
<Filename>....</Filename>
</Elements>
<PersonItems>
<PersonItem>
<FirstName>...</FirstName>
<LastName>...</LastName>
<Speed>...</Speed>
</PersonItem>
<PersonItem>
<FirstName>...</FirstName>
<LastName>...</LastName>
<Speed>...</Speed>
</PersonItem>
[...]
</PersonItems>
</XmlContent>
Now the values should be presented in an Excel sheet using Excel 2007 OpenXmlFormat. The calculated values should be mapped to a specific cell within the worksheet along PersonItems should be bound to a table within the same worksheet.
Is there a way to embed the XML file into the worksheet package and bind the values to the appropriate fields by using the c# Package API as a CustomXmlPart?
I found an example on Channel9 where Matthew Scott made something similar with Word 2007 by using the Word Content Control Toolkit. However, this only works with Word.
Is there something similar for Excel?
Or is there even a better approach for solving this task?
Well, after research and playing around with XML mapping I came to the conclusion that there is not "easy" way to achieve that what I am longing to do.
When importing XML Content within the Excel application, Excel creates an XML mapping definition and stores it within the Package. The XML content itself will be splitted by using the mapping definition and merged within the contents of the Excel file.
This means, that the XML file itself vanishes right after import and can no longer be used.
However, the intentional scenario is possbible with Word 2007+ as you can see in the links above.
Maybe this information is helpful for anybody who has a similar task like me.
The easiest way is to Parse the xml file(SAX,DOM), get the corresponding attributes and values, then write those to an excel file.
In a C# console application I have a PointF[] array. I need to draw those points in an .xls chart file, but I need guidance how to do this?
Have a look at Open XML SDK 2.0 for Microsoft Office
I've used it before to do something like you're describing.
I started off creating an .xls file in Excel that had the correct chart which read values from a specific range of cells and so on. Then using the SDK I added/changed the values of those cells and saved a new version of the file. So basically I used the file created in Excel as a template that I could change whenever without changing the code (as long as the values are written to the same range of cells).
You could also put the value cells in a separate worksheet so that the user does not see them when opening the file...
I'd like to use Excel's XML Map feature from server-side C# in a web app. XML maps enable you to associate an XML schema with a workbook and specify which cells map to which parts of the schema. From there you can import XML files to update cell values, and export XML containing the latest values (i.e. if they have been manually changed). You can do this manually on the Developer tab in Excel.
We already have a licence for Aspose Cells, but (despite some recent work in this area) it doesn't seem to fully support XML maps. Has anyone had any success with this?
I've created a test using Excel Interop, which works (i.e. can set up an XML Map programatically and use it to both import and export values). It boils down to this:
XmlMap map = workbook.XmlMaps.Add(xmlSchema, Missing.Value);
// map cell C3 to the question text
var worksheet = (Worksheet)workbook.Worksheets[1];
Range cell = (Range)worksheet.Cells[3, 3];
cell.XPath.Clear(); // just in case
cell.XPath.SetValue(map, "/Root/Question/Text", Missing.Value, false);
// import the XML to populate the mapped cells
map.ImportXml(xmlData, true);
However, that's not really suitable for use on a server because it relies on running the Excel process in the background.
Is it possible to use Microsoft's Open XML SDK to import or export XML via an XML Map? I've found the Map class, but I think that just represents the metadata for a map that already exists. Does the SDK contain this sort of transformation logic or does it just represent a worksheet's content as classes?
To further providing you details about XMLMaps feature, currently, Aspose.Cells only supports the following options regarding XML Maps:
It can preserve XmlMaps in the template file and re-save the file with it.
It supports to Import XML Mapping from external sources.
It can remove or check the XML mappings.
Currently it does not support the following at the moment:
It cannot add XML Maps to the Excel file.
It does not export XML Maps to save an external file (We will try to support exporting xml Maps in the second quarter of 2013)
My name is Nayyer and I am developer evangelist at Aspose.
I have an XSL file that I am generating from CSV from and Object etc. etc.
Everything is done except that I need to highlight particular rows in the xsl file. I don't want to have to open Excel and use Macros.
Is there a way to do this in C#?
Do you mean XLS and not XSL?
If so, here's a link that explains the basics of how to use Excel as an object. Since you're opening it as an object, it won't be visible (unless you want it to be), but you'll have full access to navigate, highlight rows, and do whatever else you would normally do in Excel. When done, dispose the object.
Connecting to and navigating Excel through C#