我试图写数据表到具有大量记录的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来完成对数据进行拉取和压缩的繁重工作。