OpenXmlSDK не может прочитать созданный вручную файл xlsx: «Указанный пакет недействителен.Основная часть отсутствует. - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть сторонняя библиотека, которая создает xlsx-файл.Он не использует OpenXmlSDK, он объединяет файл из фрагментов xml-разметки.Для архивирования используются ZipArchive класс.Но когда я пытаюсь сделать с OpenXmlSDK

var document = SpreadsheetDocument.Open(fileStream, false);

, происходит сбой с ошибкой:

DocumentFormat.OpenXml.Packaging.OpenXmlPackageException: 'Указанный пакетнедействительным.Основная часть отсутствует. '

MS Excel открывает этот файл нормально.Помогает восстановление из Excel.

Кроме того, я разархивирую файлы, затем снова архивирую их (без каких-либо изменений), пытаюсь снова вызвать вышеуказанный код, и он работает.

В чем проблема?Как заархивировать xlsx-файл, готовый для OpenXmlSDK?

РЕШЕНИЕ

Проблема была с сохранением файла сторонней библиотекой.Файлы, включенные в zip, имеют имя записи с \ вместо /.Код этой библиотеки был отредактирован, чтобы исправить это, и все в порядке.

1 Ответ

0 голосов
/ 06 февраля 2019

После некоторого исследования я обнаружил, что люди жалуются на это исключение в двух сценариях:

Поскольку вы открываете файл из потока, вторая причина скорее не применима в этом случае.

Если шрифтиспользование не является причиной, попробуйте вручную сравнить версии файлов до и после сохранения в Excel в Open XML Productivity Tool (https://www.microsoft.com/en-us/download/details.aspx?id=30425).

Если нет различий в содержимом документов, попробуйте сравнить параметры сжатия архива.

ОБНОВЛЕНИЕ

Кажется, я нашел дополнительную информацию о проблеме, которая может помочь найти решение.

Мне удалось воспроизвести Основная часть отсутствует. ошибка при создании архива с: ZipFile.CreateFromDirectory(@"C:\DirToCompress", destFilePath, CompressionLevel.Fastest, false);.

Затем я проверил, что открытие файла с Package.Open(destFilePath, FileMode.Open, FileAccess.Read) на самом деле указано 0 части fв файле.

После проверки некоторых различий я заметил, что в правильном файле xlsx записи, вложенные в папки в архиве, имеют FullName пути, представленные с использованием символа /, например: _rels/.rels,В поврежденном файле имена были написаны символом \, например: _rels\.rels.Вы можете исследовать его, открыв файл с использованием класса ZipArchive (например: new ZipArchive(archiveStream, ZipArchiveMode.Read, false, UTF8Encoding.UTF8);) и изучив коллекцию Entries.

Важно отметить, что существуют правила именования деталей, описанные вспецификация Office Open XML: https://www.ecma -international.org / news / TC45_current_work / Office% 20Open% 20XML% 20Part% 202% 20-% 20Open% 20Packaging% 20Conventions.pdf

В качестве теста я написал код, который открывает поврежденный файл xlsx с использованием класса ZipArchive и переписывает каждую запись, копируя ее содержимое и заменяя \ на / в качестве имени воссозданной записи.После этой операции полученный файл, по-видимому, открывается правильно с помощью метода SpreadsheetDocument.Open(...).

Обратите внимание, что использованный мной метод исправления имен был очень простым и может быть недостаточным или работать неправильно в некоторых сценариях.Однако эти заметки могут помочь найти желаемое решение проблемы.

...