我试图写数据表到具有大量记录的excel。我正在尝试使用分而治之的策略,其中每个线程都被分配为写入到excelworkbook的相应工作表中。
class Program
{
int processorCount = 2;
static volatile bool processing = true;
DataTable employeeTable = new DataTable("Employee");
ManualResetEvent mre = new ManualResetEvent(false);
AutoResetEvent ar = new AutoResetEvent(true);
int record_count;
static void Main(string[] args)
{
Program p = new Program();
//Create an Emplyee DataTable
p.employeeTable.Columns.Add("Employee ID");
p.employeeTable.Columns.Add("Employee Name");
for (int i = 0; i <= 2; i++)
{
p.employeeTable.Rows.Add(i.ToString(), "ABC");
}
p.record_count = p.employeeTable.Rows.Count / p.processorCount;
Excel.Application excelApp = new Excel.Application();
//Create an Excel workbook instance and open it from the predefined location
Excel.Workbook excelWorkBook1 = excelApp.Workbooks.Open(@"F:\Org.xlsx");
Thread[] threads = new Thread[3];
for (int i = 0; i < 3; i++)
{
// p.ExportDataSetToExcel(i);
ParameterizedThreadStart ps = new ParameterizedThreadStart(p.ExportDataSetToExcel);
threads[i] = new Thread(ps);
threads[i].Start(new Custom() { sheetNo = i, excelWorkBook = excelWorkBook1 });
}
for (int j = 0; j < 3; j++)
{
threads[j].Join();
}
Console.WriteLine("Succeess");
Console.ReadKey();
}
private void ExportDataSetToExcel(object sheet1)
{
lock (this)
{
bool found = false;
Excel.Worksheet excelWorkSheet;
int sheetNo = ((Custom)sheet1).sheetNo;
Excel.Workbook excelWorkBook = ((Custom)sheet1).excelWorkBook;
excelWorkSheet = (excelWorkBook).Sheets["Sheet" + ((int)sheetNo + 1).ToString()];
for (int i = 1; i < employeeTable.Columns.Count + 1; i++)
{
excelWorkSheet.Cells[1, i] = employeeTable.Columns[i - 1].ColumnName;
}
int baseIndex = (int)sheetNo * record_count;
for (int j = baseIndex; j < baseIndex + record_count; j++)
{
for (int k = 0; k < employeeTable.Columns.Count; k++)
{
excelWorkSheet.Cells[j + 2, k + 1] = employeeTable.Rows[j].ItemArray[k].ToString();
}
}
Console.WriteLine(sheetNo.ToString());
Console.WriteLine("\n");
(excelWorkBook).Save();
(excelWorkBook).Close();
}
}
}**strong text**
public class Custom
{
public int sheetNo;
public Excel.Workbook excelWorkBook;
}
最佳答案:
可以使用EPPlus,NPOI之类的库,也可以直接使用Open XML SDK来创建Excel文件,而不是通过OLE或VSTO使用互操作。
互操作会迫使您在单个线程上工作,并且您始终要支付CPU互操作成本,浪费的CPU和内存来运行Excel,最后还要付出CPU和IO来保存文件。
另一方面,Open XML SDK和其他库甚至不需要Excel。所有操作都在内存中,您只需支付CPU和IO成本来保存文件。结果,它们快了几个数量级
因此,您可以在无法使用Interop和VSTO的Web和服务器应用程序中使用它们
EPPlus具有一些不错的功能,例如从DataTable(LoadFromDataTable)或LINQ查询(LoadFromCollection)创建Excel表,这使得导出数据非常容易,例如:
using (var excelFile = new ExcelPackage(targetFile))
{
var worksheet = excelFile.Workbook.Worksheets.Add("Sheet1");
var tableRange=worksheet.Cells["A1"].LoadFromCollection(employees, true);
excelFile.Save();
}
更新
我只是在评论中读到,OP希望导出大量行,并认为Excel有一定的限制。事实并非如此,但开始时的情况完全不同。
自2010年以来,Excel对行数没有任何限制。只要一台计算机具有足够的内存,它就可以通过PowerPivot / PowerQuery处理多个源,每个源都有几百万行。在2010年,文件大小被人为限制为2GB(以适应SharePoint),但我认为该大小限制在2013年被删除。这是一个很大的大小,因为PowerPivot使用与Analysis Services相同的列压缩。
在这种情况下,最好的选择是创建具有PowerPivot连接的Excel文件,将其提供给用户,并让他们在需要时刷新数据。
不幸的是,这是Excel的功能,而不是文件格式。这意味着您不能使用SDK创建具有列压缩数据的文件,而不得不再次使用interop / VSTO。不过,在这种情况下,将由Excel来完成对数据进行拉取和压缩的繁重工作。