Over the years there have been a number of methods to move SQL data into Microsoft Excel.  Using Automation you can call methods and properties that are specific to excel which gives you the greatest flexibility for specifying the location of your data in the workbook.  The following are two recent approaches to export Sql Server table row data to an excel workbook. 

1.) Using Automation you can use transfer data cell by cell

2.) Transfer data in an array to a range of cells


I created a WPF application with a button "Export" for this code.  The click event creates performs the the following actions

a.) Gets a reference to the automation object
b.) Adds a default workbook
c.) Gets the list of tables within the database
d.) Gets data
e.) Exports the data to excel worksheets (there are 2 methods defined (1) range method (2) cell by cell
f.) Saves the excel sheet
g.) Clean up

 

This blog posts shows two ways to extract data from SQL Server and place into an Excel document. The Range method was much quicker than the cell by cell approach.  The code below gets a list of all tables within a particular SQL Database and exports the data to Excel. 

I didn’t use was Excel 2007 document format at this.  If you have a good post or web link using this technique I would happily reference.  Let me know if you would like the Visual Studio project.

private void btnExport_Click(object sender, RoutedEventArgs e) {
    lblMessage.Content="Export Started..";
 
    WpfApplication.DoEvents();
    ApplicationClass app = CreateExcelDocument(false);
 
    //add workbook to excel document
    Workbook workbook = app.Workbooks.Add(Type.Missing);
 
    DataSet ds = GetData(GetTableList());            
    
    //shown below are 2 method of moving data from sql to excel, only use one of them
    //(1)call method to export to worksheet using range functionality (much faster than cell by cell method
    Export(ds, ref workbook);
 
    //(2)cell by cell method
    //InsertIntoExcel(app, ds);
    
     string fileName = @"C:\Safety3.xlsx";
     SaveDoc(workbook, fileName);
     CloseExcelDocument(app);
     lblMessage.Content = "Finished..";
}

a.) Create Excel document

/// <summary>
/// creates excel document
/// </summary>
private ApplicationClass CreateExcelDocument(bool visible) {
    ApplicationClass app = null;
    try {
        app = new Microsoft.Office.Interop.Excel.ApplicationClass();
        app.Visible = visible;
 
    } catch (Exception ex) {
        MessageBox.Show(ex.ToString());
    }
    return app;
}


c.) The following method GetTableList() returns a List<ExportInfo> where ExportInfo is a structure that has the Name and SQL to be used for each table to be exported.

public class ExportInfo {
    public string Name { get; set; }
    public string Sql { get; set; }
}

/// <summary>
/// get list of sql tables in database
/// </summary>
/// <returns>list of ExportInfo objects</returns>
private List<ExportInfo> GetTableList() {
    System.Data.DataTable tables = new System.Data.DataTable("Tables");
    using (SqlConnection connection = new SqlConnection(GetConnectionString())) {
        
        SqlCommand command = connection.CreateCommand();
        command.CommandText = "select table_name as Name from INFORMATION_SCHEMA.tables where TABLE_TYPE = 'BASE TABLE'";
        connection.Open();
        tables.Load(command.ExecuteReader(CommandBehavior.CloseConnection));
        connection.Close();
    }
 
    List<ExportInfo> exps = new List<ExportInfo>();
    foreach (DataRow row in tables.Rows) {
        exps.Add(new ExportInfo(){Name=row[0].ToString(), Sql = String.Format("select top 1 * from {0}",row[0].ToString())});
    }
    return exps;            
}

d.) Gets Data by interating over collection of exportInfo’s to retrieve sql statements

/// <summary>
/// get data from sql server
/// </summary>
/// <param name="exps"></param>
/// <returns>dataset with return results</returns>
private System.Data.DataSet GetData(List<ExportInfo> exps) {
    DataSet ds = new DataSet();
    string executeSql = string.Empty;
    foreach (ExportInfo exp in exps) {
        executeSql += exp.Sql + ";";
    }
 
    string connectionString = GetConnectionString();
    SqlConnection conn = new SqlConnection(connectionString);
    SqlDataAdapter adapter = new SqlDataAdapter(executeSql, conn);
    try {
        adapter.Fill(ds);
    } catch (Exception ex) {
 
    }
 
    int index = 0;
    foreach (System.Data.DataTable dt in ds.Tables) {
        dt.TableName = exps[index].Name;
        index += 1;
    }
    return ds;
}

e.) Export using range (1)

/// <summary>
/// Copy data from dataset into workbook
/// </summary>
/// <param name="dataSet"></param>
/// <param name="excelWorkbook"></param>        
private void Export(DataSet dataSet, ref Workbook excelWorkbook) {
 
    int sheetIndex = 0;
 
    // build rawData 2 dimensional array with data for each datatable            
    foreach (System.Data.DataTable dt in dataSet.Tables) {
 
        // Copy the DataTable to an object array
        object[,] data = new object[dt.Rows.Count + 1, dt.Columns.Count];
 
        // Copy the column names to the first row of the object array
        for (int col = 0; col < dt.Columns.Count; col++) {
            data[0, col] = dt.Columns[col].ColumnName;
        }
 
        // Copy the values to the object array
        for (int col = 0; col < dt.Columns.Count; col++) {
            for (int row = 0; row < dt.Rows.Count; row++) {
                data[row + 1, col] = dt.Rows[row].ItemArray[col];
            }
        }
 
        // Calculate the final column letter
        string finalColLetter = string.Empty;
        string colCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        int colCharsetLen = colCharset.Length;
 
        if (dt.Columns.Count > colCharsetLen) {
            finalColLetter = colCharset.Substring(
                (dt.Columns.Count - 1) / colCharsetLen - 1, 1);
        }
 
        finalColLetter += colCharset.Substring(
                (dt.Columns.Count - 1) % colCharsetLen, 1);
 
        // Create a new Sheet
        Worksheet excelSheet = (Worksheet)excelWorkbook.Sheets.Add(excelWorkbook.Sheets.get_Item(++sheetIndex),
                                                                    Type.Missing, 1, XlSheetType.xlWorksheet);
 
        excelSheet.Name = dt.TableName; // name new sheet name of table
 
        // Fast data export to Excel
        string excelRange = string.Format("A1:{0}{1}", finalColLetter, dt.Rows.Count + 1);
        excelSheet.get_Range(excelRange, Type.Missing).Value2 = data;
 
        // Mark the first row as BOLD
        ((Range)excelSheet.Rows[1, Type.Missing]).Font.Bold = true;
    }
}

Export by iterating of Cells (2)

/// <summary>
/// inserts data into excel row by row
/// </summary>
/// <param name="excel"></param>
/// <param name="ds"></param>
private void InsertIntoExcel(Microsoft.Office.Interop.Excel.Application excel, System.Data.DataSet ds) {
    foreach (System.Data.DataTable dt in ds.Tables) {
        Microsoft.Office.Interop.Excel.Worksheet theSheet = (Microsoft.Office.Interop.Excel.Worksheet)excel.Workbooks[1].Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
        theSheet.Name = dt.TableName;
 
        int colIndex = 0;
        int rowIndex = 1;
        string err = string.Empty;
        try {
            
            colIndex = 0;
            foreach (DataColumn col in dt.Columns) {
                colIndex += 1;
                excel.Cells[1, colIndex] = col.ColumnName;
            }
 
            rowIndex = 1;
            foreach (DataRow row in dt.Rows) {
                rowIndex += 1;
                colIndex = 0;
                foreach (DataColumn col in dt.Columns) {
                    colIndex += 1;
                    excel.Cells[rowIndex, colIndex] = row[col.ColumnName].ToString();
                }
            }
        } catch (Exception ex) {
 
            err += "RowIndex=" + rowIndex.ToString() + " ColIndex=" + colIndex.ToString();
        }
    } // next 
}

 

f.)  g.) Save and clean up

