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
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();
}
}
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.