Spreadsheet Lite SaveAs 函数中的错误消息 "entries cannot be opened multiple times in update mode."

Error message "entries cannot be opened multiple times in update mode." in Spreadsheet Lite SaveAs function

在下面的代码中执行 dBWorksheet.SaveAs(xlsFileSpec) 后,我看到一个异常:

"entries cannot be opened multiple times in update mode."

        SLDocument dBWorksheet = new SLDocument();
        TimeSpan interval = new TimeSpan(0, 0, 2);

        dBWorksheet.SetCellValue(2, 1, "Hour");
        dBWorksheet.SetCellValue(3, 1, "Time");

        int Row = 3;

        // Create the hour and time of day columns.
        for(TimeSpan dBTime = new TimeSpan(0, 0, 0); dBTime.TotalHours < 24; dBTime = dBTime.Add(interval)) 
        {
            dBWorksheet.SetCellValue(Row, 1, dBTime.Hours);
            dBWorksheet.SetCellValue(Row, 2, dBTime.ToString());

            Row++;
        }

        // Save the new worksheet.
        dBWorksheet.SaveAs(xlsFileSpec);

从 .NET Core 3.0 回滚到 .NET Framework 4。7.x

这显然不是最理想的解决方案。

但是,我找到的唯一解决方案是将应用程序从 .NET Core 3.0 和 SpreadsheetLight.Core 回滚到 .NET Framework 4。7.x 和 SpreadsheetLight。

上面问题中发布的代码无需修改即可运行。

我认为这与 .NET Core 3.0 System.IO.Packaging 中修复的内存泄漏有关。这将需要进一步调查并可能修复 SpreadsheetLight.Core.

晚会有点晚了,但刚好遇到这个问题。 我通过创建一个新的 SLDocument 并从旧的 SLDocument 逐个单元格地复制来解决这个问题。可能不会 100% 有效,但到目前为止它已经涵盖了我的报告。

代码

using (var file = new SLDocument())
            {
                file.CopyFromTemplate(Path.Combine("ReportTemplates\Tackningsbidrag_budget.xlsx"), maxCols: 20, maxRows: 10);

                // code

                using (var ms = new MemoryStream())
                {
                    file.SaveAs(ms);
                }
            }

扩展方法:

public static void CopyFromTemplate(this SLDocument file, string pathToOrgFile, int? maxCols = null, int? maxRows = null)
    {
        using (var orgFile = new SLDocument(pathToOrgFile))
        {
            var page = orgFile.GetPageSettings();
            file.SetPageSettings(page);

            foreach (var cell in orgFile.GetWorksheetMergeCells())
            {
                file.MergeWorksheetCells(cell.StartRowIndex, cell.StartColumnIndex, cell.EndRowIndex, cell.EndColumnIndex);
            }

            var stats = orgFile.GetWorksheetStatistics();
            var endCol = stats.EndColumnIndex;
            if (maxCols.HasValue && maxCols < endCol)
            {
                endCol = maxCols.Value;
            }

            var endRow = stats.EndRowIndex;
            if (maxRows.HasValue && maxRows < endRow)
            {
                endRow = maxRows.Value;
            }
            for (int col = stats.StartColumnIndex; col <= endCol; col++)
            {
                file.SetColumnStyle(col, orgFile.GetColumnStyle(col));
                file.SetColumnWidth(col, orgFile.GetColumnWidth(col));

            }

            for (int row = stats.StartRowIndex; row <= endRow; row++)
            {
                file.SetRowStyle(row, orgFile.GetRowStyle(row));
                file.SetRowHeight(row, orgFile.GetRowHeight(row));
            }


            for (int row = stats.StartRowIndex; row <= endRow; row++)
            {
                for (int col = stats.StartColumnIndex; col <= endCol; col++)
                {
                    var formula = orgFile.GetCellFormula(row, col);
                    var stringValue = orgFile.GetCellValueAsString(row, col);
                    file.SetCellValue(row, col, !string.IsNullOrWhiteSpace(formula) ? ("=" + formula) : stringValue);

                    file.SetCellStyle(row, col, orgFile.GetCellStyle(row, col));
                }
            }
        }
    }

我是这样解决的。

  1. 已下载 SpreadsheetLight(版本 3.5)的源代码。 http://spreadsheetlight.com/downloads/SpreadsheetLight3.5.zip

  2. 创建了一个名为“SpreadsheetLight”的 .NET Core 库项目,并向其中添加了必要的 NuGet 包(DocumentFormat.OpenXML 和 System.Drawing.Common)。复制并粘贴本项目中所有下载的源代码文件。

  3. 将项目“SpreadsheetLight”添加到我的解决方案并在现有项目之一中引用它。

  4. 在“SLDocument.cs”文件中,对“LoadDocumentProperties()”方法进行以下更改,使代码如下所示:

    // XDocument xdoc = XDocument.Load(XmlReader.Create(xl.CoreFilePropertiesPart.GetStream()));

    流流=xl.CoreFilePropertiesPart.GetStream(); XDocument xdoc = XDocument.Load(XmlReader.Create(流));

    foreach(xdoc.Descendants() 中的 XElement xelem) { //代码省略。 }

    stream.Close();

  5. 构建您的解决方案并进行测试。

当我打开(通过 SpreadsheetLight)以“Excel 2007-365”格式保存(通过 LibreOffice Calc)的 .xlsx 文件时出现此错误,然后我尝试使用 SaveAs 函数。 当我(通过 LibreOffice Calc)将 .xlsx 文件保存为“Office Open XML”时,我可以毫无问题地打开并另存为(通过 SpreadsheetLight).xlsx 文件。