使用 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.
- rename the xlsx to zip
- Open the zip and browse to the xl\workbook.xml file
- 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
我使用 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.
- rename the xlsx to zip
- Open the zip and browse to the xl\workbook.xml file
- 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