当包含大量行时,OpenXml 电子表格输出在 OpenOffice 中打开 "General Error"

OpenXml Spreadsheet Output gives "General Error" opening in OpenOffice when containing a large number of rows

OpenXML 的电子表格输出在 Excel(和 Google 文档)中有效,但在 OpenOffice 4.x...

中会引发运行时错误

具体错误是

General Error.

General input/output error.

没有进一步的解释。实际上,只有当电子表格的行数超过 40 行时,它才会发生在我身上;但是,似乎没有特定数量的行导致该问题。

我已经为这个问题创建了一个解决方法。这个post只是为了向那些只需要一些东西的人分享我可怕的解决方案。

我怀疑原因可能在 Zip headers 或部分 zip 条目本身中,并且它们是库中的错误,该错误为 System.IO.Packaging 命名空间写入 Zip 输出(我假设 OpenXML 使用)或者 OpenOffice 有一个非常简单的 zip reader。也许中央目录文件偏移量与压缩文件大小有关,但由于时间有限,我没有费心去检查。

有一天我可能会进一步调查,或者如果有人知道快速解决方案,请告诉我。这些文件是使用 MSDN 上的示例编写的,它们在 Excel.

中可以正确打开

与此同时,如果有人需要 band-aid 解决这个问题,我正在 post 快速修复这里,因为我自己找不到一个。它需要一个字节数组(可能从 MemorySteam 转储或读取 FileStream)。它输出另一个字节数组。

聪明的人可以让它接受一个 Stream,寻找相对于 Beginning 的 0,然后从那里读取,也许直接写入另一个传入的流。这将是对 reader 的练习,除非有人碰巧 post 做出同样的反应。

如果有人有更好的解决方案,我不介意知道。

使用 .NET 4.5

参考文献System.IO.Compression

using System;
using System.IO;
using System.IO.Compression;

namespace redmasq {
   public static class ExcelFileFixExample {
        public static byte[] XLSXOpenOfficePackageFix(byte[] fileData) {
            using (MemoryStream ms = new MemoryStream(fileData, false)) {
                using (ZipArchive za = new ZipArchive(ms)) {
                    using (MemoryStream ms2 = new MemoryStream()) {
                        using (ZipArchive za2 = new ZipArchive(ms2, ZipArchiveMode.Create)) {
                            foreach (ZipArchiveEntry entry in za.Entries) {
                                ZipArchiveEntry zae = za2.CreateEntry(entry.FullName, System.IO.Compression.CompressionLevel.Optimal);
                                using (Stream src = entry.Open()) {
                                    using (Stream dest = zae.Open()) {
                                        src.CopyTo(dest);
                                    }
                                }
                            }
                        }
                        return ms2.ToArray();
                    }
                }
            }
        }
   }
}