Click here to Skip to main content
Licence CPOL
First Posted 31 May 2011
Views 19,831
Bookmarked 55 times

Exporting Data to Excel

By | 15 Jun 2011 | Article
A few different ways of exporting data to Excel.

Introduction

Exporting data to Excel is a very common requirement in programs. In this article, I want to explain some solutions and offer you a solution for large amount data exporting to Excel which may be useful for you.

Solution 1 - OLEDB

Using OLEDB, we can export data to Excel conveniently. When you deal with this, just make the Excel an Access. Create tables with SQL and insert data information. See the code below:

public static void Export(DataTable dt, string filepath, string tablename)
{
    //excel 2003
    string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + 
           filepath + ";Extended Properties=Excel 8.0;";
    //Excel 2007
    //string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + 
    //       filepath + ";Extended Properties=Excel 12.0 Xml;";
    try
    {
        using (OleDbConnection con = new OleDbConnection(connString))
        {
            con.Open();
            StringBuilder strSQL = new StringBuilder();
            strSQL.Append("CREATE TABLE ").Append("[" + tablename + "]");
            strSQL.Append("(");
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                strSQL.Append("[" + dt.Columns[i].ColumnName + "] text,");
            }
            strSQL = strSQL.Remove(strSQL.Length - 1, 1);
            strSQL.Append(")");

            OleDbCommand cmd = new OleDbCommand(strSQL.ToString(), con);
            cmd.ExecuteNonQuery();

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                strSQL.Clear();
                StringBuilder strfield = new StringBuilder();
                StringBuilder strvalue = new StringBuilder();
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    strfield.Append("[" + dt.Columns[j].ColumnName + "]");
                    strvalue.Append("'" + dt.Rows[i][j].ToString() + "'");
                    if (j != dt.Columns.Count - 1)
                    {
                        strfield.Append(",");
                        strvalue.Append(",");
                    }
                    else
                    {
                    }
                }
                cmd.CommandText = strSQL.Append(" insert into [" + tablename + "]( ")
                    .Append(strfield.ToString())
                    .Append(") values (").Append(strvalue).Append(")").ToString();
                cmd.ExecuteNonQuery();
            }
            con.Close();
        }
        Console.WriteLine("OK");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Use connString to control and generate Excel 2003 or Excel 2007. At the same time, the file name should match (xls or xlsx).

Solution 2 - Excel COM

Excel provides a COM component which can generate an Excel file. It can generate cells with content and format, which OLEDB does not support. But this solution requires the user to install Excel related components, and once the file is generated, the Excel process will still exist.

public static void Export(DataTable dt, string filepath)
{
    ExcelApp.Application myExcel = new ExcelApp.Application();
    //Create a New file
    ExcelApp._Workbook mybook = myExcel.Workbooks.Add();
    //Open the exist file
    //ExcelApp._Workbook mybook = myExcel.Workbooks.Open(filepath,
    //          Type.Missing, Type.Missing, Type.Missing,
    //    Type.Missing,Type.Missing, Type.Missing, Type.Missing,
    //    Type.Missing, Type.Missing, Type.Missing,
    //    Type.Missing, Type.Missing,Type.Missing, Type.Missing);
    //ExcelApp._Workbook mybook = myExcel.Workbooks.Open(Filename: filepath);
    myExcel.Visible = true;
    try
    {
        mybook.Activate();
        ExcelApp._Worksheet mysheet = mybook.Worksheets.Add();      
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                ExcelApp.Range cell = 
                  mysheet.get_Range(((char)(65 + j)).ToString() + (i + 1).ToString());
                cell.Select();
                cell.Cells.FormulaR1C1 = dt.Rows[i][j] ?? "";
            }
        }
        //mybook.SaveAs(Filename: filepath);
        mybook.Save();
    }
    catch (Exception ex)
    {
    }
    finally
    {
        mybook.Close();
        myExcel.Quit();
        GC.Collect();
    }
}

While using the COM component, the user needs to add the "Microsoft Office.Interop.Excel" reference. ExcelApp is given as a namespace alias.

using ExcelApp = Microsoft.Office.Interop.Excel;

Solution 3 - Open XML

The Open XML SDK provided by Microsoft can be used to generate Excel. Rename Office 2007 (Word, Excel, PPT) as a .zip and release the zip file; you will find the released files are XML files.

Note: Microsoft Office version should be 2007 or above.

Solution 4 - Data Export Component

Use the Data Export Component to export data to Excel and you don't even need to install Microsoft Office.

Recommend a Free Data Export Component which also recommended in these articles:

Huge Amount Data Export to Excel Solution

The solutions above are normal methods. For large amounts of data, the first two solutions may not be useful, especially the COM component, which needs to generate rows one by one. But using QueryTable in COM can improve the solution a lot.

