如何将公式写入Excel二进制文件?

3

我发现了一个开源项目(源代码),它具有基本的Excel功能,包括写入单元格、写入整数到单元格、更改颜色、字体等等。但是缺少一件事情,那就是添加公式,我无法实现它,如果有人知道如何做,那就太好了。

BIFF格式:

internal sealed class BIFF
    {
        public const ushort DefaultColor = 0x7fff;

        public const ushort BOFRecord = 0x0209;
        public const ushort EOFRecord = 0x0A;

        public const ushort FontRecord = 0x0231;
        public const ushort FormatRecord = 0x001E;
        public const ushort LabelRecord = 0x0204;
        public const ushort WindowProtectRecord = 0x0019;
        public const ushort XFRecord = 0x0243;
        public const ushort HeaderRecord = 0x0014;
        public const ushort FooterRecord = 0x0015;
        public const ushort ExtendedRecord = 0x0243;
        public const ushort StyleRecord = 0x0293;
        public const ushort CodepageRecord = 0x0042;
        public const ushort NumberRecord = 0x0203;
        public const ushort ColumnInfoRecord = 0x007D;       

    }

编写整数和字符串的示例方法

private void WriteStringCell(BinaryWriter writer, CellInfo cell)
        {
            string value;
            if (cell.Value is string)
                value = (string)cell.Value;
            else
                value = cell.Value.ToString();
            if (value.Length > 255)
                value = value.Substring(0, 255);
            ushort[] clData = { BIFF.LabelRecord, 0, 0, 0, 0, 0 };
            byte[] plainText = Encoding.GetEncoding(CodePage).GetBytes(value);
            int iLen = plainText.Length;
            clData[1] = (ushort)(8 + iLen);
            clData[2] = (ushort)cell.Row;
            clData[3] = (ushort)cell.Column;
            clData[4] = (ushort)cell.FXIndex;
            clData[5] = (ushort)iLen;
            WriteUshortArray(writer, clData);
            writer.Write(plainText);
        }
private void WriteNumberCell(BinaryWriter writer, CellInfo cell)
        {
            double dValue = Convert.ToDouble(cell.Value);
            ushort[] clData = { BIFF.NumberRecord, 14, (ushort)cell.Row, (ushort)cell.Column, (ushort)cell.FXIndex };
            WriteUshortArray(writer, clData);
            writer.Write(dValue);
        }

你可以从提供的链接下载源代码。所以我想要一个方法 WriteFromulaCell,它将在Excel中写入公式。但是完全没有成功。
提前致谢。

为什么不使用Excel的自动化模型? - Richard
因为BIFF的原因,我现在使用互操作性,但它很慢,如果超过3k条记录就会崩溃。所以我找到了这个库,它可以在不到3秒钟内生成10k条记录。 - Senad Meškin
好的。所以这是“性能”(这种背景对问题很重要)。通过从一次处理单元格转为整个范围并使用 Excel 自动化,发现了一个数量级的性能变化,您确定您不能在不进行如此激进的更改的情况下提高性能吗? - Richard
3个回答

1

BIFF 中的公式是用二进制标记流表示的。如果你想要创建一个 WriteFormulaCell() 函数,能够将类似 "=SUM(A3:Q47)" 的字符串转换为有效的 FORMULA 记录,那就需要花费几个月或者几年的时间(取决于你的工作速度)。而且,它们用于标记的字节码也发生了多次更改——每个 BIFF 版本在编码这些内容的方式上都有所不同。

如果你想要在指定的位置插入一个特定的简单公式,可以打开 Excel,在空白的电子表格上正确输入公式,保存为 Excel 97 文件格式,并查看 BIFF 文件。你会找到一个包含正确解析的标记流的 FORMULA 记录,你可以将其复制并插入到自己的文件中。我假设你已经知道相对引用和绝对引用的区别。对其他工作表的引用将使用索引而不是名称。定义的名称在此技巧中将不起作用。可能存在其他限制,具体情况取决于你的操作,本文不提供保证。


谢谢,我已经开始使用NPOI库了 :) - Senad Meškin

0
据我所知,Excel的“二进制”文件实际上是一个带有XML代码的ZIP文件(至少对于较新的Excel格式是如此)。我以前使用过Microsoft的库来读取这些文件。

我不需要读取,我需要写入,并且必须是 .xls 文件格式,这意味着可以被 Excel 97-2003 读取。 - Senad Meškin

0

尝试使用NPOI,它具有添加公式的功能,是开源和免费的,或者还有另一个开源xls项目:excellibrary。这两个项目都声称具有完整的BIFF实现。


我尝试了所有的方法,NPOI 太慢了,导出一个复杂的 Excel 文件需要 20 分钟,而且我有 967 个这样的文件。 - Senad Meškin
还有一件事,它们需要3.5 .NET框架,而我需要实现的服务器上只有.NET 2.0,目前没有升级。 - Senad Meškin
好吧,至少你可以查看源代码,了解他们是如何编写公式的。 - Antonio Bakula
我会做到的,但是我需要今天先完成那些报告。 :) - Senad Meškin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接