Excel и Libre Office конфликтуют из-за вывода Open XML - PullRequest
0 голосов
/ 03 июня 2019

Open XML генерирует файлы .xlsx, которые могут быть прочитаны Open Office, но не самим Excel.

Исходя из этого, я могу начать ( Экспорт DataTable в Excel с Open Xml SDK в c #) Я добавил код для создания файла .xlsx.Пытаясь открыть в Excel, меня спрашивают, хочу ли я восстановить файл.Скажите «да»: «Книга не может быть открыта или отремонтирована в Microsoft Excel, потому что она повреждена».После многих часов попыток перемешать данные из моей таблицы, чтобы сделать эту работу, я, наконец, в отчаянии вскинул руки и сделал электронную таблицу с одним номером в первой ячейке.

Все еще поврежден.

Переименование его в .zip и исследование показывает неповрежденные файлы .xml.По какой-то причине я взял законный файл .xlsx, созданный в Excel, разархивировал его, заново распаковал без изменения содержимого и переименовал обратно в .xlsx.Excel объявил его испорченным.Так что это явно не проблема контента, а проблема формата файла.Отказавшись в пятницу, я отправил некоторые образцы файлов домой и открыл их там в Libre Office.Проблем не было вообще.Содержимое файла было правильным, и у Calc не было проблем.Я использую Excel для 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 голосов
/ 04 июня 2019

Работая над этим, я исходил из того, что какой-то посторонний мусор в конце файла .zip безвреден.7-Zip, Windows Explorer и Libre Office, похоже, все согласны (как и некоторые другие zip-программы, которые я использовал дома, имя которых ускользает от меня).Excel, однако, нет.Использование указателя на memStream.GetBuffer() было нормально, но использование его длины не было.(Предыдущий Seek() не был необходим.) Ограничение записи данных длиной, равной текущей позиции вывода, не позволяет Excel сойти с рельсов.

...