Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenXml: Worksheet Child Elements change in ordering results in a corrupt file

I am trying to use openxml to produce automated excel files. One problem I am facing is to accomodate my object model with open xml object model for excel. I have to come to a point where I realise that the order in which I append the child elements for a worksheet matters.

For Example:

workSheet.Append(sheetViews);
workSheet.Append(columns);
workSheet.Append(sheetData);
workSheet.Append(mergeCells);
workSheet.Append(drawing);

the above ordering doesnot give any error.

But the following:

workSheet.Append(sheetViews);
workSheet.Append(columns);
workSheet.Append(sheetData);
workSheet.Append(drawing);
workSheet.Append(mergeCells);

gives an error

So this doesn't let me to create a drawing object whenever I want to and append it to the worksheet. Which forces me to create these elements before using them.

Can anyone tell me if I have understood the problem correctly ? Because I believe we should be able to open any excel file create a new child element for a worksheet if necessary and append it. But now this might break the order in which these elements are supposed to be appended.

Thanks.

like image 564
mariner Avatar asked Aug 02 '12 22:08

mariner


2 Answers

According to the Standard ECMA-376 Office Open XML File Formats, CT_Worksheet has a required sequence:

CT_Worksheet Schema Diagram

The reason the following is crashing:

workSheet.Append(sheetViews);
workSheet.Append(columns);
workSheet.Append(sheetData);
workSheet.Append(drawing);
workSheet.Append(mergeCells);

Is because you have drawing before mergeCells. As long as you append your mergeCells after drawing, your code should work fine.

Note: You can find the full XSD in ECMA-376 3rd edition Part 1 (.zip) -> OfficeOpenXML-XMLSchema-Strict -> sml.xsd.

like image 185
Joe Masilotti Avatar answered Nov 10 '22 00:11

Joe Masilotti


I found that for all "Singleton" children where the parent objects has a Property defined (such as Worksheet.sheetViews) use the singleton property and assign the new object to that instead of using "Append" This causes the class itself to ensure the order is correct.

workSheet.Append(sheetViews);
workSheet.Append(columns);
workSheet.Append(sheetData);  // bad idea(though it does work if the order is good)
workSheet.Append(drawing);
workSheet.Append(mergeCells);

More correct format...

workSheet.sheetViews=sheetViews; // order doesn't matter.
workSheet.columns=columns;
...
like image 1
DarrenMB Avatar answered Nov 09 '22 22:11

DarrenMB