我有一个程序,它导出一个System.Data.DataTable到XLSX / OPENXML电子表格。 终于等来了它主要的工作。 然而,在Excel中打开电子表格时,Excel的抱怨文件是无效的,需要维修,让这条消息...
我们发现一个问题,在一些内容。 你希望我们尝试恢复多,我们可以吗? 如果您信任该工作簿的来源,CLIK是。
如果我点击是的,它回来了这条消息...
点击日志文件,打开的是,恰恰说明了这...
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<logFileName>error268360_01.xml</logFileName>
<summary>Errors were detected in file 'C:\Users\aabdi\AppData\Local\Temp\data.20190814.152538.xlsx'</summary>
<repairedRecords>
<repairedRecord>Repaired Records: Cell information from /xl/worksheets/sheet1.xml part</repairedRecord>
</repairedRecords>
</recoveryLog>
显然,我们不希望这个部署到生产环境中是这样的。 所以,我一直在试图找出如何解决这个问题。 我扔在一起,一个小巧的样本来验证XML并显示错误的基础上, 从MSDN这个链接 。 但是,当我运行该程序并加载Excel的抱怨完全相同的XLSX文件,确认伤愈复出说,该文件是完全有效的。 所以,我不知道还有什么地方从那里。
对于试图验证我的XLSX XML任何更好的工具? 以下是我使用生成XLSX文件的完整代码。 (是的,它是在VB.NET,这是一个传统的应用程序。)
如果我在注释掉该行For Each dr As DataRow
循环,那么XLSX文件在Excel中打开罚款,(只是没有任何数据)。 所以这件事情的个体细胞,但我不是真的会大量使用它们。 设定值和数据类型,仅此而已。
我也试过更换For Each
环路ConstructDataRow
用下面的,但它仍然输出相同的“坏”的XML ...
rv.Append(
(From dc In dr.Table.Columns
Select ConstructCell(
NVL(dr(dc.Ordinal), String.Empty),
MapSystemTypeToCellType(dc.DataType)
)
).ToArray()
)
也试过更换调用Append
与AppendChild
每个细胞也一样,但这并没有帮助。
该压缩了XLSX文件(示数,以虚拟数据)可以在这里找到:
https://drive.google.com/open?id=1KVVWEqH7VHMxwbRA-Pn807SXHZ32oJWR
全部数据表到Excel XLSX代码
#Region " ToExcel "
<Extension>
Public Function ToExcel(ByVal target As DataTable) As Attachment
Dim filename = Path.GetTempFileName()
Using doc As SpreadsheetDocument = SpreadsheetDocument.Create(filename, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook)
Dim data = New SheetData()
Dim wbp = doc.AddWorkbookPart()
wbp.Workbook = New Workbook()
Dim wsp = wbp.AddNewPart(Of WorksheetPart)()
wsp.Worksheet = New Worksheet(data)
Dim sheets = wbp.Workbook.AppendChild(New Sheets())
Dim sheet = New Sheet() With {.Id = wbp.GetIdOfPart(wsp), .SheetId = 1, .Name = "Data"}
sheets.Append(sheet)
data.AppendChild(ConstructHeaderRow(target))
For Each dr As DataRow In target.Rows
data.AppendChild(ConstructDataRow(dr)) '// THIS LINE YIELDS THE BAD PARTS
Next
wbp.Workbook.Save()
End Using
Dim attachmentname As String = Path.Combine(Path.GetDirectoryName(filename), $"data.{Now.ToString("yyyyMMdd.HHmmss")}.xlsx")
File.Move(filename, attachmentname)
Return New Attachment(attachmentname, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
End Function
Private Function ConstructHeaderRow(dt As DataTable) As Row
Dim rv = New Row()
For Each dc As DataColumn In dt.Columns
rv.Append(ConstructCell(dc.ColumnName, CellValues.String))
Next
Return rv
End Function
Private Function ConstructDataRow(dr As DataRow) As Row
Dim rv = New Row()
For Each dc As DataColumn In dr.Table.Columns
rv.Append(ConstructCell(NVL(dr(dc.Ordinal), String.Empty), MapSystemTypeToCellType(dc.DataType)))
Next
Return rv
End Function
Private Function ConstructCell(value As String, datatype As CellValues) As Cell
Return New Cell() With {
.CellValue = New CellValue(value),
.DataType = datatype
}
End Function
Private Function MapSystemTypeToCellType(t As System.Type) As CellValues
Dim rv As CellValues
Select Case True
Case t Is GetType(String)
rv = CellValues.String
Case t Is GetType(Date)
rv = CellValues.Date
Case t Is GetType(Boolean)
rv = CellValues.Boolean
Case IsNumericType(t)
rv = CellValues.Number
Case Else
rv = CellValues.String
End Select
Return rv
End Function
#End Region