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

Generate Excel files without using Microsoft Excel

By , 22 Jun 2011
 

Introduction

Generating Excel files from web pages or other applications is a major subject in many articles. I'd like to present here a solution that does not require MS Excel to be installed on the target computer. This article shows how to create Microsoft Excel Binary Interchange File Format (BIFF) without using Microsoft Excel. BIFF is the native file format for Excel data, and can be viewed and modified in Microsoft Excel 97 or later.

Approaches and problems

The technique that is most frequently used to transfer data to an Excel workbooks is Automation. With Automation, you can call methods and properties that are specific to Excel tasks, but this solution has many drawbacks. Some of them are described in the Microsoft Knowledge Base. Additionally, you have to manage the lifetime of the temporary XLS files created on the server. Also, it is slow, because Excel runs in a separate process.

ExcelWriter class

The solution presented here is to write directly to a stream in Excel binary file format. For this purpose, I created very small C# class called ExcelWriter.

ExcelWriter class diagram
/// <summary>
/// Produces Excel file without using Excel
/// </summary>
public class ExcelWriter
{
    private Stream stream;
    private BinaryWriter writer;

    private ushort[] clBegin = { 0x0809, 8, 0, 0x10, 0, 0 };
    private ushort[] clEnd = { 0x0A, 00 };


    private void WriteUshortArray(ushort[] value)
    {
        for (int i = 0; i < value.Length; i++)
            writer.Write(value[i]);
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="ExcelWriter"/> class.
    /// </summary>
    /// <param name="stream">The stream.</param>
    public ExcelWriter(Stream stream)
    {
        this.stream = stream;
        writer = new BinaryWriter(stream);
    }

    /// <summary>
    /// Writes the text cell value.
    /// </summary>
    /// <param name="row">The row.</param>
    /// <param name="col">The col.</param>
    /// <param name="value">The string value.</param>
    public void WriteCell(int row, int col, string value)
    {
        ushort[] clData = { 0x0204, 0, 0, 0, 0, 0 };
        int iLen = value.Length;
        byte[] plainText = Encoding.ASCII.GetBytes(value);
        clData[1] = (ushort)(8 + iLen);
        clData[2] = (ushort)row;
        clData[3] = (ushort)col;
        clData[5] = (ushort)iLen;
        WriteUshortArray(clData);
        writer.Write(plainText);
    }

    /// <summary>
    /// Writes the integer cell value.
    /// </summary>
    /// <param name="row">The row number.</param>
    /// <param name="col">The column number.</param>
    /// <param name="value">The value.</param>
    public void WriteCell(int row, int col, int value)
    {
        ushort[] clData = { 0x027E, 10, 0, 0, 0 };
        clData[2] = (ushort)row;
        clData[3] = (ushort)col;
        WriteUshortArray(clData);
        int iValue = (value << 2) | 2;
        writer.Write(iValue);
    }

    /// <summary>
    /// Writes the double cell value.
    /// </summary>
    /// <param name="row">The row number.</param>
    /// <param name="col">The column number.</param>
    /// <param name="value">The value.</param>
    public void WriteCell(int row, int col, double value)
    {
        ushort[] clData = { 0x0203, 14, 0, 0, 0 };
        clData[2] = (ushort)row;
        clData[3] = (ushort)col;
        WriteUshortArray(clData);
        writer.Write(value);
    }

    /// <summary>
    /// Writes the empty cell.
    /// </summary>
    /// <param name="row">The row number.</param>
    /// <param name="col">The column number.</param>
    public void WriteCell(int row, int col)
    {
        ushort[] clData = { 0x0201, 6, 0, 0, 0x17 };
        clData[2] = (ushort)row;
        clData[3] = (ushort)col;
        WriteUshortArray(clData);
    }

    /// <summary>
    /// Must be called once for creating XLS file header
    /// </summary>
    public void BeginWrite()
    {
        WriteUshortArray(clBegin);
    }

    /// <summary>
    /// Ends the writing operation, but do not close the stream
    /// </summary>
    public void EndWrite()
    {
        WriteUshortArray(clEnd);
        writer.Flush();
    }
}

Using the code

The ExcelWriter sample is a console application that writes an XLS file to the name and location specified. The XLS file that is created is simply an empty spreadsheet. Then, you can start to write cell values by calling the WriteCell method with the row number, column number, and a cell value as parameters:

namespace XLSExportDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            FileStream stream = new FileStream("demo.xls", FileMode.OpenOrCreate);
            ExcelWriter writer = new ExcelWriter(stream);
            writer.BeginWrite();
            writer.WriteCell(0, 0, "ExcelWriter Demo");
            writer.WriteCell(1, 0, "int");
            writer.WriteCell(1, 1, 10);
            writer.WriteCell(2, 0, "double");
            writer.WriteCell(2, 1, 1.5);
            writer.WriteCell(3, 0, "empty");
            writer.WriteCell(3, 1);
            writer.EndWrite();
            stream.Close();
        }
    }
}

