Make sure that your tests are representative of the actual data. Excel handles simple numeric cells much more efficiently than simple text cells - especially when all of the text cells are unique. So, if your data is really going to be made up of 10 character unique strings, by all means use that as your test case. If it's actually going to be mostly numbers, make sure your tests reflect that fact.
For example. I built a simple test using SpreadsheetGear for .NET to generate a 300,000 row by 50 column Open XML (.xlsx) workbook. To create and save to disk with unique numbers took 13.62 seconds on my almost two year old overclocked QX6850 CPU, while creating and saving a 300,000 row by 50 column .xlsx workbook with 10 character unique strings took 78 seconds - 6 times longer for text than for numbers. I will paste the code below and you can run it with the free SpreadsheetGear trial which you can download here.
It is important to note that Open XML (.xlsx) is compressed, so if your data has much redundancy, you are likely to get smaller files with .xlsx than with .csv. This could have a big impact on performance if you are generating workbooks on a web server for consumption over a network.
SpreadsheetGear with the IWorkbook.SaveToStream method, and most other 3rd party Excel compatible libraries will let you save directly to the response stream in an ASP.NET application, so you will be able to avoid saving to disk on the server.
Disclaimer: I own SpreadsheetGear LLC
Here is the test code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SpreadsheetGear;
namespace ConsoleApplication11
{
class Program
{
static void Main(string[] args)
{
var timer = System.Diagnostics.Stopwatch.StartNew();
int rows = 300000;
int sheets = 1;
var workbook = Factory.GetWorkbook();
var sb = new System.Text.StringBuilder();
int counter = 0;
bool numeric = true;
for (int sheet = 0; sheet < sheets; sheet++)
{
// Use the SpreadsheetGear Advanced API which is faster than the IRange API.
var worksheet = (sheet == 0) ? workbook.Worksheets[0] : workbook.Worksheets.Add();
var values = (SpreadsheetGear.Advanced.Cells.IValues)worksheet;
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < 50; col++)
{
if (numeric)
values.SetNumber(row, col, ++counter);
else
{
sb.Length = 0;
// Make a 10 character unique string.
sb.Append(++counter);
System.Diagnostics.Debug.Assert(sb.Length <= 10);
// Make it 10 characters long.
while (sb.Length < 10)
sb.Append((char)('A' + (char)sb.Length));
values.SetText(row, col, sb);
}
}
}
}
Console.WriteLine("Created {0} cells in {1} seconds.", counter, timer.Elapsed.TotalSeconds);
workbook.SaveAs(@"C:\tmp\BigWorkbook.xlsx", FileFormat.OpenXMLWorkbook);
Console.WriteLine("Created and saved {0} cells in {1} seconds.", counter, timer.Elapsed.TotalSeconds);
}
}
}