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

Export a DataSet to Microsoft Excel without the use of COM objects

By , 28 May 2005
 

Introduction

This function takes in a DataSet and file name and writes the DataSet to an Excel worksheet. The code is pretty straightforward. Great thing about this function is that, it's technically an XML file that is saved as an XLS file. So it can be used as either file format. No more leading zero truncation on numbers that look like strings. Example, if you made a tab delimited file and put a field such as "00036" (a field that looks like a number but should be regarded as a string), MS Excel would truncate the leading zeros... This problem is solved with this method.

Here is the code:

public static void exportToExcel(DataSet source, string fileName)

{

    System.IO.StreamWriter excelDoc;

    excelDoc = new System.IO.StreamWriter(fileName);
    const string startExcelXML = "<xml version>\r\n<Workbook " + 
          "xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" + 
          " 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 <Styles>\r\n " + 
          "<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n " + 
          "<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>" + 
          "\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>" + 
          "\r\n <Protection/>\r\n </Style>\r\n " + 
          "<Style ss:ID=\"BoldColumn\">\r\n <Font " + 
          "x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n " + 
          "<Style     ss:ID=\"StringLiteral\">\r\n <NumberFormat" + 
          " ss:Format=\"@\"/>\r\n </Style>\r\n <Style " + 
          "ss:ID=\"Decimal\">\r\n <NumberFormat " + 
          "ss:Format=\"0.0000\"/>\r\n </Style>\r\n " + 
          "<Style ss:ID=\"Integer\">\r\n <NumberFormat " + 
          "ss:Format=\"0\"/>\r\n </Style>\r\n <Style " + 
          "ss:ID=\"DateLiteral\">\r\n <NumberFormat " + 
          "ss:Format=\"mm/dd/yyyy;@\"/>\r\n </Style>\r\n " + 
          "</Styles>\r\n ";
     const string endExcelXML = "</Workbook>";

     int rowCount = 0;
     int sheetCount = 1;
     /*
    <xml version>
    <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
    xmlns:o="urn:schemas-microsoft-com:office:office"
    xmlns:x="urn:schemas-microsoft-com:office:excel"
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
    <Styles>
    <Style ss:ID="Default" ss:Name="Normal">
      <Alignment ss:Vertical="Bottom"/>
      <Borders/>
      <Font/>
      <Interior/>
      <NumberFormat/>
      <Protection/>
    </Style>
    <Style ss:ID="BoldColumn">
      <Font x:Family="Swiss" ss:Bold="1"/>
    </Style>
    <Style ss:ID="StringLiteral">
      <NumberFormat ss:Format="@"/>
    </Style>
    <Style ss:ID="Decimal">
      <NumberFormat ss:Format="0.0000"/>
    </Style>
    <Style ss:ID="Integer">
      <NumberFormat ss:Format="0"/>
    </Style>
    <Style ss:ID="DateLiteral">
      <NumberFormat ss:Format="mm/dd/yyyy;@"/>
    </Style>
    </Styles>
    <Worksheet ss:Name="Sheet1">
    </Worksheet>
    </Workbook>
    */
    excelDoc.Write(startExcelXML);
    excelDoc.Write("<Worksheet ss:Name=\"Sheet" + sheetCount + "\">");
    excelDoc.Write("<Table>");
    excelDoc.Write("<Row>");
    for(int x = 0; x < source.Tables[0].Columns.Count; x++)
    {
      excelDoc.Write("<Cell ss:StyleID=\"BoldColumn\"><Data ss:Type=\"String\">");
      excelDoc.Write(source.Tables[0].Columns[x].ColumnName);
      excelDoc.Write("</Data></Cell>");
    }
    excelDoc.Write("</Row>");
    foreach(DataRow x in source.Tables[0].Rows)
    {
      rowCount++;
      //if the number of rows is > 64000 create a new page to continue output
      if(rowCount==64000) 
      {
        rowCount = 0;
        sheetCount++;
        excelDoc.Write("</Table>");
        excelDoc.Write(" </Worksheet>");
        excelDoc.Write("<Worksheet ss:Name=\"Sheet" + sheetCount + "\">");
        excelDoc.Write("<Table>");
      }
      excelDoc.Write("<Row>"); //ID=" + rowCount + "
      for(int y = 0; y < source.Tables[0].Columns.Count; y++)
      {
        System.Type rowType;
        rowType = x[y].GetType();
        switch(rowType.ToString())
        {
          case "System.String":
             string XMLstring = x[y].ToString();
             XMLstring = XMLstring.Trim();
             XMLstring = XMLstring.Replace("&","&");
             XMLstring = XMLstring.Replace(">",">");
             XMLstring = XMLstring.Replace("<","<");
             excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" + 
                            "<Data ss:Type=\"String\">");
             excelDoc.Write(XMLstring);
             excelDoc.Write("</Data></Cell>");
             break;
           case "System.DateTime":
             //Excel has a specific Date Format of YYYY-MM-DD followed by  
             //the letter 'T' then hh:mm:sss.lll Example 2005-01-31T24:01:21.000
             //The Following Code puts the date stored in XMLDate 
             //to the format above
             DateTime XMLDate = (DateTime)x[y];
             string XMLDatetoString = ""; //Excel Converted Date
             XMLDatetoString = XMLDate.Year.ToString() +
                  "-" + 
                  (XMLDate.Month < 10 ? "0" + 
                  XMLDate.Month.ToString() : XMLDate.Month.ToString()) +
                  "-" +
                  (XMLDate.Day < 10 ? "0" + 
                  XMLDate.Day.ToString() : XMLDate.Day.ToString()) +
                  "T" +
                  (XMLDate.Hour < 10 ? "0" + 
                  XMLDate.Hour.ToString() : XMLDate.Hour.ToString()) +
                  ":" +
                  (XMLDate.Minute < 10 ? "0" + 
                  XMLDate.Minute.ToString() : XMLDate.Minute.ToString()) +
                  ":" +
                  (XMLDate.Second < 10 ? "0" + 
                  XMLDate.Second.ToString() : XMLDate.Second.ToString()) + 
                  ".000";
                excelDoc.Write("<Cell ss:StyleID=\"DateLiteral\">" + 
                             "<Data ss:Type=\"DateTime\">");
                excelDoc.Write(XMLDatetoString);
                excelDoc.Write("</Data></Cell>");
                break;
              case "System.Boolean":
                excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" + 
                            "<Data ss:Type=\"String\">");
                excelDoc.Write(x[y].ToString());
                excelDoc.Write("</Data></Cell>");
                break;
              case "System.Int16":
              case "System.Int32":
              case "System.Int64":
              case "System.Byte":
                excelDoc.Write("<Cell ss:StyleID=\"Integer\">" + 
                        "<Data ss:Type=\"Number\">");
                excelDoc.Write(x[y].ToString());
                excelDoc.Write("</Data></Cell>");
                break;
              case "System.Decimal":
              case "System.Double":
                excelDoc.Write("<Cell ss:StyleID=\"Decimal\">" + 
                      "<Data ss:Type=\"Number\">");
                excelDoc.Write(x[y].ToString());
                excelDoc.Write("</Data></Cell>");
                break;
              case "System.DBNull":
                excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" + 
                      "<Data ss:Type=\"String\">");
                excelDoc.Write("");
                excelDoc.Write("</Data></Cell>");
                break;
              default:
                throw(new Exception(rowType.ToString() + " not handled."));
            }
          }
          excelDoc.Write("</Row>");
        }
        excelDoc.Write("</Table>");
        excelDoc.Write(" </Worksheet>");
        excelDoc.Write(endExcelXML);
        excelDoc.Close();
    }

