【问题标题】:Update a table linked to a PowerPivot datamodel using EPPlus and it corrupts the datamodel使用 EPPlus 更新链接到 PowerPivot 数据模型的表,它会破坏数据模型
【发布时间】:2015-07-28 17:21:54
【问题描述】:

我使用 EPPlus 读取了一个 XLSX 文件。 我替换表格中的数据并设置表格范围。

打开生成的电子表格时出现错误: “我们发现 'MySpreadsheet.xlsx' 中的某些内容存在问题。您希望我们尽可能多地恢复吗?” -- 我点击是,我得到另一个错误: "Excel 能够通过修复或删除不可读的内容来打开文件。删除部分:数据存储"

该错误仅在我将此表添加到 PowerPivot 数据模型后发生。

[编辑] - 我创建了一个重现此问题的 win forms 应用程序。你 可以在here下载

我找到了问题,但不知道怎么解决 修复它。

  1. 将 xlsx 重命名为 zip
  2. 打开 zip 并浏览到 xl\workbook.xml 文件
  3. 查找节点集合。

注意 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


【解决方案1】:

为了解决这个问题,我们不得不更改 EPPlus v4.04 源代码。

ExcelWorkbook.cs @ line 975 已更改

//elem.InnerText = name.FullAddressAbsolute; This was causing issues with power pivot

到

elem.InnerText = name.FullAddress; //Changed to full address... so far everything is working

【讨论】:

  • 这可能为时过早。现在我收到一个错误“缓存源不是工作表”
猜你喜欢
  • 1970-01-01
  • 2014-08-29
  • 1970-01-01
  • 2017-03-29
  • 1970-01-01
  • 2018-11-20
  • 2011-07-05
  • 2018-03-18
  • 2016-12-25
相关资源
最近更新 更多