The picture below shows the final result of this sample:

The ExcelWriter class supports numeric and text values for the cells, and can be used for exporting data from the database to an XLS file, or for producing an XLS stream from a website on the fly.

I hope this article gives you a head start in working with Excel files from .NET and C#.

History

  • 03 March 2009 - Initial submission.

License

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

About the Author

Serhiy Perevoznyk
Architect
Belgium Belgium
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   
QuestionMultiple SheetsmemberMember 810781128 Oct '12 - 16:09 
Is it possible to use this if I need to save an excel file with multiple sheets?
Questionlimited to 255 chars per cell. how we can increase the limit ..?memberaisoft19 Oct '12 - 5:50 
limited to 255 chars per cell. how we can increase the limit ..?
QuestionGenerating Excelmembernirajzambad7 Aug '12 - 3:03 
What if i dont want to create new instance of excel sheet and write to the previous excel file
and to the next row where i stopped last time
GeneralMy vote of 5memberHuỳnh Hữu Ân24 Jul '12 - 18:06 
This excellent. Now i can export data to excel without microsoft com or oledb! bd
QuestionThe generated xls file could not be read by OLEDBmemberdaiwuju4 Jul '12 - 22:57 
DataTable dataTable_Excel;
string strExcelFile = FileOpen;
strExcelFile = string.Format("Provider = Microsoft.Jet.OLEDB.4.0; Data Source = {0}; Extended Properties = \"Excel 8.0; HDR = Yes; IMEX = 1\";",strExcelFile);
OleDbConnection conOLDB = new OleDbConnection(strExcelFile);
conOLDB.Open();
DataTable dataTable_ExcelSheet = conOLDB.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string sheetName = dataTable_ExcelSheet.Rows[0]["TABLE_NAME"].ToString().Trim();
string selectstr = string.Format("SELECT * FROM [{0}]", sheetName);
OleDbCommand selectCommand = new OleDbCommand(selectstr, conOLDB);
OleDbDataAdapter daExcel = new OleDbDataAdapter();
daExcel.SelectCommand = selectCommand;
daExcel.Fill(dataTable_Excel);
conOLDB.Close();
conOLDB.Dispose();
QuestionA minor problem in Chinese Fontmemberdaiwuju29 Jun '12 - 19:05 
When I set private Font defaultFont = new Font("宋体", 10), the font shows in the excel is '??'.
QuestionMere cellsmemberdaniloao31 May '12 - 13:50 
Can I merge cells?
QuestionBordersmemberMember 901259929 May '12 - 6:49 
Hello all,
 
So far this works great. Formatting and file creation can be done with ease. However, I notice that this does not have option to make border (e.g. for creating table on a worksheet). Am I missing something or is there really not a way to set the border settings for each cell?
 
Thank you for your help
QuestionMore Than one WorkSheetmemberhichamveo24 May '12 - 6:57 
Hi,
thanks for this good article.But i want to add more than one worksheet by xls file.
any idea about this need?thanks
sdfrt

QuestionGreat work!!memberCurtCobrain7 Apr '12 - 4:57 
Thank you very much !!
GeneralMy vote of 5memberMikhail Tsennykh (devnoob)19 Mar '12 - 8:50 
Awesome, thank you!
QuestionCreating .XLSX filememberbhavtosh.sharma2 Mar '12 - 0:57 
hi,
firstly, a very handy way of creating excel on the fly. i tried your solution to create excel 2010 format as .XLSX file which was saved but while opening it, excel didnt open it as there was an error saying the file format is not same as per the .xlsx extension...
 
any view to share...
Thanks and Good Day,
Bhavtosh

AnswerRe: Creating .XLSX filememberdaiwuju29 Jun '12 - 19:00 
Maybe you could have a look at this: http://lateral8.com/articles/2010/3/5/openxml-sdk-20-export-a-datatable-to-excel.aspx[^]
QuestionProtected Viewmemberccchg9 Feb '12 - 0:22 
This is a very interesting way to generate Excel. However, I encounter problem when opening the generated Excel file with Protected View restriction. I opened the generated file using Microsoft Office 2010.
 
When I enable "Excel 3 Worksheets" to open as normal rather than in Protected View, then I do not face Protected View restriction message anymore.
 
Does it any excel version or file type specify in the code? How shall we able to generate the Excel with later version to avoid Protected View restriction?
 
Thank you
QuestionSpecial characters are not comingmemberiliyash11 Jan '12 - 4:37 
I have data which have some special characters. while writing the data in cell all these characters converted to " ?".
Please give the solution for this type of data.
AnswerRe: Special characters are not comingmemberiliyash11 Jan '12 - 20:42 
Change Encoding format As following:
 
byte[] plainText = Encoding.Default.GetBytes(newValue);
QuestionprintmemberMember 85283912 Jan '12 - 10:17 
how do i print that excel file without using microsoft interop? Thanks...
QuestionI get an Office File Validation warningmemberLeo Muller19 Dec '11 - 20:27 
Hi, very nice code, simple and to the point.
 
I tried it out, and it worked, but when I open the XLS file, office 2007 gives me this message: "Office File Validation detected a problem while trying to open this file. Opening it may be dangerous".
 
The file opened fine, but I can't give this to our end users like this. Any idea why the created file doesn't pass the office file validator?
GeneralMy vote of 5memberMember 366623525 Nov '11 - 0:10 
It has solved a big problem for me. I wanted to generate stock taking data in the excel format but without using excel.
 
Thanks for such a wonderful code
 
Sanjay Batra, India
QuestionHO TO MERGE COLUMS AND ROWSmembersheriefes11 Nov '11 - 0:08 

Questioninsert imagememberJorge Teodoro1 Nov '11 - 9:08 
Hi,
How to insert image in the cell without using class worksheet?
QuestionExcel file gives error on openingmembershubhamalhotra17 Oct '11 - 3:18 
Hi,
 
I am able to create a file with extension .xls using ExcelWriter class provided above. But for any field if i have large data(like 500 chars or more) it creates file without any error, but when i open the file in MS excel it gives error on open saying "File Error: you may have lost some data."
 
Please suggest what i am missing here.
Questionwarrior!that would be perfect if ExcelReader.cs and ExcelSheet is adding to the filememberbatsword13 Sep '11 - 16:31 
Laugh | :laugh:
QuestionMy vote of 5memberFilip D'haene9 Sep '11 - 5:58 
Excellent!
 
Thanks for sharing. Smile | :)
QuestionAdding new work sheet would be a great feature in the next versionmemberNikolay Dovgaluk1 Aug '11 - 4:06 
Hi, Serhiy
 
Thank's for you job. It is a great and useful example of how to export data to excel, however adding support for worksheet would be a great feature in the next release.
 
Serhiy, can we count on the next version?
QuestionHow to create 2nd Excel sheet using your method?memberMember 399944929 Jul '11 - 18:50 
Hi thanks for sharing this article. I used your method to generate Excel file with one sheet successfully. Now can you tell me how can I create the 2nd excel sheet?
 

Regards,
Asif
AnswerRe: How to create 2nd Excel sheet using your method?memberAA123546548978917 May '12 - 4:00 
I am also looking into this.
 
Did you find the solution?
AnswerRe: How to create 2nd Excel sheet using your method?memberKapilDesai28 Aug '12 - 21:48 
Waiting for the solution.....as i am having more than 65536 rows to be exported into excel.....
QuestionVery Easymembertexgfalco30 Jun '11 - 13:32 
I added 2 method to ExcelDocument for to adapt a column's width at a cell's value:
 
        public int getColumnWidth(int column)
        {
            int idx;
            ColumnInfo info = new ColumnInfo();
            info.Index = column;
            idx = columns.IndexOf(info);
            if (idx == -1)
                return -1;
            else
                return columns[idx].Width;
        }
 
        public void adaptColumnWidth(int row, int column)
        {
            Size size = TextRenderer.MeasureText(this[row, column].Value.ToString(), defaultFont);
            
            int idx;
            ColumnInfo info = new ColumnInfo();
            info.Index = column;
            info.Width = size.Width;
            idx = columns.IndexOf(info);
            if (idx == -1)
                columns.Add(info);
            else if (getColumnWidth(column) < size.Width)
                columns[idx].Width = size.Width;
        }
 
Serhiy good work Wink | ;)
AnswerRe: Very EasymemberSerhiy Perevoznyk1 Jul '11 - 9:37 
Good idea. I will include your code in the next update. Thank you
GeneralMy vote of 5memberJamal Alqabandi27 Jun '11 - 23:59 
Thank you.
QuestionnoobmemberBarbo23 Jun '11 - 3:29 
you noob, this class is for dummies... learn how to program..
AnswerRe: noobmemberAORD22 May '12 - 12:10 
Clearly Barbo you are out of touch with reality. The article is obviously a solution or provides a direction to many people, read the feed back. Your comments lack reasons and examples which make you look like a fool. Looking forward to reading some of your articles.
___________________________
 
Here come the machines!

