Click here to Skip to main content
Click here to Skip to main content

Export data to Excel in Webmatrix

By , 21 May 2012
 

Introduction

When I was looking for a method to upload data from the SQL Server CE database of my Web Pages site, I found a possible answer in the “Solution 1 – OLEDB” proposal of the “Exporting Data to Excel” article.

During the development I came across some small problems and finally I obtained an acceptable implementation that I will share in this article.

My solution uses the System.Data.SqlServerCe.dll, that must be referenced in Web.config file, and three functions, which I outline in the following.

The code in depth

Web.config file

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true">
      <assemblies>
        <add assembly="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845DCD8080CC91"/>
      </assemblies>
    </compilation>
  </system.web>
</configuration>

The add assembly setting references the System.Data.SqlServerCe.dll assembly that is needed during the compilation of the web page (see CreateDataTable function).

CreateDataTable functions

public static DataTable CreateDataTable(string sqlCeDb, string sqlCmd)
{
    DataSet dataSet = new DataSet();
    DataTable dt = new DataTable();
    
    try {
        SqlCeConnection sqlConn= new SqlCeConnection();
        sqlConn.ConnectionString = "Data Source = " + sqlCeDb; 

        SqlCeCommand cmd = new SqlCeCommand(); 
        cmd.CommandType = CommandType.Text; 
        cmd.CommandText = sqlCmd; 
        cmd.Connection = sqlConn;

        sqlConn.Open();
        SqlCeDataAdapter sda = new SqlCeDataAdapter(cmd);
    
        sda.Fill(dataSet);
        sqlConn.Close(); 
        
        dt = dataSet.Tables[0];
        return dt;
    }
    catch (Exception ex)
    {
        return dt;
    }      
}

The CreateDataTable function opens a connection with the SQL Server CE database and exports data as DataTable from the database.

It accepts the physical path of the SQL Server CE .sdf file as first parameter and the SQL query extracting data from the database as second parameter.

The function instantiates classes from the System.Data.SqlServerCe namespace, that must be referenced in Web.Config.

ExportToExcel function

public static int ExportToExcel(DataTable dt, string excelFile, string sheetName)
{
    // Create the connection string
    string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + 
        excelFile + ";Extended Properties=Excel 12.0 Xml;";
    
    int rNumb = 0;
    try
    {
        using (OleDbConnection con = new OleDbConnection(connString))
        {
            con.Open();
            
            // Build the field names string
            StringBuilder strField = new StringBuilder();
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                strField.Append("[" + dt.Columns[i].ColumnName + "],");
            }
            strField = strField.Remove(strField.Length - 1, 1);
            
            // Create Excel sheet
            var sqlCmd = "CREATE TABLE [" + sheetName + "] (" + strField.ToString().Replace("]", "] text") + ")";
            OleDbCommand cmd = new OleDbCommand(sqlCmd, con);
            cmd.ExecuteNonQuery();

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                
                // Insert data into Excel sheet
                StringBuilder strValue = new StringBuilder();
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    strValue.Append("'" + AddSingleQuotes(dt.Rows[i][j].ToString()) + "',");
                }
                strValue = strValue.Remove(strValue.Length - 1, 1);
                
                cmd.CommandText = "INSERT INTO [" + sheetName + "] (" + strField.ToString() + ") VALUES (" +
                        strValue.ToString() + ")";
                cmd.ExecuteNonQuery();
                rNumb = i + 1;
            }
            con.Close();
        }
        return rNumb;
    }
    catch (Exception ex)
    {
        return -1;
    }
}

The ExportToExcel function receives a DataTable as first parameter and transfers its content into a sheet (with name from the third parameter) of a new Excel file created at the path passed with the second parameter.

If the function is successful, it returns the number of exported records, otherwise it returns -1.

It derives with some modifications from the Export function from Exporting Data to Excel; in the following I highlight its points of interest.

The connection string

I have chosen to produce an Excel file in the new .xlsx file format introduced by Excel 2007, and so I have used a connection string to the Access Database Engine 2010, which exists in 32-bit and 64-bit versions and that must be downloaded from Microsoft Access Database Engine 2010 Redistributable, if it’s not present on your system yet.

