保存OpenXML文档时操作共享string表
我正在尝试使用Entity Framework数据创buildExcel 2010工作簿(EF不是问题)。 我或多或less地跟随代码: CodeProject链接
在上面的链接中创build文本单元格的代码将所有文本创build为内联string。 为了遵循最佳实践(至less据我了解OpenXML)我想改变这个使用共享string表,所以我在这里find的代码来帮助。
为此,我从工作簿中获取共享string表,添加我的字符串,然后保存表。 我的代码:
private static int InsertSharedStringItem(WorkbookPart wbPart, string value) { int index = 0; bool found = false; var stringTablePart = wbPart.GetPartsOfType<SharedStringTablePart>() .FirstOrDefault(); if (stringTablePart == null) { // Create it. stringTablePart = wbPart.AddNewPart<SharedStringTablePart>(); } var stringTable = stringTablePart.SharedStringTable; if (stringTable == null) { stringTable = new SharedStringTable(); } foreach (SharedStringItem item in stringTable.Elements<SharedStringItem>()) { if (item.InnerText == value) { found = true; break; } index += 1; }
if (!found) { stringTable.AppendChild(new SharedStringItem(new Text(value))); stringTable.Save(); }
return index; }
我已经突出(显然分离)的问题领域)
不幸的是我得到一个InvalidOperationException: Cannot save DOM tree since this element is not associated with an OpenXmlPart
到stringTable.Save()上的OpenXmlPart。 线
我试图通过将if(!found)块更改为:
if (!found) { stringTable.AppendChild(new SharedStringItem(new Text(value))); wbPart.SharedStringTablePart.SharedStringTable = stringTable; stringtable.Save(); }
当代码碰到新行时,它将返回一个UnhandledArgument Exception: Cannot set the given root element to this part. The given part root element has already been associated with another OpenXmlPart.
UnhandledArgument Exception: Cannot set the given root element to this part. The given part root element has already been associated with another OpenXmlPart.
在这一点上,我很困惑我的stringtable
是否与OpenXmlPart相关联。
有人可以看到我做错了什么,或者指出一个更好的方法来做到这一点?
添加SharedStringTablePart时,立即初始化与该部件关联的SharedStringTable。 然后你不检查SharedStringTable对象的无效性。 尝试这个:
if (stringTablePart == null) { // Create it. stringTablePart = wbPart.AddNewPart<SharedStringTablePart>(); stringTablePart.SharedStringTable = new SharedStringTable(); } var stringTable = stringTablePart.SharedStringTable; //if (stringTable == null) //{ // stringTable = new SharedStringTable(); //}
我希望这个片段足以让你识别你的函数中的部分。 如果SharedStringTablePart不为null,则已经有一个SharedStringTable对象。 如果它是空的,那么…好吧,同时创build两个。
可能对原始海报没有用处,但是如果其他人绊倒了这一点。 微软的例子有一个模板excel文件,他们用来修改。 这个答案是从头创build一个Excel文档。 希望这有助于某人。
在创build和首次保存文档时,请尝试添加SharedStringTablePart
和SharedStringTable
。 我正在创build一个文件,并将其放置在临时文件夹中,然后重新打开文件进行修改。
public string CreateSpreadsheet() { string filepath = Path.GetTempFileName(); filepath = filepath.Replace(".tmp", ".xlsx"); // Create a spreadsheet document by supplying the filepath. // By default, AutoSave = true, Editable = true, and Type = xlsx. SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument. Create(filepath, SpreadsheetDocumentType.Workbook); // Add a WorkbookPart to the document. WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart(); workbookpart.Workbook = new Workbook(); workbookpart.Workbook.Save(); **WorkbookPart wbPart = spreadsheetDocument.WorkbookPart; var stringTablePart = wbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault(); if (stringTablePart == null) { // Create it. stringTablePart = wbPart.AddNewPart<SharedStringTablePart>(); } stringTablePart.SharedStringTable = new SharedStringTable();** // Close the document. spreadsheetDocument.Close(); return filepath; }