【发布时间】:2015-07-28 17:21:54
【问题描述】:
我使用 EPPlus 读取了一个 XLSX 文件。 我替换表格中的数据并设置表格范围。
打开生成的电子表格时出现错误: “我们发现 'MySpreadsheet.xlsx' 中的某些内容存在问题。您希望我们尽可能多地恢复吗?” -- 我点击是,我得到另一个错误: "Excel 能够通过修复或删除不可读的内容来打开文件。删除部分:数据存储"
该错误仅在我将此表添加到 PowerPivot 数据模型后发生。
[编辑] - 我创建了一个重现此问题的 win forms 应用程序。你 可以在here下载
我找到了问题,但不知道怎么解决 修复它。
- 将 xlsx 重命名为 zip
- 打开 zip 并浏览到 xl\workbook.xml 文件
- 查找节点集合。
注意 EPPlus 如何将
<definedNames>集合更改为使用绝对单元格地址。Excel: <definedName name="_xlcn.LinkedTable_MyDate" hidden="1">MyDate[]</definedName> EPPlus: <definedName name="_xlcn.LinkedTable_MyDate" hidden="1">'MyDate'!$A$2:$A$5</definedName>如果我在 EPPlus 完成保存后修改此行,那么我可以将其拉出 在 Excel 中打开而不损坏数据模型。
我尝试更改 WorkbookXml,但它发生在 ExcelPackage.Save 方法运行。
For Each node In pck.Workbook.WorkbookXml.GetElementsByTagName("definedNames")(0).ChildNodes node.innerText = "MyDate[]" Next有什么想法吗?
先试试这个:创建一个包含一个表格的电子表格。将工作表和表命名为“DateList”。保存它并在上面运行下面的代码——它会工作的。
然后执行以下操作:打开同一个电子表格并将 DateList 表添加到可数据透视的数据模型中。保存它并在上面运行下面的代码——它会失败。
这是我的 MVC 控制器中的一些代码——只有相关位:
Public Class ScorecardProgressReportDatesVM
Public Property WeekRange As Date
End Class
Public Function GetScorecardProgressReport(id As Integer) As ActionResult
Dim contentType As String = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Dim DateList As New List(Of ScorecardProgressReportDatesVM)
DateList.Add(New ScorecardProgressReportDatesVM With {.WeekRange = CDate("Jan 1, 2015")})
DateList.Add(New ScorecardProgressReportDatesVM With {.WeekRange = CDate("Jan 1, 2015")})
Dim templateFile As New IO.FileInfo("c:\test.xlsx")
Dim ms As New IO.MemoryStream
Using pck As New ExcelPackage(templateFile)
ExtendTable(pck, "DateList", DateList)
pck.SaveAs(ms)
ms.Position = 0
End Using
Dim fsr = New FileStreamResult(ms, contentType)
fsr.FileDownloadName = "StipProgress.xlsx"
Return fsr
End Function
Private Sub ExtendTable(package As ExcelPackage, tableName As String, newList As Object)
Dim ws As OfficeOpenXml.ExcelWorksheet
ws = package.Workbook.Worksheets(tableName)
Dim OutRange = ws.Cells("A1").LoadFromCollection(newList, True)
Dim t = ws.Tables(tableName)
Dim te = t.TableXml.DocumentElement
Dim newRange = String.Format("{0}:{1}", t.Address.Start.Address, OutRange.End.Address)
te.Attributes("ref").Value = newRange
te("autoFilter").Attributes("ref").Value = newRange
End Sub
【问题讨论】:
-
excel文件中的DateList表是什么样子的?如果您要弄乱它的属性,请确保您也更新列集合。
-
与 ScorecardProgressReportDatesVM 相同。一列名为 WeekRange。正在修改的属性是更改表以匹配列表中的项目数。列没有改变,整个表最初是使用 LoadFromCollection 从此类的列表中创建的。
-
我在epplus.codeplex.com/workitem/15312#向 CodePlex 添加了一个错误报告
-
有趣。您使用的是哪个版本的 epplus? ExcelPivotCacheDefinition.cs 中出现错误 - “缓存源不是工作表”。似乎是
if (CacheSource == eSourceType.Worksheet)行,如果我创建一个数据透视表,它将被设置为“外部”。 (显然我似乎没有 Power Pivot 插件)。 -
我正在使用 EPPlus v4.0.4、VS2013 Update4、.Net 4.5 和 Office 365 Excel 2013 v15.0.4727.1000
标签: vb.net excel asp.net-mvc-4 powerpivot epplus