数据表直接到Excel C#

时间:2017-01-17 19:00:02

标签: c# sql excel

我运行一个我要在Excel模板上转储的存储过程。

它目前有效,但只是花了太长时间。在SQL Server Management Studio中,查询运行正常,但是当我只是写入模板时,它真的很慢。

有人能建议一种更有效的方法来达到同样的效果吗?

以下是我的代码的一部分:

sdate = StartDate.Value.ToString();
edate = EndDate.Value.ToString();

Excel.Application oXL;
Excel._Workbook oWB;
Excel._Worksheet aSheet;

try
{
//Start Excel and get Application object.
oXL = new Excel.Application();
oXL.Visible = true;

//open the excel template
oWB = oXL.Workbooks.Open("C:\\TEMP\\template.xlsm");

//oWB = (Excel._Workbook)(oXL.Workbooks.Add(Missing.Value));

//Call to service
//aSheet = (Excel._Worksheet)oWB.Worksheets.get_Item(1);
aSheet = (Excel._Worksheet)oWB.ActiveSheet;
//backgroundWorker1.ReportProgress(i++);
writedata_from_proc(aSheet, "dbo.CODE_RED_2017");
//backgroundWorker1.ReportProgress(i++);


 //Make sure Excel is visible and give the user control
//of Microsoft Excel's lifetime.
//backgroundWorker1.ReportProgress(i++);
MessageBox.Show("Data extraction complete");
oXL.Visible = true;
oXL.UserControl = true;
//SaveExcel(oWB);

//clean up the COM objects to remove them from the memory
Marshal.FinalReleaseComObject(aSheet);
Marshal.FinalReleaseComObject(oWB);
Marshal.FinalReleaseComObject(oXL);
}
catch (Exception theException)
{
String errorMessage;
errorMessage = "Error: ";
errorMessage = String.Concat(errorMessage, theException.Message);
errorMessage = String.Concat(errorMessage, " Line: ");
errorMessage = String.Concat(errorMessage, theException.Source);

MessageBox.Show(errorMessage, "Error");
}
    }

以下是我最初错过的代码:

public void writedata_from_proc(Excel._Worksheet oWS,string sentproc)
        {
            int rowCount = 0;
            SqlCommand cmd = new SqlCommand(sentproc.ToString());
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@start_date", SqlDbType.DateTime).Value = getsdate();
            cmd.Parameters.Add("@end_date",SqlDbType.DateTime).Value=getedate();
            cmd.CommandTimeout = 0;

            DataTable dt = GetData(cmd);
            oWS.UsedRange.Rows.Count.ToString();
            if (sentproc.Contains("CODE_RED"))
            {
               rowCount = 1;
            }
            else
            {
                rowCount = oWS.UsedRange.Rows.Count;
        }
        foreach (DataRow dr in dt.Rows)
        {
            rowCount += 1;
            for (int i = 1; i < dt.Columns.Count + 1; i++)
            {
                // Add the header the first time through 
                if (rowCount == 2)
                {
                    oWS.Cells[1, i] = dt.Columns[i - 1].ColumnName;
                }
                oWS.Cells[rowCount, i] = dr[i - 1];
            }
        }

    }

1 个答案:

答案 0 :(得分:1)

Excel已经有一个内置工具,可以完成此操作,并且不会超过运行查询并获取结果所需的时间。它叫做MS Query。简而言之,你会:

  1. 转到Excel功能区的“数据”标签
  2. 选择“获取外部数据”(功能区组) - &gt; “来自其他来源” - &gt; “来自SQL Server。”我假设这是SQL Server。根据您的语法,它可能是Sybase,在这种情况下,您仍然可以通过ODBC(SQL Server下面的一些选项)执行此操作。
  3. 绕过所有设计师,您将进入MS查询窗口。从这里,您可以直接编辑SQL并输入您的SQL - exec dbo.CODE_RED_2017
  4. 当您关闭MS Query时,它会询问您要将数据放在何处。选一个单元格。
  5. 最重要的是,当需要刷新时,右键单击表并选择“刷新”,它将重新执行您的过程(或查询)。根据我的经验,Excel实际上比大多数数据库浏览器提供的数据更快

    这是一个包含更多详细信息的Microsoft链接:

    https://support.office.com/en-us/article/Use-Microsoft-Query-to-retrieve-external-data-42a2ea18-44d9-40b3-9c38-4c62f252da2e?ui=en-US&rs=en-US&ad=US&fromAR=1

    所以,你根本不需要C#。也就是说,如果你通过C#以某种方式自动化这个,那么这也可以这样做。这是一个例子:

    string sql = "exec dbo.CODE_RED_2017";
    string source = "your connection string here";
    Excel.Range r = activeSheet.Range["A1"];
    
    Excel.ListObject lo = sheet.ListObjects.AddEx(Excel.XlListObjectSourceType.xlSrcQuery,
        source, true, Excel.XlYesNoGuess.xlGuess, r);
    
    lo.QueryTable.CommandText = sql;
    lo.Refresh();