使用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字体用于显示特殊符号)的表格的工作簿时,出现此问题。 必须删除格式来修复信息。