在Excel中使用C#closures的XML合并列的性能

我有一个列表,它包含9多个属性,它包含一个子列表。

例如

Public Class BaseClass { public string Item1 { get; set; } public string Item2 { get; set; } public List<ChildClass> Item3 { get; set; } ............ } Public Class ChildClass { public string Item1 { get; set; } public string Item2 { get; set; } public string Item3 { get; set; } } 

我编程将集合转换为Excel文件与列分组。 在我的实际原始列表中,我有超过3000个项目,每个项目都有一个儿童列表,计数为4到6.对于迭代收集需要超过20分钟的1500个collections

示例Excel工作表的快照:

在这里输入图像描述

请参考下面的示例代码,它会生成虚拟数据的Excel

我正在使用ClosedXML – 请从NuGet获取参考

 using ClosedXML.Excel; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; class Program { static void Main(string[] args) { Program obj = new Program(); obj.GenerateData(); } public void GenerateData() { XLWorkbook xlWorkBook = new XLWorkbook(); IXLWorksheet xlWorkSheet = xlWorkBook.Worksheets.Add("SearchResults"); Stopwatch stopwatch = new Stopwatch(); List<TimeSpan> timeElapsedList = new List<TimeSpan>(); Console.WriteLine("Excel Generation Started..."); stopwatch.Start(); int counter = 0; int length = 1500; int rowCount = 1; for (int i = 0; i < length; i++) { Stopwatch loopstopwatch = new Stopwatch(); loopstopwatch.Start(); counter++; #region Loop Statements Start int rowHeight = 5; int minHt = rowCount; int maxHt = rowCount + rowHeight - 1; xlWorkSheet.Cell(rowCount, 1).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 1).Value = "Row " + i + " - Item 1"; xlWorkSheet.Cell(rowCount, 1).Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; xlWorkSheet.Range("A" + minHt.ToString() + ":A" + maxHt).Column(1).Merge(); xlWorkSheet.Cell(rowCount, 2).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 2).Value = "Row " + i + " - Item 2"; xlWorkSheet.Cell(rowCount, 2).Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; xlWorkSheet.Range("B" + minHt.ToString() + ":B" + maxHt).Column(1).Merge(); xlWorkSheet.Cell(rowCount, 3).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 3).Value = "Row " + i + " - Item 3"; xlWorkSheet.Cell(rowCount, 3).Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; xlWorkSheet.Range("C" + minHt.ToString() + ":C" + maxHt).Column(1).Merge(); xlWorkSheet.Cell(rowCount, 4).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 4).Value = "Row " + i + " - Item 4"; xlWorkSheet.Cell(rowCount, 4).Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; xlWorkSheet.Range("D" + minHt.ToString() + ":D" + maxHt).Column(1).Merge(); xlWorkSheet.Cell(rowCount, 5).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 5).Value = "Row " + i + " - Item 5"; xlWorkSheet.Cell(rowCount, 5).Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; xlWorkSheet.Range("E" + minHt.ToString() + ":E" + maxHt).Column(1).Merge(); xlWorkSheet.Cell(rowCount, 6).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 6).Value = "Row " + i + " - Item 6"; xlWorkSheet.Cell(rowCount, 6).Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; xlWorkSheet.Range("F" + minHt.ToString() + ":F" + maxHt).Column(1).Merge(); xlWorkSheet.Cell(rowCount, 7).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 7).Value = "Row " + i + " - Item 7"; xlWorkSheet.Cell(rowCount, 7).Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; xlWorkSheet.Range("G" + minHt.ToString() + ":G" + maxHt).Column(1).Merge(); xlWorkSheet.Cell(rowCount, 8).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 8).Value = "Row " + i + " - Item 8"; xlWorkSheet.Cell(rowCount, 8).Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; xlWorkSheet.Range("H" + minHt.ToString() + ":H" + maxHt).Column(1).Merge(); for (int j = 0; j < rowHeight; j++) { xlWorkSheet.Cell(rowCount, 9).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 9).Value = "Row " + i + " | SubRow" + j + " - Sub Item 1"; xlWorkSheet.Cell(rowCount, 10).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 10).Value = "Row " + i + " | SubRow" + j + " - Sub Item 2"; xlWorkSheet.Cell(rowCount, 11).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 11).Value = "Row " + i + " | SubRow" + j + " - Sub Item 3"; xlWorkSheet.Cell(rowCount, 12).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 12).Value = "Row " + i + " | SubRow" + j + " - Sub Item 4"; xlWorkSheet.Cell(rowCount, 13).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 13).Value = "Row " + i + " | SubRow" + j + " - Sub Item 5"; xlWorkSheet.Cell(rowCount, 14).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 14).Value = "Row " + i + " | SubRow" + j + " - Sub Item 6"; xlWorkSheet.Cell(rowCount, 15).WorksheetColumn().Width = 25; xlWorkSheet.Cell(rowCount, 15).Value = "Row " + i + " | SubRow" + j + " - Sub Item 7"; rowCount++; } xlWorkSheet.Cell(minHt, 16).WorksheetColumn().Width = 25; xlWorkSheet.Cell(minHt, 16).Value = "Row " + i + " - Item 9"; xlWorkSheet.Cell(minHt, 16).Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; xlWorkSheet.Range("P" + minHt.ToString() + ":P" + maxHt).Column(1).Merge(); #endregion loopstopwatch.Stop(); timeElapsedList.Add(loopstopwatch.Elapsed); Console.WriteLine("Iteration No: {0} - Time Taken {1}", counter, loopstopwatch.Elapsed); } stopwatch.Stop(); Console.WriteLine("Excel Construction Completed !"); Console.WriteLine("Total Time Taken to Complete {0}", stopwatch.Elapsed); Console.WriteLine("Minimum Time : {0}", timeElapsedList.Min()); Console.WriteLine("Maximum Time : {0}", timeElapsedList.Max()); } } 

请帮助我如何在时间pipe理方面优化与列合并的代码。

如果您确定您正在合并的范围不相交(这似乎是这种情况),则可以使用以下“ Merge重载获得更好的性能:

 IXLRange Merge(bool checkIntersect) 

并传递false (当前使用的无参数Merge重载传递true )作为checkIntersect 。 看起来像检查交集的ClosedXML实现具有O(N ^ 2)时间复杂度。

.Merge().Merge(false)replace所有的.Merge()调用,并且执行时间将接近没有合并的执行时间。

如果你需要合并单行的单元格 – 我用这个过程解决了它:

  1. 如果您需要将合并的单元格中的文本alignment到左侧,请将该值放到第一个单元格中 ,将该单元alignment到左侧并保留其他单元格为空

     cell = row.Cell(cellNumberFirst); cell.SetValue("value to write"); cell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Left; 

2.如果您需要将合并的单元格中的文本居中alignment – 将值设置为第一个单元格,并将合并的单元格范围设置为水平alignment到中心连续

 cell = row.Cell(cellNumberFirst); cell.SetValue("value to write"); sheet.Range(row.RowNumber(), cellNumberFirst, row.RowNumber(), cellNumberLast).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.CenterContinuous; 

3.如果您需要将合并的单元格中的文本右alignment – 将值放到最后一个单元格 ,将该单元格向右alignment,并保持其他单元格为空

 cell = row.Cell(cellNumberLast); cell.SetValue("value to write"); cell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Right; 

对于我来说,22500行和19列的SaveAs时间从2.5小时减less到15秒。