C# 将 List<object> 粘贴到 Excel 列而不循环
C# Paste List<object> into Excel column withou looping
我有一些代码可以从应用程序 运行 收集问题,我想创建一份关于问题的报告。不幸的是,使用 Intertop
会使此导出变得很长 运行。
//loop results
int i = 2;
foreach (EntryIssue entryIssue in DuplicatesList)
{
xlWorkSheet.Cells[i, 1] = entryIssue.dataString;
xlWorkSheet.Cells[i, 2] = entryIssue.fileLine;
xlWorkSheet.Cells[i, 3] = entryIssue.fileName;
i++;
}
创建了另外三个工作表和另外三个用代码填充它们的列表,但它们的工作方式相似。
有没有办法避免列表的迭代并将列表的结果粘贴到特定范围内?
我认为这可以节省一些时间,或者我应该使用 Intertop
以外的其他库吗?
编辑:
好的,
我找到了一个解决方案,虽然它似乎只适用于二维数组,但一维数组似乎有问题,因为它只根据数组中的第一条记录分配记录。我不确定如何解决这个问题。
我最初的想法是用Linq
粘贴
一维数组(不起作用):
xlRange = xlWorkSheet.get_Range((object)xlWorkSheet.Cells[2, 1], (object)xlWorkSheet.Cells[DuplicatesList.Count + 1, 1]);
var getArray = DuplicatesList.Select(r => r.dataString).ToArray();
xlRange.Value = getArray;
xlRange = xlWorkSheet.get_Range((object)xlWorkSheet.Cells[2, 2], (object)xlWorkSheet.Cells[DuplicatesList.Count + 1, 2]);
getArray = DuplicatesList.Select(r => r.fileLine).ToArray();
xlRange.Value = getArray;
xlRange = xlWorkSheet.get_Range((object)xlWorkSheet.Cells[2, 3], (object)xlWorkSheet.Cells[DuplicatesList.Count + 1, 3]);
getArray = DuplicatesList.Select(r => r.fileName).ToArray();
xlRange.Value = getArray;
然后我决定将列表元素迭代到数组中,因为我不知道您是否可以从对象列表分配到多维数组。
在一个包含 22 万个项目的文件上,它从 10 分钟以上减少到大约 2-3 秒。
二维数组(有效)
//set range
xlRange = xlWorkSheet.get_Range((object)xlWorkSheet.Cells[2, 1], (object)xlWorkSheet.Cells[DuplicatesList.Count + 1, 3]);
//fill array
int i = 0;
object[,] getArray = new object[DuplicatesList.Count, 3];
foreach (EntryIssue entryIssue in DuplicatesList)
{
getArray[i, 0] = entryIssue.dataString;
getArray[i, 1] = entryIssue.fileLine;
getArray[i, 2] = entryIssue.fileName;
i++;
}
//assign array to range
xlRange.Value = getArray;
稍后我将清除 Marshall
ips.Marshal.ReleaseComObject(xlRange);
ips.Marshal.ReleaseComObject(xlWorkSheet);
ips.Marshal.ReleaseComObject(xlWorkBook);
ips.Marshal.ReleaseComObject(xlApp);
Nuget 的 Epplus 将是一个简单的解决方案。即:
void Main()
{
var r = new Random();
var data = new List<MyData>();
for (int i = 0; i < 100000; i++)
{
data.Add(new MyData { DataString = $"Data {i}", FileLine = r.Next(1, 1000), FileName = $"File #{i}" });
}
Stopwatch sw = new Stopwatch();
sw.Start();
ExcelPackage pck = new ExcelPackage();
var ws = pck.Workbook.Worksheets.Add("FromAnonymous");
//Load the collection starting from cell A1...
ws.Cells["A1"].LoadFromCollection(data, true, TableStyles.Medium9);
ws.Cells[ws.Dimension.Address].AutoFitColumns();
//...and save
var fi = new FileInfo(@"c:\temp\AnonymousCollection.xlsx");
if (fi.Exists)
{
fi.Delete();
}
pck.SaveAs(fi);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
public class MyData
{
public string DataString { get; set; }
public int FileLine { get; set; }
public string FileName { get; set; }
}
我有一些代码可以从应用程序 运行 收集问题,我想创建一份关于问题的报告。不幸的是,使用 Intertop
会使此导出变得很长 运行。
//loop results
int i = 2;
foreach (EntryIssue entryIssue in DuplicatesList)
{
xlWorkSheet.Cells[i, 1] = entryIssue.dataString;
xlWorkSheet.Cells[i, 2] = entryIssue.fileLine;
xlWorkSheet.Cells[i, 3] = entryIssue.fileName;
i++;
}
创建了另外三个工作表和另外三个用代码填充它们的列表,但它们的工作方式相似。
有没有办法避免列表的迭代并将列表的结果粘贴到特定范围内?
我认为这可以节省一些时间,或者我应该使用 Intertop
以外的其他库吗?
编辑:
好的, 我找到了一个解决方案,虽然它似乎只适用于二维数组,但一维数组似乎有问题,因为它只根据数组中的第一条记录分配记录。我不确定如何解决这个问题。
我最初的想法是用Linq
一维数组(不起作用):
xlRange = xlWorkSheet.get_Range((object)xlWorkSheet.Cells[2, 1], (object)xlWorkSheet.Cells[DuplicatesList.Count + 1, 1]);
var getArray = DuplicatesList.Select(r => r.dataString).ToArray();
xlRange.Value = getArray;
xlRange = xlWorkSheet.get_Range((object)xlWorkSheet.Cells[2, 2], (object)xlWorkSheet.Cells[DuplicatesList.Count + 1, 2]);
getArray = DuplicatesList.Select(r => r.fileLine).ToArray();
xlRange.Value = getArray;
xlRange = xlWorkSheet.get_Range((object)xlWorkSheet.Cells[2, 3], (object)xlWorkSheet.Cells[DuplicatesList.Count + 1, 3]);
getArray = DuplicatesList.Select(r => r.fileName).ToArray();
xlRange.Value = getArray;
然后我决定将列表元素迭代到数组中,因为我不知道您是否可以从对象列表分配到多维数组。 在一个包含 22 万个项目的文件上,它从 10 分钟以上减少到大约 2-3 秒。
二维数组(有效)
//set range
xlRange = xlWorkSheet.get_Range((object)xlWorkSheet.Cells[2, 1], (object)xlWorkSheet.Cells[DuplicatesList.Count + 1, 3]);
//fill array
int i = 0;
object[,] getArray = new object[DuplicatesList.Count, 3];
foreach (EntryIssue entryIssue in DuplicatesList)
{
getArray[i, 0] = entryIssue.dataString;
getArray[i, 1] = entryIssue.fileLine;
getArray[i, 2] = entryIssue.fileName;
i++;
}
//assign array to range
xlRange.Value = getArray;
稍后我将清除 Marshall
ips.Marshal.ReleaseComObject(xlRange);
ips.Marshal.ReleaseComObject(xlWorkSheet);
ips.Marshal.ReleaseComObject(xlWorkBook);
ips.Marshal.ReleaseComObject(xlApp);
Nuget 的 Epplus 将是一个简单的解决方案。即:
void Main()
{
var r = new Random();
var data = new List<MyData>();
for (int i = 0; i < 100000; i++)
{
data.Add(new MyData { DataString = $"Data {i}", FileLine = r.Next(1, 1000), FileName = $"File #{i}" });
}
Stopwatch sw = new Stopwatch();
sw.Start();
ExcelPackage pck = new ExcelPackage();
var ws = pck.Workbook.Worksheets.Add("FromAnonymous");
//Load the collection starting from cell A1...
ws.Cells["A1"].LoadFromCollection(data, true, TableStyles.Medium9);
ws.Cells[ws.Dimension.Address].AutoFitColumns();
//...and save
var fi = new FileInfo(@"c:\temp\AnonymousCollection.xlsx");
if (fi.Exists)
{
fi.Delete();
}
pck.SaveAs(fi);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
public class MyData
{
public string DataString { get; set; }
public int FileLine { get; set; }
public string FileName { get; set; }
}