public static void Export( string filepath,string strSQL)
{
    ExcelApp.Application myExcel = new ExcelApp.Application();
    ExcelApp._Workbook mybook = myExcel.Workbooks.Add();            
    try
    {
        mybook.Activate();
        ExcelApp._Worksheet mysheet = mybook.Worksheets.Add();
        string conn = 
          "ODBC;Driver=SQL Server;Server=.;uid=sa;pwd=sa;database=sample;";
        ExcelApp.QueryTable querytable = 
          mysheet.QueryTables.Add(conn, mysheet.get_Range("A1"), strSQL);
        querytable.Refresh(false);
        mybook.SaveAs(Filename : filepath,AccessMode:ExcelApp.XlSaveAsAccessMode.xlNoChange);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    finally
    {
        mybook.Close();
        myExcel.Quit();
    }
}

Although this is much faster, it's not stable. Sometimes it's fast and sometimes it's slow. And an Excel process exists after we close the app, and there is no easy way to switch it off.

In SQL Server, OPENDATASOURCE or OPENROWSET can directly read data from Excel.

SELECT * 
FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
'Data Source=D:\book.xls;Extended Properties=EXCEL 5.0')...[sheet1$] ;

-- or

insert into OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
'Data Source=D:\book.xls;Extended Properties=EXCEL 5.0')...[sheet1$]
select Customer .name ,Product .fullname
from [v_Order]

A file is created and there should be some information in the first line.

Before using OPENDATASOURCE, execute this:

exec sp_configure 'Ad Hoc Distributed Queries','1'
RECONFIGURE

Otherwise there will be an error: "SQL Server stopped the visit of STATEMENT 'OpenRowset/OpenDatasource' in 'Ad Hoc Distributed Queries'.

But because of this, the file can not be directly generated in the client. Use BCP to export data can be very fast. But the output Excel file is not standard format.

SQL Server can do this Job. How about Access? It also works if we use "in":

select * from product
in '[ODBC;Driver=SQL Server;Server=.;uid=sa;pwd=sa;database=sample;]'

Executing the code above in Access can get the data from SQL Server. "in" also supports other databases besides SQL Server.

At the beginning I mentioned that we can deal with Excel as Access. Just export OLEDB to an Excel table and insert the recorded SQL command text to replace the queries (need to change the code to select into). Here is the code:

public static void Export(string strSQL, string filepath)
{
    //string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + 
    //       filepath + ";Extended Properties=Excel 8.0;";
    string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + 
           filepath + ";Extended Properties=Excel 12.0 Xml;";
    try
    {
        using (OleDbConnection conn = new OleDbConnection(connString))
        {
            conn.Open();
            OleDbCommand cmd = new OleDbCommand(strSQL, conn);
            cmd.ExecuteNonQuery();
            conn.Close();
        }
        Console.WriteLine("OK");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Use the SQL:

select  * into product
from product
in "" [ODBC;Driver=SQL Server;Server=.;uid=sa;pwd=sa;database=sample;]
If you need add where, orderby, place them behind SQL 
select  [fullname] as Name,[alias] as Abbreviation,[price] as Price
into Product
from product
in "" [ODBC;Driver=SQL Server;Server=.;uid=sa;pwd=sa;database=sample;]
where id_product  >1
order by fullname

Note:

  • Only 65536 rows a sheet in Excel 2003
  • 1048576 rows a sheet in Excel 2007

I welcome all kinds of suggestions from you!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

loveyou999


e-iceblue
United States United States

Member

Follow on Twitter Follow on Twitter


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Questionhow to do this? Pinmembermani.kishore.asp.net19:37 26 Apr '12  
QuestionUsing OLEDB... Pinmemberbiop.codeproject21:54 4 Apr '12  
QuestionCOM solution PinmemberHRThomann4:50 9 Sep '11  
QuestionError exporting from SQL to Excel Pinmemberhewp14:08 5 Aug '11  
GeneralMy vote of 2 PinmemberDave Elliott14:32 14 Jun '11  
GeneralMy vote of 4 PinmemberYvan Rodrigues4:08 7 Jun '11  
GeneralMy vote of 5 PinmemberBob Carter3:43 7 Jun '11  
GeneralMy vote of 2 PinmemberRob Grainger2:26 3 Jun '11  
GeneralRe: My vote of 2 PinmemberCikaPero21:30 1 Sep '11  
GeneralMy vote of 5 PinmemberJacky201123:09 2 Jun '11  
GeneralThose dreaded words... PinmemberMBigglesworth7923:04 2 Jun '11  
GeneralMy vote of 4 PinmemberMBigglesworth7922:57 2 Jun '11  
GeneralBetter Excel Reading and Wrting Pinmemberavigodse23:25 31 May '11  
GeneralRe: Better Excel Reading and Wrting Pinmemberzingoraa23:28 31 May '11  
GeneralRe: Better Excel Reading and Wrting Pinmemberavigodse23:40 31 May '11  
GeneralRe: Better Excel Reading and Wrting PinmemberJamesHoward97222:30 18 Dec '11  
GeneralMy vote of 5 Pinmemberavigodse23:23 31 May '11  
GeneralMy vote of 5 Pinmemberknoami22:44 31 May '11  
GeneralMy vote of 2 PinmemberSelvin22:22 31 May '11  
GeneralRe: My vote of 2 Pinmemberloveyou99922:34 31 May '11  
GeneralRe: My vote of 2 PinmemberSelvin22:40 31 May '11  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 16 Jun 2011
Article Copyright 2011 by loveyou999
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid