使用EPPlus生成的Excel文件中的不可读内容
使用EPPlus库从模板生成Excel文件时遇到了一些问题。 该文件具有第一个电子表格,其中包含用于填充下表中的数据透视表的数据。
当我打开生成的文件时,出现以下错误信息:“Excel中发现'sampleFromTemplate.xlsx'中的不可读内容。是否要恢复此工作簿的内容?我相信此工作簿的来源,单击是。
我显然是单击是,然后得到对文件进行修复的摘要,并链接到一个XML格式的日志文件,其中包含:
<?xml version="1.0" encoding="UTF-8" standalone="true"?> <recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> <logFileName>error095080_01.xml</logFileName> <summary>Errors were detected in file 'C:\TEMP\sampleFromTemplate.xlsx'</summary> <repairedRecords summary="Following is a list of repairs:"> <repairedRecord>Repaired Records: Table from /xl/tables/table1.xml part (Table)</repairedRecord> </repairedRecords> </recoveryLog>
这显然是由我在代码中定义的指定范围(“Table1”)引起的,以指示要用于数据透视表的数据。 在名为“Table1”的模板中已经有一个“Table Name”,但是我似乎无法通过ExcelPackage.Worksheet.Names集合来访问它。 作为EPPlus的新人,并没有用Excel做很多实验,我不明白我做错了什么。 以下是我生成文件的一些代码:
private string GenerateFromTemplate(string fileName, string templateName, DataTable tab) { FileInfo newFile = new FileInfo(string.Format("C:\\MyPath\\{0}.xlsx", fileName)); FileInfo templateFile = new FileInfo(string.Format("C:\\MyPath\\{0}.xlsx", templateName)); try { using (ExcelPackage pkg = new ExcelPackage(newFile, templateFile)) { ExcelWorksheet sheet = pkg.Workbook.Worksheets["MyDataSheet"]; ExcelRange range = sheet.Cells[string.Format("A1:U{0}", dt.Rows.Count)]; pkg.Workbook.Names.Add("Table1", range as ExcelRangeBase); int sheetRowIndex = 2; foreach (DataRow row in this.dt.Rows) { sheet.Cells[sheetRowIndex, 1].Value = row["Row1"]; sheet.Cells[sheetRowIndex, 2].Value = row["Row2"]; [...] sheet.Cells[sheetRowIndex, 21].Value = row["Row21"]; sheetRowIndex++; } pkg.Save(); return newFile.FullName; } } catch (IOException ex) { return ex.Message; } }
请注意,无论如何,透视表正确填充,那么为什么会发生这种情况呢?
谢谢 :-)
我只是自己碰到了这个问题,并修复了这个问题,把我的解决scheme放在这里,如果有人遇到它:
这是使用asp.net,显而易见的原因,否则不适用。
我的问题不是表范围,Epplus生成的文件就好了,而是服务器的响应是附加到Excel文件的页面响应,显然使文件无效。 发送文件后立即结束服务器响应,解决了我的问题,一些调整:
Response.BinaryWrite(pck.GetAsByteArray()); // send the file Response.End();
问题没有解决,但现在我知道到底是为什么。 这个“表1”的东西不是一个命名的范围,而是一个表,我可以通过工作表的“表”集合访问。
现在,问题是EPPlus中的表集合和表对象都是只读的,所以我无法从我的代码中定义表的维度,我也不能删除它或添加一个新的符合我的需要。 EPPlus的作者已经提到,它可能有一天会实现( 这里和这里 )公共汽车,因为信息差不多3年了,我想没有希望看到这种情况发生…
无论如何,我希望这将有助于任何人遇到同样的问题。
[编辑]我终于想出了一种方法来绕过这个问题:ExcelTable对象有一个名为“TableXml”的可写属性,其中包含该表的xml定义 – 当然,它的范围。 这里是我的情况下的内容:
<?xml version="1.0" encoding="UTF-8" standalone="true"?> <table dataCellStyle="Normal 2" headerRowCellStyle="Normal 2" headerRowDxfId="70" totalsRowShown="0" insertRow="1" ref="A1:U2" displayName="Table1" name="Table1" id="1" xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> <autoFilter ref="A1:U2"/> <tableColumns count="21"> <tableColumn dataCellStyle="Normal 2" name="Activity" id="1"/> <tableColumn dataCellStyle="Normal 2" name="Category" id="21"/> [...] <tableColumn dataCellStyle="Normal 2" name="Closed Year" id="20" dataDxfId="62"/> </tableColumns> <tableStyleInfo name="TableStyleMedium9" showColumnStripes="0" showRowStripes="1" showLastColumn="0" showFirstColumn="0"/> </table>
我们在这里感兴趣的是“table”和“autoFilter”节点中的“ref”属性,因为改变它们的值可以重新定义我们表的范围。
我这样做了:
XmlDocument tabXml = sheet.Tables(0).TableXml; XmlNode tableNode = tabXml.ChildNodes[1]; tableNode.Attributes["ref"].Value = string.Format("A1:U{0}", dt.Rows.Count + 1); XmlNode autoFilterNode = tableNode.ChildNodes[0]; autoFilterNode.Attributes["ref"].Value = string.Format("A1:U{0}", dt.Rows.Count + 1);
而现在我的Excel文件正确生成与“Table1”适合我的数据的实际范围!
我碰到这个时,我有一个错误,每行后添加一个额外的列分隔符:
head1{tab}head2{tab} col11{tab}col21{tab} col22{tab}col22{tab}
最后一列之后的额外的选项卡以同样的方式打破了最终的Excel电子表格,并删除它解决了问题。 注意我正在使用LoadFromText
从文本数据一次加载整个工作表。 这可能不是OP的问题,但也许未来的search者会发现这有帮助。
我花了大约4个小时解决这个问题,由于我的问题和解决scheme不在岗位上,我写它为任何未来的访客,
我的问题是由Excel表中的重复列导致的。 在向一列添加空间之后,问题就解决了。 有趣的部分是,当我通过MS excel生成数据透视表时,错误从来没有出现过,它只是在我使用epplus在Excel文件中生成数据透视表时才出现。 使错误更难find
在编辑具有特殊格式(Windings字体用于显示特殊符号)的表格的工作簿时,出现此问题。 必须删除格式来修复信息。
- 使用Microsoft Office interop v.11与Windows 7,Microsoft Office 2010的应用程序
- 我如何使用Parallel.ForEach for Excel?
- 如何从c#中包含多行的数据中读取单行?
- 即使在此字段中只有数字,也可以以stringforms读取Excel字段
- itgenclr007:使用VSTO加载项修复32位Excel中的OutOfMemory
- 将类属性映射到Excel / Spreadsheet列名的问题(使用LinqToExcel库时)
- 从Excel 2010中调用Web服务
- 什么架构来解决这个SystemOutOfMemoryException,同时允许我实例化一个工作表的单元格?
- 用于格式化模板的用于Excel 2003电子表格生成的.NET组件