SQL reader在创建excel文件时需要花费大量时间

时间:2017-01-10 00:42:34

标签: c# sql excel

我现在陷入了一个耗时的过程。我正在使用C#创建一个excel文件,我在SQL中有一个存储过程,大约需要2-3分钟才能执行并返回90K行的结果集。但是当我尝试在C#中执行该过程并在while循环中读取数据时,我花了30分钟来创建一个excel文件。这是我的代码

string gpn = cmbGPN.SelectedItem.ToString();
            string MRR_Query = " exec sp_MRR_Retention '"+Yr+"','"+Mn+"'";

            int xlCol, xlRow, xlMin, xlMax;

            reader = func.getReader(MRR_Query);

            object typeMissing = Type.Missing;
            Excel._Application app = new Excel.Application();
            Excel.Workbook workbook = app.Workbooks.Add(typeMissing);
            Excel.Worksheet sheet = (Excel.Worksheet)workbook.Worksheets.get_Item(1);
            object misValue = System.Reflection.Missing.Value;
            sheet.Name = "MRR Retention";

            app.ActiveWindow.Zoom = 80;
            sheet.Application.ActiveWindow.SplitRow = 1;
            sheet.Application.ActiveWindow.FreezePanes = true;

            // Column name for raw data sheet
            sheet.Cells[1, 1] = "Month";
            sheet.Cells[1, 2] = "Parent_Name";
            sheet.Cells[1, 3] = "Customer_Name";
            sheet.Cells[1, 4] = "Customer_Account_No";
            sheet.Cells[1, 5] = "Item_Category";
            sheet.Cells[1, 6] = "Item_Description_Summary";
            sheet.Cells[1, 7] = "Item_Number";
            sheet.Cells[1, 8] = "Date_Range";
            sheet.Cells[1, 9] = "Activity_Type";
            sheet.Cells[1, 10] = "Line_Type";
            sheet.Cells[1, 11] = "IBX_Code";
            sheet.Cells[1, 12] = "IBX_Country";
            sheet.Cells[1, 13] = "Primary_Sales_Rep";
            sheet.Cells[1, 14] = "MRC_Amount_USD_Budget_Rate";
            sheet.Cells[1, 15] = "Entered_Currency_Code";
            sheet.Cells[1, 16] = "MRC_Amount_LC";
            sheet.Cells[1, 17] = "UCM_ID";
            sheet.Cells[1, 18] = "GAM_TAG";
            sheet.Cells[1, 19] = "Client_Services_Manager";
            sheet.Cells[1, 20] = "Sales_Program_Type";
            sheet.Cells[1, 21] = "SFDC_Account_ID";
            sheet.Cells[1, 22] = "Account_Owner";

            sheet.Range["A1:W1"].Borders.Color = Color.Black;
            sheet.Range["A1:W1"].ColumnWidth = 12;
            sheet.Range["A1:W1"].Interior.Color = Color.YellowGreen;
            sheet.Range["A1:W1"].Font.Color = Color.Black;
            sheet.Range["A1:W1"].Font.Bold = true;
            sheet.Range["A1:W1"].EntireRow.AutoFit();


            int row = 2;

            while (reader.Read())
            {
                sheet.Cells[row, 1] = reader.GetValue(0);
                sheet.Cells[row, 2] = reader.GetValue(1);
                sheet.Cells[row, 3] = reader.GetValue(2);
                sheet.Cells[row, 4] = reader.GetValue(3);
                sheet.Cells[row, 5] = reader.GetValue(4);
                sheet.Cells[row, 6] = reader.GetValue(5);
                sheet.Cells[row, 7] = reader.GetValue(6);
                sheet.Cells[row, 8] = reader.GetValue(7);
                sheet.Cells[row, 9] = reader.GetValue(8);
                sheet.Cells[row, 10] = reader.GetValue(9);
                sheet.Cells[row, 11] = reader.GetValue(10);
                sheet.Cells[row, 12] = reader.GetValue(11);
                sheet.Cells[row, 13] = reader.GetValue(12);
                sheet.Cells[row, 14] = reader.GetValue(13);
                sheet.Cells[row, 15] = reader.GetValue(14);
                sheet.Cells[row, 16] = reader.GetValue(15);
                sheet.Cells[row, 17] = reader.GetValue(16);
                sheet.Cells[row, 18] = reader.GetValue(17);
                sheet.Cells[row, 19] = reader.GetValue(18);
                sheet.Cells[row, 20] = reader.GetValue(19);
                sheet.Cells[row, 21] = reader.GetValue(20);
                sheet.Cells[row, 22] = reader.GetValue(21);

                row = row + 1;
            }

            reader.Close();                                                                             //closing the reader and nullify if any recordset is remaining 
            func.CloseCon();

            workbook.SaveAs("D:\\MRR_Retention_Auto.xlsx", typeMissing, typeMissing, typeMissing, typeMissing, typeMissing, Excel.XlSaveAsAccessMode.xlExclusive, typeMissing, typeMissing, typeMissing, typeMissing, typeMissing);
            workbook.Close(true, typeMissing, typeMissing);
            app.Quit();

任何人都可以请注意这件事并告诉我如何快速完成这个过程。如果我使用SQL数据适配器代替它会快吗?期待建议和答案。

1 个答案:

答案 0 :(得分:1)

如果你真的想要速度(和紧凑的代码),让Excel为你做所有繁重的工作并使用Microsoft Query(内置于Excel中)而不是手动执行此操作。以下是如何进行查询并将其转换为链接到MS Query的Excel表的示例:

string sql = "select * from foo";
string source = "your connection string here";

Excel.ListObject lo = sheet.ListObjects.AddEx(Excel.XlListObjectSourceType.xlSrcQuery,
    source, true, Excel.XlYesNoGuess.xlGuess, range);

try
{
    lo.QueryTable.CommandText = sql;
    lo.Refresh();
}
catch (Exception ex)
{
    ErrorMessage = ex.ToString();
}

range将是一个Excel Range对象,其中包含您想要输出的左上角单元格的目标。

如果您不知道连接字符串是什么样的,那么分解它的最佳方法是通过Excel生成查询,然后进入查询属性,复制并粘贴连接字符串文本。

此外,如果您的连接是ODBC,则说"DNS=<dns name>;"就足够了,Excel将从ODBC属性中提取所有连接属性。