使用 C# 和 OleDbConnection 将 DataTable 导出到 Excel - 仅写入列名
Exporting DataTable to Excel with C# and OleDbConnection - Only column names are written
我想将包含多个数据表的数据集写入 Excel 文件中。每个 DataTable 都有自己的工作表。它到目前为止有效,但每个工作表只写列标题(= DataTable 的列)。有没有办法调试为什么没有写入值?
我也在尝试识别数据类型,会不会出错?
public static void ExportExcelTable(string filename, DataSet dataset)
{
var excelConnectionString = GetExcelConnectionString(filename);
using (var connection = new OleDbConnection(string.Format(excelConnectionString, filename)))
{
connection.Open();
foreach (DataTable datatable in dataset.Tables)
{
using (var createCmd = connection.CreateCommand())
{
createCmd.CommandText = CreateTable(datatable);
createCmd.ExecuteNonQuery();
using (var dataadapter = new OleDbDataAdapter($"SELECT * FROM [{datatable.TableName}]", connection))
{
using (var builder = new OleDbCommandBuilder(dataadapter))
{
builder.RefreshSchema();
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";
dataadapter.InsertCommand = builder.GetInsertCommand();
dataadapter.Update(datatable);
}
}
}
}
}
}
static string GetExcelConnectionString(string file)
{
var props = new Dictionary<string, string>();
var extension = file.Split('.').Last();
switch (extension)
{
case "xls":
props["Provider"] = "Microsoft.Jet.OLEDB.4.0";
props["Extended Properties"] = "Excel 8.0";
break;
case "xlsx":
props["Provider"] = "Microsoft.ACE.OLEDB.12.0;";
props["Extended Properties"] = "Excel 12.0 XML";
break;
default:
throw new Exception($"Fehler: {file}");
}
props["Data Source"] = file;
var sb = new StringBuilder();
foreach (var prop in props)
{
sb.Append(prop.Key);
sb.Append('=');
sb.Append(prop.Value);
sb.Append(';');
}
return sb.ToString();
}
static string CreateTable(DataTable table)
{
string sqlsc = "CREATE TABLE " + table.TableName + " (";
for (int i = 0; i < table.Columns.Count; i++)
{
sqlsc += "\n [" + table.Columns[i].ColumnName + "] ";
string columnType = table.Columns[i].DataType.ToString();
switch (columnType)
{
case "System.Int32":
sqlsc += " int ";
break;
case "System.Int64":
sqlsc += " bigint ";
break;
case "System.Int16":
sqlsc += " smallint";
break;
case "System.Byte":
sqlsc += " tinyint";
break;
case "System.Decimal":
sqlsc += " decimal ";
break;
case "System.DateTime":
sqlsc += " datetime ";
break;
default:
sqlsc += " longtext";
break;
}
sqlsc += ",";
}
return sqlsc.Substring(0, sqlsc.Length - 1) + "\n)";
}
数据适配器使用 DataRow.RowState 来确定 运行 的查询。行需要处于已添加的行状态才能触发 InsertCommand 的使用。如果您以未标记为已添加的方式加载包含行的数据表(例如 ImportRow 或通过某种导致调用 AcceptChanges 的方式,例如即使您执行了 Rows.Add
也调用了它,或者您使用 Filled带有 AcceptChangesDuringFill = true
的数据适配器),没有插入 运行s
我想将包含多个数据表的数据集写入 Excel 文件中。每个 DataTable 都有自己的工作表。它到目前为止有效,但每个工作表只写列标题(= DataTable 的列)。有没有办法调试为什么没有写入值?
我也在尝试识别数据类型,会不会出错?
public static void ExportExcelTable(string filename, DataSet dataset)
{
var excelConnectionString = GetExcelConnectionString(filename);
using (var connection = new OleDbConnection(string.Format(excelConnectionString, filename)))
{
connection.Open();
foreach (DataTable datatable in dataset.Tables)
{
using (var createCmd = connection.CreateCommand())
{
createCmd.CommandText = CreateTable(datatable);
createCmd.ExecuteNonQuery();
using (var dataadapter = new OleDbDataAdapter($"SELECT * FROM [{datatable.TableName}]", connection))
{
using (var builder = new OleDbCommandBuilder(dataadapter))
{
builder.RefreshSchema();
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";
dataadapter.InsertCommand = builder.GetInsertCommand();
dataadapter.Update(datatable);
}
}
}
}
}
}
static string GetExcelConnectionString(string file)
{
var props = new Dictionary<string, string>();
var extension = file.Split('.').Last();
switch (extension)
{
case "xls":
props["Provider"] = "Microsoft.Jet.OLEDB.4.0";
props["Extended Properties"] = "Excel 8.0";
break;
case "xlsx":
props["Provider"] = "Microsoft.ACE.OLEDB.12.0;";
props["Extended Properties"] = "Excel 12.0 XML";
break;
default:
throw new Exception($"Fehler: {file}");
}
props["Data Source"] = file;
var sb = new StringBuilder();
foreach (var prop in props)
{
sb.Append(prop.Key);
sb.Append('=');
sb.Append(prop.Value);
sb.Append(';');
}
return sb.ToString();
}
static string CreateTable(DataTable table)
{
string sqlsc = "CREATE TABLE " + table.TableName + " (";
for (int i = 0; i < table.Columns.Count; i++)
{
sqlsc += "\n [" + table.Columns[i].ColumnName + "] ";
string columnType = table.Columns[i].DataType.ToString();
switch (columnType)
{
case "System.Int32":
sqlsc += " int ";
break;
case "System.Int64":
sqlsc += " bigint ";
break;
case "System.Int16":
sqlsc += " smallint";
break;
case "System.Byte":
sqlsc += " tinyint";
break;
case "System.Decimal":
sqlsc += " decimal ";
break;
case "System.DateTime":
sqlsc += " datetime ";
break;
default:
sqlsc += " longtext";
break;
}
sqlsc += ",";
}
return sqlsc.Substring(0, sqlsc.Length - 1) + "\n)";
}
数据适配器使用 DataRow.RowState 来确定 运行 的查询。行需要处于已添加的行状态才能触发 InsertCommand 的使用。如果您以未标记为已添加的方式加载包含行的数据表(例如 ImportRow 或通过某种导致调用 AcceptChanges 的方式,例如即使您执行了 Rows.Add
也调用了它,或者您使用 Filled带有 AcceptChangesDuringFill = true
的数据适配器),没有插入 运行s