/// <summary>
/// Save workbook to file system
/// </summary>
/// <param name="excelWorkbook"></param>
/// <param name="fileName"></param>
private void SaveDoc(Workbook excelWorkbook, string fileName) {
    // Save and Close the Workbook
    excelWorkbook.SaveAs(fileName, XlFileFormat.xlWorkbookNormal, Type.Missing,
        Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlExclusive,
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
    excelWorkbook.Close(true, Type.Missing, Type.Missing);
    excelWorkbook = null;
}

 

/// <summary>
/// Clean up and close document
/// </summary>
/// <param name="excelApp"></param>
private void CloseExcelDocument(ApplicationClass excelApp) {
    // Release the Application object
    excelApp.Quit();
    excelApp = null;
 
    // Collect the unreferenced objects
    GC.Collect();
    GC.WaitForPendingFinalizers();
}
category: Feature

Comments


# Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by WebDevVote.com on 8/24/2009 5:24 PM
Gravatar You are voted (great) - Trackback from WebDevVote.com
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Charles Miles on 8/24/2009 10:23 PM
Gravatar Nice article - it seems like this is a really common need yet not something Microsoft has given us a fantastic strategy for. I work with this problem alot so thought some other links might be interesting:

http://www.codeplex.com/ExcelPackage
It seems the authors are not updating this project but with some of the user contributed patches/updates applied this allows pretty good support for the scenario above without Excel installed.

www.codeproject.com/.../DataTableToRecordset.aspx
The Excel object provides a few methods to work quite nicely with ADODB Recordsets - we use this approach at work quite alot and it often provides low hassle handling of tricky fields like UPCs that need to be text not numbers.

Charles
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by dyardy on 8/25/2009 8:41 AM
Gravatar Thanks for the feedback and the above links. I found the excel range method that I included performed very well with very large amounts of data. I wonder how ADODB.Recordset approach performs in comparison. I wouldn't think it does as well.
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Aram on 9/23/2009 12:47 PM
Gravatar very good !!!!!!!!
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Tony on 10/1/2009 5:49 PM
Gravatar Can you post the VS project? Thanks
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by dyardy on 10/9/2009 1:28 PM
Gravatar Tony, send me an email via the contact page and provide your email address.
Thanks
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Prasad on 12/3/2009 1:27 AM
Gravatar Excellent Code
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by george on 12/6/2009 1:05 AM
Gravatar thanks for this.. this solves my problem . i've been looking for a solution for quite some time now .... greatly appreciate this :)
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by easy chess lessons on 1/7/2010 6:48 AM
Gravatar I would suggest using dependency injection to pass a class that provides the means for retrieving the current user to make this audit implementation more usable from different environments.
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Vaibhavi Sawant on 1/7/2010 2:45 PM
Gravatar Hi
Can u send me ur project
U hv dn gr8 job
Thnks
Pls send me project on my email id
sonuprincess143@gmail.com
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Gisle on 2/3/2010 8:49 AM
Gravatar Hi
Very interesting...Please send me your project....Thanks
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Application Hosting on 3/12/2010 1:52 AM
Gravatar Easy option to get useful information as well as share good stuff with good ideas and concepts
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Lucy on 3/31/2010 4:56 PM
Gravatar Do you know how to export mutiple table into one exce with different sheets?

I am new to C#.net.

Thanks!
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by james on 4/15/2010 5:05 PM
Gravatar thanks very useful info here
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Lulu on 5/4/2010 1:54 PM
Gravatar Do you know how to export mutiple table into one exce with different sheets?

Thanks, thanks!!!
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by tan on 6/15/2010 11:48 PM
Gravatar Hi
You did a great job. Can u send me ur project.
Thnks
Pls send me your project on my email add
tristan050887@yahoo.com
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by maaz on 6/16/2010 7:47 AM
Gravatar I m newbie, type whole project but did not worked for me, if u don't mind me asking,
1- xlsx extension not opening in 2007 Excel
2-I did not understand GetConnectionString() function?
3-Sql string is defined where
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Arjun on 6/28/2010 5:53 AM
Gravatar Hi Maaz

Thats like a newbie.. I liked your question.. The answer to your 3rd question is ur 2nd question itself....

# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by web design on 6/28/2010 6:24 AM
Gravatar Thanks for such interesting post – I appreciate.
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by Desmond Lee on 7/11/2010 8:29 PM
Gravatar can you send me the solution file and can you tell me your IDE version ?? thanks....
jin_5091@yahoo.com ..
# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by chat software on 7/20/2010 4:51 AM
Gravatar Well, the info your share here is great and informative to me as I am very new to the subject. But I love reading and getting some more knowledge on it. Thanks

# re: Export SQL Data to Microsoft Excel (using Visual Studio 2008, c#)
Posted by phoncky on 8/3/2010 8:54 AM
Gravatar good stuff. i have issues with Exporting Microsoft Excel Data to SQL Server2008 database (using Visual Studio 2008, c#). can you help?
Post Comment
Title *
Name *
Email
Url
Comment *
Please add 3 and 6 and type the answer here:

About Me

An engineer by training and a software developer at heart. My techniques and approaches meld engineering approaches with software technology.

Core to these principles is a systematic approach to the development of software with a strong lifecycle and process management emphasis through adoption of mature technologies.

Ten years designing heavy structural steel and concrete structures and 12 years in the software development profession have embedded strong project management and business knowledge in my approaches.

Subscribe to Rss Feed


Follow me on twitter @dyardy