簡體   English   中英

無法在 C# 中使用 Gembox 加載 .xls 文件

[英]Unable to load .xls file using Gembox in C#

我想使用 C# 加載.xls文件(類型: 97-2003電子表格)。 我正在使用 Gembox 庫。

當我使用下面的命令時,我遇到“文件包含損壞的數據。 ”作為錯誤。

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

當我刪除 XlsxLoadOptions 參數時,我收到“讀取錯誤:文件不是有效的 OLE2 復合文件。

我是 C# 新手,無法調試問題的根本原因。 請幫忙!

更新 (2020-03-28)

在較新版本的 GemBox.Spreadsheet 中, ExcelFile.Load(String)將檢查文件的簽名,以防出現“.xls”文件。
換句話說,不再需要下面的GetLoadOptions方法。

此外,還有一個新的重載方法ExcelFile.Load(Stream)
這將始終檢查提供的流中的文件簽名。

原版

這個問題在評論中得到了回答。 不幸的是,它在那里不太明顯,所以這里是答案以及有關它的一些其他詳細信息。

GemBox.Spreadsheet 提供了很少的Load 重載方法 使用以下內容時:

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);
// ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM