使用 EPPlus 更新链接到 PowerPivot 数据模型的 table,它损坏了数据模型

Update a table linked to a PowerPivot datamodel using EPPlus and it corrupts the datamodel

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

当我打开生成的电子表格时出现错误: "We found a problem with some content in 'MySpreadsheet.xlsx'. Do you want us to try to recover as much as we can?" -- 我单击“是”,但出现另一个错误: "Excel was able to open the file by repairing or removing the unreadable content. Removed Part: Data store"

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

[EDIT] - I created a win forms app that reproduces this problem. You can download it at here

I found the problem but don't know how to fix it.

  1. rename the xlsx to zip
  2. Open the zip and browse to the xl\workbook.xml file
  3. Look for the node collection.

Notice how EPPlus changes the <definedNames> collection to use absolute cell addresses.

Excel: <definedName name="_xlcn.LinkedTable_MyDate" hidden="1">MyDate[]</definedName>

EPPlus:  <definedName name="_xlcn.LinkedTable_MyDate" hidden="1">'MyDate'!$A:$A</definedName>

If I modify this line after EPPlus is done saving then I can pull it up in Excel without corrupting the Data Model.

I tried changing the WorkbookXml but it is happening when the ExcelPackage.Save method runs.

    For Each node In pck.Workbook.WorkbookXml.GetElementsByTagName("definedNames")(0).ChildNodes
        node.innerText = "MyDate[]"
    Next

Any ideas?

先试试这个:创建一个包含 table 的电子表格。为工作表命名并 table "DateList"。保存它并 运行 下面的代码 -- 它会起作用。

然后执行此操作:打开同一个电子表格并将 DateList table 添加到数据透视表table 数据模型。保存它并 运行 下面的代码 -- 它会失败。

这是我的 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

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

ExcelWorkbook.cs @第 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