Excel和Libre Office在Open XML输出方面发生冲突

时间:2019-06-03 14:56:29

标签: excel openxml libreoffice

Open XML生成的.xlsx文件可以由Open Office读取,但不能由Excel本身读取。

以此为起点(Export DataTable to Excel with Open Xml SDK in c#),我添加了创建.xlsx文件的代码。尝试使用Excel打开时,系统询问我是否要修复文件。说“是”,因为该工作簿已损坏,因此无法通过Microsoft Excel打开或修复该工作簿。经过数小时的尝试来整理表中的数据以完成这项工作后,我终于绝望了,在第一个单元格中制作了一个带有单个数字的电子表格。

仍然腐败。

将其重命名为.zip并浏览显示完整的.xml文件。我一时兴起,拿走了一个由Excel创建的合法的.xlsx文件,将其解压缩,重新压缩而不更改内容,然后重命名为.xlsx。 Excel声明它已损坏。因此,这显然不是内容问题,而是文件格式问题。在星期五放弃时,我将一些示例文件发送回了家,并在Libre Office那里打开了它们。完全没有问题。文件内容正确,Calc没问题。我正在使用Excel for Office 365(32位)。

// ignore the bits (var list) that get data from the database. I've reduced this to just the output of a single header line
List< ReportFilingHistoryModel> list = DB.Reports.Report.GetReportClientsFullHistoryFiltered<ReportFilingHistoryModel>(search, client, report, signature);

MemoryStream memStream = new MemoryStream();
using (SpreadsheetDocument workbook = SpreadsheetDocument.Create(memStream, SpreadsheetDocumentType.Workbook))
{
    var workbookPart = workbook.AddWorkbookPart();

    workbook.WorkbookPart.Workbook = new Workbook();

    workbook.WorkbookPart.Workbook.Sheets = new Sheets();

    var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
    var sheetData = new SheetData();
    sheetPart.Worksheet = new Worksheet(sheetData);

    Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<Sheets>();
    string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);

    uint sheetId = 1;
    if (sheets.Elements<Sheet>().Count() > 0)
    {
        sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
    }

    Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = "History" };
    sheets.Append(sheet);

    Row headerRow = new Row();

    foreach( var s in "Foo|Bar".Split('|'))
    {
        var cell = new Cell();
        cell.DataType = CellValues.Number;
        cell.CellValue = new CellValue("5");
        headerRow.AppendChild(cell);
    }
    sheetData.AppendChild(headerRow);
}
memStream.Seek(0, SeekOrigin.Begin);
Guid result = DB.Reports.Report.AddClientHistoryList( "test.xlsx", memStream.GetBuffer(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
return Ok(result);

这应该可以正常工作。我注意到了其他堆栈溢出讨论,这些讨论直接回到了我上面提到的第一个链接。我似乎做对了(Calc也同意)。已经讨论了共享字符串和诸如此类的问题,但是通过使用纯数字,我应该不会遇到问题。我在这里想念什么?

1 个答案:

答案 0 :(得分:0)

在处理此问题时,我想到了.zip文件末尾的一些多余垃圾是无害的。 7-Zip,Windows资源管理器和Libre Office似乎都同意(就像我在家中使用的其他一些zip程序一样,它们的名字让我不知道)。 Excel,但是没有。使用memStream.GetBuffer()处的指针是可以的,但不能使用其长度。 (前面的Seek()是不必要的。)将数据写入的长度限制为等于当前输出位置的长度,可以防止Excel脱离轨道。