OpenXML:excel在.xsls中发现不可读的内容

我在ASP.NET应用程序中使用OpenXML。 这里是生成它的代码:

MemoryStream ms = new System.IO.MemoryStream(); SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook); WorkbookPart workbookPart = spreadsheetDocument.AddWorkbookPart(); workbookPart.Workbook = new Workbook(); WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>(); worksheetPart.Worksheet = new Worksheet(); UInt32Value rowIndex = 0; SheetData sheetData = new SheetData(); Row r1 = new Row() { RowIndex = rowIndex }; Cell c1 = new Cell() { DataType = CellValues.String, CellValue=new CellValue("col1") }; Cell c2 = new Cell() { DataType = CellValues.String, CellValue = new CellValue("col2") }; Cell c3 = new Cell() { DataType = CellValues.String, CellValue = new CellValue("col3") }; Cell c4 = new Cell() { DataType = CellValues.String, CellValue = new CellValue("col4") }; r1.Append(new List<Cell>() { c1, c2, c3, c4 }); rowIndex++; sheetData.Append(r1); foreach (Rezultat rez in rezultati) { Row r2 = new Row() { RowIndex = rowIndex }; Cell c1 = new Cell() { DataType = CellValues.String, CellValue = new CellValue(rez.a) }; Cell c2 = new Cell() { DataType = CellValues.String, CellValue = new CellValue(rez.b) }; Cell c3 = new Cell() { DataType = CellValues.String, CellValue = new CellValue(rez.c) }; Cell prolaz = new Cell() { DataType = CellValues.String }; if (rez.d) { prolaz.CellValue = new CellValue("DA"); } else { prolaz.CellValue = new CellValue("NE"); } r2.Append(new List<Cell>() { c1,c2,c3,c4 }); rowIndex++; sheetData.Append(r2); } worksheetPart.Worksheet.Append(sheetData); Sheets sheets = new Sheets(); Sheet sheet = new Sheet(); sheet.Name = "first"; sheet.SheetId = 1; sheet.Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart); sheets.Append(sheet); spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(sheets); spreadsheetDocument.WorkbookPart.Workbook.Save(); spreadsheetDocument.Close(); string fileName = "testOpenXml.xlsx"; Response.Clear(); Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", fileName)); ms.WriteTo(Response.OutputStream); ms.Close(); Response.End(); 

当我下载它,并尝试打开它在Excel中,我得到的消息,Excel中发现excel中不可读的上下文。我想我必须改变如何geenrate excel的方式。 我尝试了几个解决scheme,一些给了相同的错误,一些打开excel,但没有数据。

如果单元格不按顺序出现在文件中,则会出现此错误。

如果您在DevCenter中的“如何将文本插入电子表格文档(Open XML SDK)中的单元格”中使用Microsoft的示例代码 ,则会看到一个名为InsertCellInWorksheet的函数。 这个function有缺陷线:

if(string.Compare(cell.CellReference.Value,cellReference,true)> 0)

如果你有超过26列,这将导致他们这样sorting:

A1 AA1 AB1 B1 C1 D1 E1 ….

结果是您将看到列A中的数据和AA中的数据。 B到Z列将会丢失,您将看到令人恐惧的“Excel发现的不可读内容”消息。

你需要replace这个string.Compare与一个将在Z1之后放置AA1的函数,或者…如果你知道你正在创build所有东西,可以将它改为if(false)。

你想要创build的是InlineStringtypes的单元格而不是String。

以下是实现你需要的一部分的一个片段。 希望你可以根据你的需要修改它。

 SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(@"test.xlsx", SpreadsheetDocumentType.Workbook); WorkbookPart workbookPart = spreadsheetDocument.AddWorkbookPart(); WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>(); Row row = new Row { RowIndex = 1 }; Cell cell1 = new Cell { DataType = CellValues.InlineString }; InlineString inlineString1 = new InlineString(); Text text = new Text { Text = "col1" }; inlineString1.Append(text); cell1.Append(inlineString1); Cell cell2 = new Cell { DataType = CellValues.InlineString }; InlineString inlineString2 = new InlineString(); Text text2 = new Text { Text = "col2" }; inlineString2.Append(text2); cell2.Append(inlineString2); row.Append(new List<Cell>() { cell1, cell2 }); SheetData sheetData = new SheetData(); sheetData.Append(row); Worksheet worksheet = new Worksheet(); worksheet.Append(sheetData); worksheetPart.Worksheet = worksheet; worksheetPart.Worksheet.Save(); Sheets sheets = new Sheets(); string relId = workbookPart.GetIdOfPart(worksheetPart); Sheet sheet = new Sheet { Name = "Sheet1", SheetId = 1, Id = relId }; sheets.Append(sheet); Workbook workbook = new Workbook(); workbook.Append(sheets); spreadsheetDocument.WorkbookPart.Workbook = workbook; spreadsheetDocument.WorkbookPart.Workbook.Save(); spreadsheetDocument.Close();