【问题标题】:Faster creation of Excel (Interop)更快地创建 Excel(互操作)
【发布时间】:2018-08-09 06:29:34
【问题描述】:

我将减慢进程的代码确定为以下代码(我正在填充单元格):

我在这里所做的基本上是使用 DataSet 从数据库中加载一些数据。

Microsoft.Office.Interop.Excel.Range range1 = null;
Microsoft.Office.Interop.Excel.Range cell1 = null;
Microsoft.Office.Interop.Excel.Borders border1 = null;

for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
    int s = i + 1;
    for (j = 0; j <= ds.Tables[0].Columns.Count - 1; j++)
    {
        data = ds.Tables[0].Rows[i].ItemArray[j].ToString();
        xlWorkSheet.Cells[s + 1, j + 1] = data;

        range1 = xlWorkSheet.UsedRange;
        cell1 = range1.Cells[s + 1, j + 1];
        border1 = cell1.Borders;


        if (((IList)terms).Contains(xlWorkSheet.Cells[1, j + 1].Value.ToString()))
        {
            cell1.Interior.Color = System.Drawing.Color.Red;
        }

        range1.Columns.AutoFit();
        range1.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;

        border1.LineStyle = Microsoft.Office.Interop.Excel.XlLineStyle.xlContinuous;
        border1.Weight = 2d;

    }
}

加载整个内容有时需要超过 1 分钟。有没有可以优化的地方?

【问题讨论】:

  • 你有没有试过移动代码:range1.Columns.AutoFit(); range1.Horizo​​ntalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;到两个 for 循环之外?
  • 逐个单元格是使用互操作与 Excel 交互的最慢的方式 - 了解如何在一个操作中将数据从数组添加到工作表。例如。 stackoverflow.com/questions/536636/write-array-to-excel-range
  • Lucian 有一个很好的观点,您将所有单元格格式化为创建一个范围并在该范围内进行格式化。你甚至可以为你的边界做这件事。所以在循环之前做所有常见的格式化,然后在你需要的高亮中覆盖。
  • @Lucian 这让它快了 10 秒。谢谢!我正在研究 TimWilliams 的建议,我相信这是关键。
  • @TimWilliams 随意将其发布为答案,以便我标记它。它奏效了。

标签: c# excel


【解决方案1】:

逐个单元格是使用 Interop 与 Excel 交互的最慢的方式 - 了解如何在一次操作中将数据从数组添加到工作表。

例如

Write Array to Excel Range

展示了这种方法。

【讨论】:

    【解决方案2】:

    互操作库速度极慢,而且耗费大量系统资源。

    您可以简单地使用 OpenXML 库,而不是使用 Interop Libraries 创建 Excel 文件。 我在生产中使用它。超过 100 万行,将数据集导出到 excel 文件只需大约 10 秒。

    下面是引用的示例代码:

    Export DataTable to Excel with Open Xml SDK in c#

    private void ExportDSToExcel(DataSet ds, string destination)
    {
        using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
        {
            var workbookPart = workbook.AddWorkbookPart();
            workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
            workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();
    
            uint sheetId = 1;
    
            foreach (DataTable table in ds.Tables)
            {
                var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
                var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
                sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);                
    
                DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
                string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
    
                if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
                {
                    sheetId =
                        sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
                }
    
                DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName };
                sheets.Append(sheet);
    
                DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
    
                List<String> columns = new List<string>();
                foreach (DataColumn column in table.Columns)
                {
                    columns.Add(column.ColumnName);
    
                    DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                    cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
                    cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
                    headerRow.AppendChild(cell);
                }
    
                sheetData.AppendChild(headerRow);
    
                foreach (DataRow dsrow in table.Rows)
                {
                    DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
                    foreach (String col in columns)
                    {
                        DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                        cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
                        cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
                        newRow.AppendChild(cell);
                    }
    
                    sheetData.AppendChild(newRow);
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 2018-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多