Even if you want to create a traditional .xls file, you have to know that the old Microsoft OLE DB Provider for Jet is available in 32-bit version only.

So, the only solution for the web sites running on 64-bit environments is to use the Access Database Engine 2010 with a slightly different connection string:

string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + 
    excelFile + ";Extended Properties=Excel 8.0;";

The field names string

Two different SQL statements require a list of field name as string in the format

[field1],[field2],[field3],…,[fieldn]

The string is created by a for loop that appends to a StringBuilder object all the column names of the DataTable.

Create Excel sheet

The major simplification used by the function is that all the data from database are transferred to the Excel file as text.

This approach avoids to examine one by one the column data types of DataTable and create an Excel sheet with columns of the same source type.

So, all the columns of the Excel sheet are generated as text fields with a SQL statement that uses the field names string seen before adding to any field name “text” as data type with the use of a Replace("]", "] text") method.

Copy records from DataTable to Excel sheet

For each DataTable row a string is created appending all the row values and then the string is used together with the field names string to assemble a SQL statement that inserts the row values into the Excel sheet.

Note that the process of creating a field values string involves a call to the AddSingleQuote function to escape possible single quotes in the values.

AddSingleQuote function

public static string AddSingleQuotes(string origText)
{
 string s = origText;
    int i = 0;
    
    while ((i = s.IndexOf("'", i)) != -1)
    {
        // Add single quote after existing
        s = s.Substring(0, i) + "'" + s.Substring(i);

        // Increment the index.
        i += 2;
    }
    return s;
}

If the text passed as value to the Insert SQL statement includes a single quote, SQL Server throws an error (Error: 105 Unclosed quotation mark after the character string ‘).

The function fixes this occurrence by escaping any single quote with the addition of a second single quote.

The sample application

To illustrate the use of my functions, I propose a simple site that extract data as Excel file from a sample database with a quite complex query.

The sample database I used is the TestDB.sdf file downloadable from the link SQL SERVER – CE – Samples Database for SQL CE 4.0.

It must be copied into the App_Data directory of the sample site and then Default.cshtml page can be launched in browser.

Obviously, the query I used could be replaced with a simpler one like

SELECT * FROM Customers

License

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

About the Author

Gianmaria Gregori
Italy Italy
Member
No Biography provided

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.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWorks on Local Machine - not on azurewebsites.netmemberrichosborne26 Mar '13 - 5:25 
First, thank you for this excellent piece of code. I'm a novice and yet I got it to work perfectly on my local machine. After Publishing on azurewebsites.net, the download returns -1. I'm unclear how to proceed debugging this issue? Thanks again.
GeneralMy vote of 5memberMember 432084427 May '12 - 9:36 
Thanks for the idea and sharing.
GeneralRe: My vote of 5memberGianmaria Gregori27 May '12 - 11:01 
Thank you.
GeneralMy vote of 1membereddy morrison22 May '12 - 2:09 
description fail
GeneralRe: My vote of 1memberGianmaria Gregori22 May '12 - 2:23 
I don't understand what you mean.
GeneralMy vote of 5memberVolynsky Alex21 May '12 - 9:32 
Good Job!
GeneralRe: My vote of 5memberGianmaria Gregori27 May '12 - 11:01 
Thanks, Alex.
SuggestionData versus Dato, perhaps?memberSlacker00721 May '12 - 3:20 
In your title, that is.
 
Wink | ;)


"the meat from that butcher is just the dogs danglies, absolutely amazing cuts of beef." - DaveAuld (2011)
"No, that is just the earthly manifestation of the Great God Retardon." - Nagy Vilmos (2011)
"It is the celestial scrotum of good luck!" - Nagy Vilmos (2011)
"But you probably have the smoothest scrotum of any grown man" - Pete O'Hanlon (2012)


GeneralRe: Data versus Dato, perhaps?memberGianmaria Gregori21 May '12 - 4:27 
Thank you for your advice. Updated.

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 21 May 2012
Article Copyright 2012 by Gianmaria Gregori
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid