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

Export DataSet to Multiple Excel Sheets

By , 12 Dec 2008
 

Introduction

I was in need of exporting multiple tables in a DataSet to an Excel file with multiple sheets, and I couldn't find anything that actually works. So, I wrote one to help people who might be in the same situation. The complete code in ExcelHelper.cs is shown below.

This only works for Excel 2003 and later versions. If a table in the dataset has more than 65,000 rows, it will break it into multiple sheets for the table with sheet name (tableNameX). replaceXmlChar() function is added to escape XML reserved characters.

Limitations of the Code

It does not handle data tables with more than 256 columns (Excel 2003 column limit), and when data tables have very large rows count, it might throw OutOfMemory exception.

Using the Code

To export a DataSet, just call the ExcelHelper.ToExcel() function as follows:

 var ds = new DataSet();
            var dt = new DataTable("TableName For Sheet1");
            dt.Columns.Add("col1");
            dt.Columns.Add("col2");
            dt.Rows.Add("Value1", "Value2");

            var dt2 = new DataTable("TableName For Sheet2");
            dt2.Columns.Add("col1");
            dt2.Columns.Add("col2");
            dt2.Rows.Add("Value1", "Value2");
            ds.Tables.Add(dt);
            ds.Tables.Add(dt2);
            ExcelHelper.ToExcel(ds, "test.xls", Page.Response);      

Here is the code that does the exporting:

//ExcelHelper.cs

public class ExcelHelper
{
    //Row limits older Excel version per sheet
        const int rowLimit = 65000;

        private static string getWorkbookTemplate()
        {
            var sb = new StringBuilder();
            sb.Append("<xml version>\r\n<Workbook
		xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n");
            sb.Append(" xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n
		xmlns:x=\"urn:schemas- microsoft-com:office:excel\"\r\n
		xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\">\r\n");
            sb.Append(" <Styles>\r\n
		<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n
		<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>");
            sb.Append("\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>\r\n
		<Protection/>\r\n </Style>\r\n
		<Style ss:ID=\"BoldColumn\">\r\n <Font ");
            sb.Append("x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n
		<Style ss:ID=\"s62\">\r\n <NumberFormat");
            sb.Append(" ss:Format=\"@\"/>\r\n </Style>\r\n
		<Style ss:ID=\"Decimal\">\r\n
		<NumberFormat ss:Format=\"0.0000\"/>\r\n </Style>\r\n ");
            sb.Append("<Style ss:ID=\"Integer\">\r\n
		<NumberFormat ss:Format=\"0\"/>\r\n </Style>\r\n
		<Style ss:ID=\"DateLiteral\">\r\n <NumberFormat ");
            sb.Append("ss:Format=\"mm/dd/yyyy;@\"/>\r\n </Style>\r\n
		<Style ss:ID=\"s28\">\r\n");
            sb.Append("<Alignment ss:Horizontal=\"Left\" ss:Vertical=\"Top\"
		ss:ReadingOrder=\"LeftToRight\" ss:WrapText=\"1\"/>\r\n");
            sb.Append("<Font x:CharSet=\"1\" ss:Size=\"9\"
		ss:Color=\"#808080\" ss:Underline=\"Single\"/>\r\n");
            sb.Append("<Interior ss:Color=\"#FFFFFF\" ss:Pattern=\"Solid\"/>

		</Style>\r\n</Styles>\r\n {0}</Workbook>");
            return sb.ToString();
        }

        private static string replaceXmlChar(string input)
        {
            input = input.Replace("&", "&");
            input = input.Replace("<", "<");
            input = input.Replace(">", ">");
            input = input.Replace("\"", """);
            input = input.Replace("'", "&apos;");
            return input;
        }

        private static string getWorksheets(DataSet source)
        {
            var sw = new StringWriter();
            if (source == null || source.Tables.Count == 0)
            {
                sw.Write("<Worksheet ss:Name=\"Sheet1\"><Table><Row>

		<Cell  ss:StyleID=\"s62\"><Data ss:Type=\"String\"></Data>
		</Cell></Row></Table></Worksheet>");
                return sw.ToString();
            }
            foreach (DataTable dt in source.Tables)
            {
                if (dt.Rows.Count == 0)
                    sw.Write("<Worksheet ss:Name=\"" + replaceXmlChar(dt.TableName) +
			"\"><Table><Row><Cell  ss:StyleID=\"s62\">

			<Data ss:Type=\"String\"></Data></Cell></Row>
			</Table></Worksheet>");
                else
                {
                    //write each row data
                    var sheetCount = 0;
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        if ((i % rowLimit) == 0)
                        {
                            //add close tags for previous sheet of the same data table
                            if ((i / rowLimit) > sheetCount)
                            {
                                sw.Write("</Table></Worksheet>");
                                sheetCount = (i / rowLimit);
                            }
                            sw.Write("<Worksheet ss:Name=\"" +
				replaceXmlChar(dt.TableName) +
                                     (((i / rowLimit) == 0) ? "" :
				Convert.ToString(i / rowLimit)) + "\"><Table>");
                            //write column name row
                            sw.Write("<Row>");
                            foreach (DataColumn dc in dt.Columns)
                                sw.Write(
                                    string.Format(
                                        "<Cell ss:StyleID=\"BoldColumn\">

				<Data ss:Type=\"String\">{0}</Data></Cell>",
                                        replaceXmlChar(dc.ColumnName)));
                            sw.Write("</Row>\r\n");
                        }
                        sw.Write("<Row>\r\n");
                        foreach (DataColumn dc in dt.Columns)
                            sw.Write(
                                string.Format(
                                    "<Cell ss:StyleID=\"s62\"><Data ss:Type=\"String\">

					{0}</Data></Cell>",
                                    		replaceXmlChar
					(dt.Rows[i][dc.ColumnName].ToString())));
                        sw.Write("</Row>\r\n");
                    }
                    sw.Write("</Table></Worksheet>");
                }
            }

            return sw.ToString();
        }
        public static string GetExcelXml(DataTable dtInput, string filename)
        {
            var excelTemplate = getWorkbookTemplate();
            var ds = new DataSet();
            ds.Tables.Add(dtInput.Copy());
            var worksheets = getWorksheets(ds);
            var excelXml = string.Format(excelTemplate, worksheets);
            return excelXml;
        }

        public static string GetExcelXml(DataSet dsInput, string filename)
        {
            var excelTemplate = getWorkbookTemplate();
            var worksheets = getWorksheets(dsInput);
            var excelXml = string.Format(excelTemplate, worksheets);
            return excelXml;
        }

        public static void ToExcel
		(DataSet dsInput, string filename, HttpResponse response)
        {
            var excelXml = GetExcelXml(dsInput, filename);
            response.Clear();
            response.AppendHeader("Content-Type", "application/vnd.ms-excel");
            response.AppendHeader
		("Content-disposition", "attachment; filename=" + filename);
            response.Write(excelXml);
            response.Flush();
            response.End();
        }

        public static void ToExcel
		(DataTable dtInput, string filename, HttpResponse response)
        {
            var ds = new DataSet();
            ds.Tables.Add(dtInput.Copy());
            ToExcel(ds, filename, response);
        }
    }

History

  • 7th December, 2008: Initial post
  • 8th December, 2008: Source code and article updated
  • 11th December, 2008: Source code and article updated

License

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

About the Author

Ming_Lu
Software Developer Viocare
United States United States
Member
Education: Masters in Applied mathematics
 
Certification:
MCP in Asp.net
MCP in SQL Server 2008 Implementation.
 
Working Experience In .Net since 2005

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

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionThread ExceptionmemberMember 99523501 hr 51mins ago 
Questionjet4.0membernadersghir28 Jan '13 - 3:41 
QuestionHow to store the excel file to Network shared Drive instead of opening on client machinememberkeyur_parekh25 Oct '12 - 11:37 
QuestionUnable to export if there are 1 lakh records in the datasetmemberAbhishek K Gohil11 Oct '12 - 1:51 
Questionnot in correct format for 2010.memberTeenustar10 Oct '12 - 10:42 
GeneralThanks For Share this artical very helpfulmembersapnapal8 Aug '12 - 22:29 
GeneralMy vote of 5memberchus2425 Jun '12 - 14:43 
Questiondata display in gridview depend on user key in.how to export it?membermusiw12 Jun '12 - 23:11 
QuestionWorks Great...ThanksmemberMember 3324275 Jun '12 - 8:29 
GeneralNicemembersivasankari ts14 May '12 - 23:28 
GeneralVote of 5!membermk_ln12 Apr '12 - 11:07 
I was originally thinking that somehow inserting a page break via response.write would give me a new tab. After much searching it seems that I wouldn't be able to insert a page break via that method.
 
Your code has assisted me greatly!
 
Thanks!
GeneralMy vote of 5membermanoj kumar choubey4 Apr '12 - 23:27 
GeneralThanks for this helpful codemembermonika nafdey14 Mar '12 - 19:19 
GeneralMy vote of 5memberProEnggSoft1 Mar '12 - 18:30 
Questionerror message when opening text.xlsmemberMember 86927471 Mar '12 - 16:55 
AnswerRe: error message when opening text.xlsmembercadetduke30 Mar '12 - 9:49 
GeneralRe: error message when opening text.xlsmemberTeenustar10 Oct '12 - 10:55 
GeneralMy vote of 5memberARK Kambhampati27 Feb '12 - 20:03 
QuestionAlternate row colormemberkinjalin29 Nov '11 - 21:02 
GeneralMy vote of 5memberFredde197728 Sep '11 - 3:50 
Questionneed help with style sheet error [modified]membertalmans26 Aug '11 - 12:47 
BugNot woking with Marquee taq?membermuthura120 Jun '11 - 1:39 
GeneralMy vote of 5!memberFilip D'haene14 May '11 - 11:11 
QuestionCell Formatting.. Issues...?membercodingrocks13 Mar '11 - 2:24 
AnswerRe: Cell Formatting.. Issues...?memberMing_Lu13 Mar '11 - 14:41 
GeneralMy vote of 4memberpraveen_adb9 Jan '11 - 20:26 
GeneralMy vote of 5memberbacoares23 Nov '10 - 4:48 
GeneralMy vote of 5memberL.H.C1 Oct '10 - 18:56 
GeneralEasy alternativememberCikaPero13 Apr '10 - 22:52 
GeneralAuto Fit Excel ColumnsmemberMember 465177014 Jan '10 - 1:10 
GeneralSys.WebForms.PageRequestManagerParserErrorExceptionmemberSteve Crochet28 Dec '09 - 9:14 
GeneralRe: Sys.WebForms.PageRequestManagerParserErrorExceptionmemberMing_Lu2 Jan '10 - 3:55 
GeneralRe: Sys.WebForms.PageRequestManagerParserErrorExceptionmemberSteve Crochet4 Jan '10 - 5:44 
QuestionWhat shd i use instead of var??memberBushra2812 Oct '09 - 23:12 
GeneralBig File Sizemembertxshxx4 Oct '09 - 17:12 
QuestionExport to Excel 2003 using ASP [modified]memberkaransaxena15 Jun '09 - 10:46 
GeneralHandle linefeed in cellsmemberDACS13 Mar '09 - 13:43 
AnswerRe: Handle linefeed in cellsmemberMing_Lu3 Apr '09 - 7:18 
GeneralRe: Handle linefeed in cellsmemberDACS3 Apr '09 - 21:35 
QuestionCan I use this class in Windows Application?memberSu Win8 Mar '09 - 4:17 
AnswerRe: Can I use this class in Windows Application?memberMing_Lu3 Apr '09 - 7:29 
GeneralRe: Can I use this class in Windows Application?memberSu Win5 Apr '09 - 17:26 
GeneralRe: Can I use this class in Windows Application?memberBushra2812 Oct '09 - 23:16 
GeneralRe: Can I use this class in Windows Application?memberSu Win13 Oct '09 - 17:11 
GeneralRe: Can I use this class in Windows Application?membervijayalaya4 May '11 - 20:17 
GeneralRe: Can I use this class in Windows Application?memberSu Win5 May '11 - 16:49 
GeneralRe: Can I use this class in Windows Application?membersankar43211 Dec '11 - 22:20 
GeneralOutOfMemory problem.memberKenial8 Feb '09 - 16:01 
GeneralColors and others formatmembermmuekk16 Jan '09 - 0:47 
GeneralRe: Colors and others formatmemberMember 20363832 Apr '09 - 22:27 

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 12 Dec 2008
Article Copyright 2008 by Ming_Lu
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid