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

Generate Excel file on the fly without using Microsoft Excel and download it in a chunk-chunk way

By , 12 May 2012
 

Couple of days ago I was working with Excel file manipulation. The requirement was like that the file has to be created on the fly based on the data getting from database and then download it to the client PC. So what I did here is that, I have just created the excel file on the fly and send the data to the client in a chunk way. To do that, I wrote a handler which takes the key as the request, getting the data based on the key from the database, write the excel file and then download it to the chunk way. Fortunately, I have got an excellent article in code project which helped me for generating excel files without using Microsoft Excel.

The Handler class is given below,

public void ProcessRequest(HttpContext context)
{
    HttpRequest request = context.Request;   
    System.IO.MemoryStream currentStream = null;    
    byte[] buffer = new Byte[10000];   
    int length;  
    long dataToRead;    
    string fileName = request["FileName"];
    System.Collections.Generic.List<Test> lstTest = "Your List of Test Object";
    
    try
    {
        currentStream = new System.IO.MemoryStream();
        ExcelWriter writer = new ExcelWriter(currentStream);
        writer.BeginWrite();       
        writer.WriteCell(0, 0, "Title");
        writer.WriteCell(0, 1, "FirstName");
        writer.WriteCell(0, 2, "Surname");
        writer.WriteCell(0, 3, "Email");
        writer.WriteCell(0, 4, "TelePhoneNumber");
        writer.WriteCell(0, 5, "OrderNumber");
        writer.WriteCell(0, 6, "SubmissionDate");
        
        if (lstTest != null)
        {        
            for (int row = 0; row < lstTest.Count; row++)
            {
                writer.WriteCell(row + 1, 0, lstTest[row].Title);
                writer.WriteCell(row + 1, 1, lstTest[row].FirstName);
                writer.WriteCell(row + 1, 2, lstTest[row].SurName);
                writer.WriteCell(row + 1, 3, lstTest[row].Email);
                writer.WriteCell(row + 1, 4, lstTest[row].TelePhoneNumber);
                writer.WriteCell(row + 1, 5, lstTest[row].OrderNumber);
                writer.WriteCell(row + 1, 6, lstTest[row].SubmissionDate);
            }
        }
        writer.EndWrite();
        currentStream.Position = 0;
        context.Response.AddHeader("Content-Length", currentStream.Length.ToString());
        context.Response.AddHeader("Accept-Ranges", "bytes");
        context.Response.Buffer = false;
        context.Response.AddHeader("Connection", "Keep-Alive");
        context.Response.ContentType = "application/octet-stream";
        context.Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
       
        dataToRead = currentStream.Length;
        context.Response.ContentType = "application/octet-stream";
       
        while (dataToRead > 0)
        {       
            if (context.Response.IsClientConnected)
            {            
                length = currentStream.Read(buffer, 0, 10000);            
                context.Response.OutputStream.Write(buffer, 0, length);            
                context.Response.Flush();
                buffer = new Byte[10000];
                dataToRead = dataToRead – length;
            }
            else
            {            
                dataToRead = -1;
            }
        }
    }
    catch (Exception ex)
    {
        context.Response.Write(ex);
    }
    finally
    {
        if (currentStream != null)
        {   
            currentStream.Close();
            currentStream.Dispose();
        }
    }
}

The Test Class is given below

public class Test
{    
    public Test()
    {
    }
    public string Title { get; set; }

    public string FirstName { get; set; }
    
    public string SurName { get; set; }
   
    public string Email { get; set; }
     
    public string TelePhoneNumber { get; set; }

    public string OrderNumber { get; set; }
   
    public string SubmissionDate { get; set; }  
}
This is the ExcelWriter class. The code has been taken from this article
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]);
    } 
    public ExcelWriter(Stream stream)
    {
        this.stream = stream;
        writer = new BinaryWriter(stream);
    }   
    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);
    }   
    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);
    }   
    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);
    }   
    public void WriteCell(int row, int col)
    {
        ushort[] clData = { 0x0201, 6, 0, 0, 0x17 };
        clData[2] = (ushort)row;
        clData[3] = (ushort)col;
        WriteUshortArray(clData);
    }  
    public void BeginWrite()
    {
        WriteUshortArray(clBegin);
    }   
    public void EndWrite()
    {
        WriteUshortArray(clEnd);
        writer.Flush();
    }
}

License

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

About the Author

Md. Rashim uddin
Software Developer (Senior) KAZ Software Limited.
Bangladesh Bangladesh
Member
I am nothing more than a simple man with the high vision of evolving multifaceted software systems by using my technical and interpersonal skills which will complement my professional growth. I feel enjoyment to take challenges to resolve those technical problems which are yet to be solved.
 
My Blog: http://rashimuddin.wordpress.com/
 
My Email: rashimiiuc at yahoo dot com

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   
Questionspecial characters in textmembermazzat1 Dec '12 - 23:57 
Hi, im using this code - but ascii does not support æøå and other special characters. Is it possible to create a simular class the uses unicode og utf32?
 

I have tried to change Encoding in the writecell - but then excel cannot open the file - excel states that file is corrupt.
GeneralThanks.memberSaily21 Aug '12 - 6:08 
It is what i was looking for. Thank a bunch.
SuggestionBritish currencymemberfritterfatboy18 Jun '12 - 7:07 
The £ (GBP) symbol doesn't work as this is not an ASCII character.
 
It's not pretty, but the following works (sorry, I'm not C# - but conversion is easy):
 
    Public Sub WriteCell(row As Integer, col As Integer, value As String)
        If value.StartsWith("£") Then
            Dim currencyVal As Double
            If Double.TryParse(value.Remove(0, 1), currencyVal) Then
                WriteCell(row, col, currencyVal)
                Return
            End If
        End If
        Dim clData As UShort() = {&H204, 0, 0, 0, 0, 0}
        Dim iLen As Integer = value.Length
        Dim plainText As Byte() = Encoding.ASCII.GetBytes(value)
        clData(1) = CUShort(8 + iLen)
        clData(2) = CUShort(row)
        clData(3) = CUShort(col)
        clData(5) = CUShort(iLen)
        WriteUshortArray(clData)
        writer.Write(plainText)
    End Sub

GeneralMy vote of 5memberMember 432084427 May '12 - 9:53 
Thanks.
I think you should write that
your Code is C# or else.
Or The article Title should point to C#, may be better.
QuestionChunk way?memberHaBiX15 May '12 - 0:04 
I don't get it. What is chunky here?
 
**edit
 
If you're referring to "while (dataToRead > 0)" block, that does nothing useful - you're re-making what's already there.
 
The same would be achieved if you turned Response buffer on, and used response stream (instead of memory stream). After generating xls data in your response buffer, you can call Flush to send it (instead of copying to byte array and then copying again to response stream).
QuestionNew Worksheetmembersalimbai21 Mar '12 - 20:02 
Please help me how to add new worksheet. Because I want to export many tabbed information to Excel.
AnswerRe: New WorksheetmemberBruce Goodman5 Jun '12 - 22:02 
Hi,
 
you can try this Excel C# library to create Excel file with multiple worksheets.
Here is a sample C# code:
// Create new Excel file.
var excelFile = new ExcelFile();
 
// Add new worksheet to the excel file.
var worksheet1 = excelFile.Worksheets.Add("Sheet 1");
 
worksheet1.Cells["A1"].Value = "This is first worksheet";
 
// Add new worksheet to the excel file.
var worksheet2 = excelFile.Worksheets.Add("Sheet 2");
 
worksheet2.Cells["A1"].Value = "This is second worksheet";
 
// Save excel file to an XLS file.
excelFile.SaveXls(fileName);

GeneralMy vote of 5memberenamur18 Mar '12 - 19:55 
good stuff
GeneralRe: My vote of 5memberMd. Rashim uddin18 Mar '12 - 20:11 
Thanks

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.130523.1 | Last Updated 12 May 2012
Article Copyright 2012 by Md. Rashim uddin
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid