c# - 使用 C# 和 OleDbConnection 将 DataTable 导出到 Excel - 仅写入列名
问题描述
我想将具有多个 DataTables 的 DataSet 写入 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
了,或者您使用带有 的数据适配器填充AcceptChangesDuringFill = true
),没有插入运行
推荐阅读
- flutter - 管理图像/视频路径以供以后使用
- javascript - 无法在 vue.js 中将数据从 false 更改为 true
- c - 在 c 编程中为第二个函数添加原型
- python - DBT 和 Liquibase(创建表)
- c# - 将图像移动到剪贴板不起作用c#
- c# - C# 将物理文件转换为 iformfile
- python-3.x - ValueError 尽管尝试和除外
- python - Python中是否有一种简单的方法可以在不知道扩展名的情况下按名称获取文件?
- c++ - 用于循环编译的 constexpr
- storekit - 通过 productsRequest:didReceiveResponse 返回的 SKProduct 在生产中没有 .introductoryPrice,但沙盒符合预期