C#以编程方式将Excel文件填充到公式中需要很长时间

时间:2018-11-21 21:15:22

标签: c# excel office-interop

我正在使用 c#,VS2013和excel interop 动态生成一个excel文件,其中列数不为150,行数为4000。我的问题是,由于我要插入,因此需要很长时间Excel单元格中有很多公式。

我的请求请查看我的代码,并给我最好的建议,如何使用 = SUM(A1:A2)这样的公式来最大程度地缩短excel文件的创建时间。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using Excel;


        private void button1_Click(object sender, EventArgs e)
        {
            string strSum = "", strColName, strImmediateOneUp = "", strImmediateTwoUp = "";

            int NumRows = 4000;
            int NumColumns = 150;

            int startsum = 0;
            int currow = 0;
            bool firstTimeSum = true;

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            Excel.Application xlApp;
            Excel.Workbook xlWorkBook;
            Excel.Worksheet xlWorkSheet = null;

            object misValue = System.Reflection.Missing.Value;

            xlApp = new Excel.Application();
            xlWorkBook = xlApp.Workbooks.Add(misValue);

            xlWorkBook = xlApp.Workbooks.Add(misValue);
            xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);


            for (int row = 0; row < NumRows; row++)
            {
                for (int col = 0; col < NumColumns; col++)
                {
                    if (row < 2)
                    {
                        xlWorkSheet.Cells[row+1, col+1] = new Random().Next(1, NumRows).ToString();
                    }
                    else
                    {
                        if (firstTimeSum)
                        {
                            if (row - currow == 2)
                            {
                                currow = row;
                                startsum = 0;
                                firstTimeSum = false;
                            }
                            else
                            {
                                startsum = 1;
                            }
                        }
                        else
                        {
                            if (row - currow == 3)
                            {
                                currow = row;
                                startsum = 0;
                            }
                        }


                        if (startsum == 0)
                        {
                            strColName = GenerateColumnText(col);
                            strImmediateOneUp = strColName + ((row + 1) - 1).ToString();
                            strImmediateTwoUp = strColName + ((row + 1) - 2).ToString();
                            strSum = string.Format("=SUM({0}:{1})", strImmediateTwoUp, strImmediateOneUp);
                            xlWorkSheet.Cells[row+1, col+1] = strSum;
                        }
                        else
                        {
                            xlWorkSheet.Cells[row + 1, col + 1] = new Random().Next(1, NumRows).ToString();
                        }
                    }

                }

                startsum = 1;
            }

            if (System.IO.File.Exists(@"d:\pop.xls"))
            {
                System.IO.File.Delete(@"d:\pop.xls");
            }

            xlWorkBook.SaveAs(@"d:\pop.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue,
                misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);

            xlWorkBook.Close(true, misValue, misValue);
            xlApp.Quit();

            releaseObject(xlWorkSheet);
            releaseObject(xlWorkBook);
            releaseObject(xlApp);
            xlApp = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();

            stopwatch.Stop();
            TimeSpan timeSpan = stopwatch.Elapsed;

            MessageBox.Show(string.Format("Time elapsed: {0}h {1}m {2}s {3}ms", timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds, timeSpan.Milliseconds));

        }

        private void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch
            {
                obj = null;
                //MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
            }
        }

        private string GenerateColumnText(int num)
        {
            string str = "";
            char achar;
            int mod;
            while (true)
            {
                mod = (num % 26) + 65;
                num = (int)(num / 26);
                achar = (char)mod;
                str = achar + str;
                if (num > 0) num--;
                else if (num == 0) break;
            }
            return str;
        }

寻找最佳指南。谢谢

1 个答案:

答案 0 :(得分:3)

互操作会很慢。但是,您可以通过为范围分配相同的公式来减少通话次数:

// not sure what the 140th column is, just replace `??` by it
xlWorkSheet.Range["A3:??4000"].FormulaR1C1 = "=SUM(R[-2]C:R[-1]C)";

或者,它也可以工作:

xlWorkSheet
    .Range[3, 1].Resize[4000 - 2, 140]
    .FormulaR1C1 = "=SUM(R[-2]C:R[-1]C)";