用多个线程写入excel文件

我正在尝试写入数据表到excel有大record.I试图实现使用分而治之,每个线程被分配写入各自excelworkbook.but但我越来越文件是只读,单击确定以覆盖文件。

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; } 

不要通过OLE或VSTO使用interop,而应使用EPPlus , NPOI等库或直接使用Open XML SDK创buildExcel文件。

Interop强制您在单个线程上工作,并且始终支付CPU互操作成本,浪费的CPU和内存以运行Excel,最后还要CPU和IO来保存文件。

另一方面,Open XML SDK和其他库甚至不需要Excel。 所有操作都在内存中,您只需支付CPU和IO成本即可保存文件。 结果他们快了几个数量级

因此,您可以在使用Interop和VSTO的Web和服务器应用程序中使用它们

EPPlus具有一些很好的function,比如从DataTable(LoadFromDataTable)或LINQ查询(LoadFromCollection)创buildExcel表格,这使得导出数据非常简单,例如:

 using (var excelFile = new ExcelPackage(targetFile)) { var worksheet = excelFile.Workbook.Worksheets.Add("Sheet1"); var tableRange=worksheet.Cells["A1"].LoadFromCollection(employees, true); excelFile.Save(); } 

UPDATE

我刚刚在一个评论中看到,OP想要导出大量的行,并认为Excel有一些限制。 这是不正确的,但情况是完全不同的开始。

Excel对2010年以来的行数没有任何限制。只要一台机器有足够的内存,它就可以通过PowerPivot / PowerQuery处理多个数据行,每行数百万行。 在2010年,文件大小上有2GB的人为限制(为了适应SharePoint),但我认为这在2013年被删除。这是一个巨大的规模,因为PowerPivot使用与Analysis Services相同的列压缩。

在这种情况下,最好的select是创build一个带有PowerPivot连接的Excel文件,将其提供给用户,并让他们随时刷新数据。

不幸的是,这是Excel的一个function,而不是文件格式。 这意味着您不能使用SDK创build具有列压缩数据的文件,但必须再次使用interop / VSTO。 在这种情况下,Excel是一个很大的提升和压缩数据的工具。

不幸的是,Excel不是devise成multithreading的。 但是我推荐的是你写的写得更有效。 逐个单元格写入是减速的最大部分。

消除这两个因素(组织数据并写入数据)会将实际写入时间减less到可能无需同时写入的时间。

我有一个旧的VSTO项目,我必须从数据库中写入数据集,然后将数据提取到一个二维数组中,然后将整个数组写入表单中的一个区域,如下所示:

 Microsoft.Office.Tools.Excel.Worksheet TheSheet; private void PublishToSheet( int totalRows, int maxColumns, ref string[,] OutputArray ) { Excel.Range Range = TheSheet.Range["A1", TheSheet.Cells[totalRows, maxColumns]]; Range.NumberFormat = "@"; Range.Value2 = OutputArray; LastRow = totalRows; LastColumn = maxColumns; }