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

 
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   
Generalvery cool stuffmemberJerry139 May '13 - 2:31 
QuestionI can't open the generated XLS file through Excel 2010memberJosen.L.Zhang9 Apr '13 - 0:03 
AnswerRe: I can't open the generated XLS file through Excel 2010membersangheraajit14 Apr '13 - 22:04 
GeneralMy vote of 5memberDineshMaind5 Mar '13 - 6:01 
QuestionPlease add Border Style at next upgradememberphong104057224 Jan '13 - 16:29 
SuggestionColumn Width AutoFit?mvpadriancs9 Jan '13 - 14:46 
SuggestionCode Patch, Write DataTable [modified]mvpadriancs9 Jan '13 - 14:01 
QuestionIs it possible to Write stream to respose headers instead of a demo.xls file?membershabari713 Dec '12 - 0:25 
QuestionMore feature rich alternativememberAndrew Kirillov11 Nov '12 - 22:30 
AnswerRe: More feature rich alternativememberMember 940799029 Mar '13 - 16:58 
QuestionMultiple SheetsmemberMember 810781128 Oct '12 - 16:09 
Questionlimited to 255 chars per cell. how we can increase the limit ..?memberaisoft19 Oct '12 - 5:50 
QuestionGenerating Excelmembernirajzambad7 Aug '12 - 3:03 
GeneralMy vote of 5memberHuỳnh Hữu Ân24 Jul '12 - 18:06 
QuestionThe generated xls file could not be read by OLEDBmemberdaiwuju4 Jul '12 - 22:57 
QuestionA minor problem in Chinese Fontmemberdaiwuju29 Jun '12 - 19:05 
QuestionMere cellsmemberdaniloao31 May '12 - 13:50 
QuestionBordersmemberMember 901259929 May '12 - 6:49 
QuestionMore Than one WorkSheetmemberhichamveo24 May '12 - 6:57 
QuestionGreat work!!memberCurtCobrain7 Apr '12 - 4:57 
GeneralMy vote of 5memberMikhail Tsennykh (devnoob)19 Mar '12 - 8:50 
QuestionCreating .XLSX filememberbhavtosh.sharma2 Mar '12 - 0:57 
AnswerRe: Creating .XLSX filememberdaiwuju29 Jun '12 - 19:00 
QuestionProtected Viewmemberccchg9 Feb '12 - 0:22 
QuestionSpecial characters are not comingmemberiliyash11 Jan '12 - 4:37 
AnswerRe: Special characters are not comingmemberiliyash11 Jan '12 - 20:42 
QuestionprintmemberMember 85283912 Jan '12 - 10:17 
QuestionI get an Office File Validation warningmemberLeo Muller19 Dec '11 - 20:27 
GeneralMy vote of 5memberMember 366623525 Nov '11 - 0:10 
QuestionHO TO MERGE COLUMS AND ROWSmembersheriefes11 Nov '11 - 0:08 
Questioninsert imagememberJorge Teodoro1 Nov '11 - 9:08 
QuestionExcel file gives error on openingmembershubhamalhotra17 Oct '11 - 3:18 
Questionwarrior!that would be perfect if ExcelReader.cs and ExcelSheet is adding to the filememberbatsword13 Sep '11 - 16:31 
QuestionMy vote of 5memberFilip D'haene9 Sep '11 - 5:58 
QuestionAdding new work sheet would be a great feature in the next versionmemberNikolay Dovgaluk1 Aug '11 - 4:06 
QuestionHow to create 2nd Excel sheet using your method?memberMember 399944929 Jul '11 - 18:50 
AnswerRe: How to create 2nd Excel sheet using your method?memberAA123546548978917 May '12 - 4:00 
AnswerRe: How to create 2nd Excel sheet using your method?memberKapilDesai28 Aug '12 - 21:48 
QuestionVery Easymembertexgfalco30 Jun '11 - 13:32 
AnswerRe: Very EasymemberSerhiy Perevoznyk1 Jul '11 - 9:37 
GeneralMy vote of 5memberJamal Alqabandi27 Jun '11 - 23:59 
QuestionnoobmemberBarbo23 Jun '11 - 3:29 
AnswerRe: noobmemberAORD22 May '12 - 12:10 
GeneralMy vote of 5memberOmar Gamil22 Jun '11 - 21:38 
GeneralAlternative way to create Excel files without the need of Excel beeing installed [modified]memberaron.sinoai16 Jun '11 - 12:02 
GeneralHow to do CELL FormatmemberMember 390017225 May '11 - 20:55 
GeneralRe: How to do CELL FormatmemberSerhiy Perevoznyk22 Jun '11 - 9:34 
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 
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 
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 

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.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