簡體   English   中英

在Excel中編輯后,OpenXML無法讀取電子表格數據

[英]OpenXML unable to read spreadsheet data after editing in Excel

我正在使用OpenXML,以便將一些翻譯數據導出到Excel電子表格,然后將同一電子表格導入到我的程序中。

現在,如果我直接導​​出和導入,此方法就可以很好地工作,但是,如果我在excel中打開op電子表格並對其進行編輯或保存,則程序無法讀取數據,就好像它已損壞一樣。 但是,如果我再次打開它,Excel認為它很好,因此該文件實際上並未損壞。

導出數據

using (SpreadsheetDocument document = SpreadsheetDocument.Create(saveLocation, SpreadsheetDocumentType.Workbook))
...

//Add a WorkbookPart to the document
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();

//Add a WorksheetPart to the WorkbookPart
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();

//Add style
WorkbookStylesPart stylePart = workbookPart.AddNewPart<WorkbookStylesPart>();
stylePart.Stylesheet = GenerateStylesheet();
stylePart.Stylesheet.Save();
...

SheetData sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
//Append some rows
...

worksheetPart.Worksheet.Save();

閱讀電子表格

using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileStream, false))
        {
            WorkbookPart workbookPart = document.WorkbookPart;
            WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
            SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

            var headerRow = sheetData.Elements<Row>().FirstOrDefault();
            ...

            //All data here are numbers

因此,最初我以為可能是由excel創建了更多的工作表,並且我以為.First()會為我提供正確的工作表,但我完全錯了,但是在調試時查看該對象表明數據是正確的。 因此,顯然這里有問題,所以我決定查看.xlsx文件的存檔內容。

這是在我的程序導出並創建文件之后。 您可以看到xml文件中有一些實際數據(字符串)。

在此處輸入圖片說明

這是我在Excel中打開電子表格並將其保存后完全不做任何編輯的情況。

在此處輸入圖片說明

我不知道為什么這會發生,如果它是某種預期的行為。 我發現OpenXML充滿了奇怪的設計選擇,但是在經歷迷宮般的迷路之后,這才是真正阻止我前進的第一件事。

我在macOS的Netcore 2.0上構建,顯然Excel也在macOS上運行。

如果有人可以幫助我解決這個問題,我將非常高興。

有兩種方法將字符串存儲在Excel文件中; 就像創建時一樣使用內聯字符串,或者如注釋中指出的那樣,使用稱為SharedStringTable的單獨XML文件。 Excel恰好使用后一種方法,因此直接在每個包含字符串的單元格中插入它們,而不是在SharedStringTable中包含一個條目的索引。

幸運的是,您可以像使用文檔的任何其他部分一樣使用OpenXML讀取SharedStringTable。 例如:

using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileStream, false))
    {
        WorkbookPart workbookPart = document.WorkbookPart;
        WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
        SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

        SharedStringTablePart stringTable = workbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();

        var headerRow = sheetData.Elements<Row>().FirstOrDefault();

        foreach (Cell c in headerRow.Elements<Cell>())
        {
            string cellText;

            if (c.DataType == CellValues.SharedString)
            {
                //the value will be a number which is an index into the shared strings table
                int index = int.Parse(c.CellValue.InnerText);
                cellText = stringTable.SharedStringTable.ElementAt(index).InnerText;
            }
            else
            {
                //just take the value from the cell (note this won't work for some types e.g. dates)
                cellText = c.CellValue.InnerText;
            }

            Console.WriteLine(cellText);
        }

    }
}

對於大文件,您可能需要考慮按照本問答中的討論來緩存共享字符串。

如何提高OpenXml Excel電子表格工具中從SharedStringTable檢索值的性能?

暫無
暫無

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

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