Note

To see what generated, just pass the file name with a .txt extension. For Excel format, the file name will be .xls. For XML format, the file name will be .xml.

The Export Routine does have one side effect! (if anyone can figure out a solution to this, it would be greatly appreciated). The file is saved as an .XLS file, but it technically is still an XML file. This little nuance makes the file size larger then it really should be. A quick fix to this is to just do File Save As.... after the file has been exported. When you do the Save As in Excel, it will reconstruct it as a "real" Excel file, and it will bring the file size down to what it should be.

Feed Back is always welcome.

Simple as that...Enjoy.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Xodiak
United States United States
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

 
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   
GeneralMy vote of 5memberBrianLaF3 Aug '12 - 10:32 
QuestionHow to define 1000 grouping symbol for decimal numbermemberbotngot835 Feb '12 - 23:03 
AnswerRe: How to define 1000 grouping symbol for decimal numbermemberbotngot838 Mar '12 - 15:08 
GeneralMy vote of 5memberSavindraSingh29 Jan '12 - 23:51 
QuestionMicrosoft Office Excel cannot open or save any more documentsmembersquidder1411 Jan '12 - 4:44 
GeneralA simpler, and free, class to export from a DataSet into an Excel 2007 .xlsx file.memberMikeGledhill1 Dec '11 - 2:03 
GeneralMy vote of 5memberRajesh Kumar Chekuri16 Nov '11 - 20:09 
AnswerVery nice codememberVictorio A Pellicano7 Nov '11 - 8:31 
Question*FIX* blank worksheetmemberaarharden30 Oct '11 - 11:14 
GeneralMy vote of 5membermurat8938 Jul '11 - 2:34 
QuestionJust a quick note about your System.DateTime case....memberjp2code27 Jun '11 - 6:07 
GeneralMy vote of 5memberArjun14521 Jun '11 - 23:46 
GeneralHello hellomemberskelmannen10 Nov '10 - 10:03 
GeneralNew VB version...memberJalapeno Bob5 Nov '10 - 6:00 
QuestionWould this approach create a lot of xls files on the web server?membereric.yu.cn12 Oct '10 - 23:28 
GeneralGiving error in office 2007. Please help.memberraghav196 Sep '10 - 1:46 
GeneralExcel created as blankmemberPeeter1231 Sep '10 - 19:14 
Generalgood article~~~ ^^memberMetalzang11 Aug '10 - 14:41 
Question[question] Re: good article~~~ ^^memberMetalzang11 Aug '10 - 15:43 
GeneralVery usefulmemberPoojaGRD10 Aug '10 - 23:52 
GeneralSchema source questionmemberConsulting Mechanic20 May '10 - 11:55 
GeneralRe: Schema source questionmemberXodiak20 May '10 - 12:07 
GeneralExporting Dataset to Excel 2007 with Hyperlink in vb.net or C#.netmembermohankundenagoud29 Mar '10 - 1:00 
GeneralRe: Exporting Dataset to Excel 2007 with Hyperlink in vb.net or C#.netmemberCikaPero16 Jul '10 - 0:12 
GeneralGenerates XML but Excel Sheet is blankmemberE P Sharp11 Feb '10 - 2:05 
GeneralRe: Generates XML but Excel Sheet is blankmemberPeeter12331 Aug '10 - 23:19 
GeneralLoad Bulk Data ( DAtaset Having 50,000 Records)membermenukutti24 Nov '09 - 23:56 
GeneralVery usefulmemberkdwarak22 Sep '09 - 1:12 
Generalgood onemembermansuri.isteyaq7 Sep '09 - 23:55 
QuestionHow to open this file after you exportmemberMK_00713 Jul '09 - 11:42 
AnswerRe: How to open this file after you exportmemberXodiak25 Nov '09 - 2:52 
QuestionDoes anyone have a similar method to export a DataSet (or even a single DataTable) to a format OpenOffice.org 3.1 Calc can view?memberGeoffrey D. Roberts18 Jun '09 - 12:20 
AnswerRe: Does anyone have a similar method to export a DataSet (or even a single DataTable) to a format OpenOffice.org 3.1 Calc can view?memberGeoffrey D. Roberts18 Jun '09 - 12:41 
GeneralVery Helpfulmembercorcaigh6 Jun '09 - 0:05 
QuestionHow can you set the path where the file is saved?memberasianx27 Apr '09 - 9:43 
AnswerRe: How can you set the path where the file is saved?memberKilManish@gmail.com6 May '09 - 3:27 
GeneralWarning [modified]memberElectronikBean24 Apr '09 - 1:36 
GeneralConverted to VB, also handles multiple Data Tables and creates a new Sheet for every Data Table and names the Sheet same as Data Table NamememberUniBond16 Apr '09 - 6:47 
GeneralSaving it as an Microsoft Office Excel WorkbookmemberJimmyJamz15 Apr '09 - 4:13 
GeneralRe: Saving it as an Microsoft Office Excel WorkbookmemberXodiak15 Apr '09 - 5:42 
QuestionTime Calulationmembernishant pathak1 Apr '09 - 3:19 
AnswerRe: Time CalulationmemberXodiak1 Apr '09 - 4:50 
GeneralExporting multiple datatable to multiple sheets in excel using C#membervenkateswaran0223 Feb '09 - 20:20 
GeneralRe: Exporting multiple datatable to multiple sheets in excel using C#memberXodiak24 Feb '09 - 4:47 
GeneralRe: Exporting multiple datatable to multiple sheets in excel using C#membervikram_asv4 Mar '09 - 7:17 
GeneralVariation on a themememberGer Rietman11 Feb '09 - 21:59 
GeneralConverted it to VB.NET and then changed from StreamWriter to StringWritermemberMember 161590819 Nov '08 - 4:20 
QuestionVB ?memberFernando Velazco29 Sep '08 - 13:46 
GeneralMultiple DataTables inside DataSetmemberJames Luterek3 Sep '08 - 4:41 
Questionhow to convert datagridview content to dataset?memberSaeed.3949 May '08 - 21:31 

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 28 May 2005
Article Copyright 2005 by Xodiak
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid