无法在C#中使用Gembox加载.xls文件

时间:2017-11-21 06:14:56

标签: c# gembox-spreadsheet

我想使用C#加载.xls文件(类型:97-2003电子表格)。 我正在使用Gembox库。

当我使用下面的命令时,我遇到了" 文件包含损坏的数据。"作为错误。

ExcelFile ef = ExcelFile.Load(filepath, XlsxLoadOptions.XlsxDefault);

当我删除XlsxLoadOptions参数时,我得到" 读取错误:文件不是有效的OLE2复合文件。"

我是C#的新手,无法调试问题的根本原因。 请帮忙!

1 个答案:

答案 0 :(得分:4)

评论中回答了这个问题。不幸的是,它在那里看不到,所以这里是答案,还有一些关于它的其他细节。

GemBox.Spreadsheet提供的Load overload methods很少。使用以下内容时:

ExcelFile ef = ExcelFile.Load("C://temp//book.xls");

将产生以下结果:

ExcelFile ef = ExcelFile.Load("C://temp//book.xls", LoadOptions.XlsDefault);

与以下内容相同:

ExcelFile ef = ExcelFile.Load("C://temp//book.xls", new XlsLoadOptions());

加载选项指定输入文件的读取方式,使用ExcelFile.Load(String)方法时,选项将基于文件的扩展名。

在这种情况下,文件有" .xls"扩展,但它不是二进制XLS格式(BIFF8),而是HTML格式。这是一个有点常用的技巧,你可以拥有HTML,CSV,甚至是带有" .xls"的XLSX文件。扩展和MS Excel将能够打开它。它将检测正确的文件格式,并将提示用户输入以下消息:

  

' book.xls'的文件格式和扩展名。不匹配。该文件可能已损坏或不安全。除非你相信它的来源,否则不要打开它。你想打开吗?

请注意,此技巧仅适用于" .xls"扩展,它不适用于例如" .xlsx"。不过我们可以使用类似下面的内容来检测正确的文件格式:

private static LoadOptions GetLoadOptions(string path)
{
    string extension = Path.GetExtension(path).ToUpperInvariant();
    switch (extension)
    {
        case ".XLSX":
        case ".XLSM":
        case ".XLTX":
        case ".XLTM":
            return LoadOptions.XlsxDefault;
        case ".XLS":
        case ".XLT":
            return GetLoadOptions(path, null);
        case ".ODS":
        case ".OTS":
            return LoadOptions.OdsDefault;
        case ".TAB":
        case ".TSV":
            return new CsvLoadOptions(CsvType.TabDelimited);
        case ".CSV":
            return LoadOptions.CsvDefault;
        default:
            return null;
    }
}

private static LoadOptions GetLoadOptions(string xlsPath, LoadOptions defaultOptions)
{
    byte[] signature = new byte[8];
    using (var stream = File.OpenRead(xlsPath))
        stream.Read(signature, 0, 8);

    byte[] xlsSignature = new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 };
    if (signature.SequenceEqual(xlsSignature))
        return LoadOptions.XlsDefault;

    byte[] xlsxSignature = new byte[] { 0x50, 0x4B, 0x03, 0x04 };
    if (signature.Take(4).SequenceEqual(xlsxSignature))
        return LoadOptions.XlsxDefault;

    string firstLine = File.ReadLines(xlsPath)
        .First(line => !string.IsNullOrWhiteSpace(line)).TrimStart().ToUpperInvariant();
    if (firstLine.StartsWith("<!DOCTYPE") ||
        firstLine.StartsWith("<HTML") ||
        firstLine.StartsWith("<BODY"))
        return LoadOptions.HtmlDefault;

    return defaultOptions;
}

此处还有一个关于如何使用它的小型演示示例:

string filepath = "C://temp//book.xls";
LoadOptions options = GetLoadOptions(filepath);

if (options == null)
    throw new FileFormatException();

ExcelFile ef = ExcelFile.Load(filepath, options);
// ...