GeneralMy vote of 5memberOmar Gamil22 Jun '11 - 21:38 
very useful, Thank you Wink | ;)
is there a "Read" method ?
GeneralAlternative way to create Excel files without the need of Excel beeing installed [modified]memberaron.sinoai16 Jun '11 - 12:02 
You can create nicely formatted Excel files very easily using this library, by reusing parts from a secondary Excel file (even entire worksheets):
http://officehelper.codeplex.com/documentation
Microsoft Office does not need to be installed on the target machine!

modified 24 Feb '12 - 11:27.

GeneralHow to do CELL FormatmemberMember 390017225 May '11 - 20:55 
Can anybody tell me how to do the CELL FORMAT using this class.....
GeneralRe: How to do CELL FormatmemberSerhiy Perevoznyk22 Jun '11 - 9:34 
You can read about this in the second part of the article on http://delphi32.blogspot.com/2011/06/generate-excel-files-without-using.html[^]
GeneralHow can we format a cell like make it bold or give a background color using your write cell function?memberSamar pratap28 Apr '11 - 8:01 
public void WriteCell(int row, int col, string value)
{
ushort[] clData = { 0x0204, 0, 0, 0, 0, 0 };
int iLen = value.Length;
byte[] plainText = Encoding.ASCII.GetBytes(value);
clData[1] = (ushort)(8 + iLen);
clData[2] = (ushort)row;
clData[3] = (ushort)col;
clData[5] = (ushort)iLen;
WriteUshortArray(clData);
writer.Write(plainText);
}
 
What I need to include in order to make this cell bold. A simple example wud help and saves mine time...
 
Thanks
GeneralRe: How can we format a cell like make it bold or give a background color using your write cell function?memberMember 390017225 May '11 - 21:01 
Have u got any idea on this..?
GeneralRe: How can we format a cell like make it bold or give a background color using your write cell function?memberSerhiy Perevoznyk22 Jun '11 - 9:35 
You can read how to format the cell (including the simple example) here: http://delphi32.blogspot.com/2011/06/generate-excel-files-without-using.html[^]
GeneralCodepage problemsmemberTiMiNOd9 Apr '11 - 2:32 
Hi!! nice code. I have problems in codepage or etc.
I speak Russian and UKR, and very bad in English Smile | :)
 
DataGrid value is "тест ABC123"
Export to .xls file "???? ABC123"
 
What's the problem?
GeneralRe: Codepage problemsmemberTiMiNOd9 Apr '11 - 3:26 
The problem was covered in ASCII to the coding, another doesn't support
Cry | :((
GeneralRe: Codepage problemsmemberSerhiy Perevoznyk22 Jun '11 - 9:39 
I updated the code and added the new CodePage property. You can see the sample and download the source code here: http://delphi32.blogspot.com/2011/06/generate-excel-files-without-using.html[^]
GeneralNicememberCikaPero28 Mar '11 - 23:57 
Your code can be used for very fast sequential writing of simple Excel files and you have a 5 for that.
 
If your are looking for more 'rich' solution that is also very fast and doesn't use Microsoft Excel, check out this Excel C# / VB.NET library.
GeneralMy vote of 5memberJesper Bihrmann2 Feb '11 - 3:05 
I have testet a lot of different libraries and most of them have some issues and are werry big. This is small and it just works.
GeneralI didn't open excel file was generated by your codememberHelen.Yu14 Jan '11 - 13:40 
hi,
thank for sharing your code, It's cool.
 
I run your project and tried to open excel file that was generated.but it was threw exception using excel 2010 version.
 
pls help me, thanks.
QuestionHow to write a Cell with DateTime format?memberMark Carranza12 Jan '11 - 19:59 
Hi, thanks for the Date Format example. I'm trying to add a DateTime value and am stuck trying to figure out RK value. Please create an example WriteCell() with a numeric value that has date and time.
writer.WriteFormat(@"dd/mm/yyyy hh:mm:ss.00")  // format 2
writer.WriteCell(4, 0, "date and time");
writer.WriteDateTimeCell(4, 1, DateTime.Now, 2);
Thanks!
GeneralMy vote of 4membercimsunf29 Nov '10 - 4:23 
very simple and helpful
GeneralMy vote of 4memberrlejason28 Nov '10 - 20:42 
useful article
GeneralNPOI.codeplex.com .NET library (open source) could be considered as alternative, has more and source codememberAlexandreN12 Nov '10 - 8:03 
good job, but please consider: http://npoi.codeplex.com/releases/view/49524, it has source code on c#, samples, documentation, etc.

modified on Friday, November 12, 2010 2:20 PM

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 22 Jun 2011
Article Copyright 2009 by Serhiy Perevoznyk
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid