There is an ADO.NET provider for Excel.
This means, if you have a dataset, you can employ two DataAdapters to move data from one place to another: from Oracle to Excel, from SQL to Excel, from Excel to Oracle, etc.
Fill a DataSet from the source with the first DA, then Update the destination with the second DA. The DataAdapters do not need to be the same type - you can use any of OleDbDataAdapter, SqlDataAdapter, OracleDataAdapter, etc for the read as well as for the update.
No need to fiddle with CSV or XML formatting. No need to use Office Automation, so no PIAs and it works on Servers. It's just ADO.NET.
To connect to Excel, use the Microsoft.Jet.OLEDB oledb provider.
Full Example source.
Excerpt:
System.Data.DataSet ds1;
const string ConnStringSql= "Provider=sqloledb;Data Source=dinoch-8;Initial Catalog=Northwind;Integrated Security=SSPI;" ;
const string OutputFilename= "ExtractToExcel.xls";
const string ConnStringExcel=
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + OutputFilename + ";" +
"Extended Properties=\"Excel 8.0;HDR=yes;\""; // FIRSTROWHASNAMES=1;READONLY=false\"
const string sqlSelect="SELECT top 10 ProductId, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, GETDATE() as Extracted from Products order by UnitPrice";
const string sqlInsert="INSERT INTO Extracto (ProductId, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, Extracted) VALUES (@ProductId, @ProductName, @QuantityPerUnit, @UnitPrice, @UnitsInStock, @Extracted)";
private void ReadFromSql()
{
var ConnSql= new System.Data.OleDb.OleDbConnection(ConnStringSql);
var da1 = new System.Data.OleDb.OleDbDataAdapter();
da1.SelectCommand= new System.Data.OleDb.OleDbCommand(sqlSelect);
da1.SelectCommand.Connection= ConnSql;
ds1= new System.Data.DataSet();
da1.Fill(ds1, "Extracto");
}
private void InsertIntoExcel()
{
// need to update the row so the DA does the insert...
foreach (System.Data.DataRow r in ds1.Tables[0].Rows)
{
r["Extracted"]= System.DateTime.Now; // update the row
}
var da2 = new System.Data.OleDb.OleDbDataAdapter();
da2.UpdateCommand= new System.Data.OleDb.OleDbCommand(sqlInsert);
da2.UpdateCommand.Connection= ConnExcel;
da2.UpdateCommand.Parameters.Add("@ProductId", System.Data.OleDb.OleDbType.Integer, 4, "ProductId");
da2.UpdateCommand.Parameters.Add("@ProductName", System.Data.OleDb.OleDbType.VarWChar, 40, "ProductName");
da2.UpdateCommand.Parameters.Add("@QuantityPerUnit", System.Data.OleDb.OleDbType.VarWChar, 20, "QuantityPerUnit");
da2.UpdateCommand.Parameters.Add("@UnitPrice", System.Data.OleDb.OleDbType.Currency, 8, "UnitPrice");
da2.UpdateCommand.Parameters.Add("@UnitsInStock", System.Data.OleDb.OleDbType.SmallInt, 2, "UnitsInStock");
da2.UpdateCommand.Parameters.Add("@Extracted", System.Data.OleDb.OleDbType.Date, 8, "Extracted");
da2.Update(ds1, "Extracto");
}
This is not Excel automation, so the caveats that apply to using Excel Automation on the server do not apply.
You can start with a existing XLS file (or XLSX), and just fill in a named range. This gives you the opportunity to apply formatting and so on, prior to inserting the ilve data. In essence the existing XLS file is a template.
Or, you can start from nothing and create the XLS file, and the table/range within the XLS file, completely dynamically, at runtime. In this case the XLS file will be pretty vanilla / plain. No formatting, colors, formulas, and so on.