c# - 使用 OleDb 写入 Excel

标签 c# oledb export-to-excel oledbdataadapter

我正在尝试将数据行从 sql 导出到 Excel,但我的插入命令似乎每次都失败。我花了很多时间尝试创建这个,但最终却碰壁了。

Excel 文档是由 IRS 生成的,我们不会大声修改第 16 行以上的任何内容。第 16 行是标题行,其下方的所有内容都需要是来自 sql 的数据。 header 名称中都有空格,这似乎是我遇到麻烦的地方。

从第 16 行开始,列名称为: 与会者名字、与会者姓氏、与会者 PTIN、计划编号、授予计划的 CE 小时数、完成日期

这就是我尝试写入Excel的方式

private void GenerateReport()
{
    FileInfo xlsFileInfo = new FileInfo(Server.MapPath(CE_REPORTS_PATH + CE_PTIN_TEMPLATE + EXTENSION));

    string connectionString = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes'", xlsFileInfo.FullName);

    //create connection
    OleDbConnection oleDBConnection = new OleDbConnection(connectionString);
    oleDBConnection.Open();

    //create the adapter with the select to get 
    OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$A16:F16]", oleDBConnection);

    // Create the dataset and fill it by using the adapter.
    DataTable dataTable = new DataTable();
    adapter.FillSchema(dataTable, SchemaType.Source);
    adapter.Fill(dataTable);

    string[] colNames = new string[dataTable.Columns.Count];
    string[] colParms = new string[dataTable.Columns.Count];

    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        colNames[i] = String.Format("[{0}]", dataTable.Columns[i].ColumnName);
        colParms[i] = "?";
    }

    // Create Insert Command
    adapter.InsertCommand = new OleDbCommand(String.Format("INSERT INTO [Sheet1$] ({0}) values ({1})", string.Join(",", colNames), string.Join(",", colParms)), oleDBConnection);

    // Create Paramaters
    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        OleDbParameter param = new OleDbParameter(String.Format("@[{0}]", dataTable.Columns[i].ColumnName), OleDbType.Char, 255, dataTable.Columns[i].ColumnName);
        adapter.InsertCommand.Parameters.Add(param);
    }

    // create a new row
    DataRow newCERecord = dataTable.NewRow();

    // populate row with test data
    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        newCERecord[i] = "new Data";
    }
    dataTable.Rows.Add(newCERecord);

    // Call update on the adapter to save all the changes to the dataset
    adapter.Update(dataTable);

    oleDBConnection.Close();     
}

调用adapter.Update(dataTable)时发生的错误如下

$exception  {"The INSERT INTO statement contains the following unknown field name: 'Attendee First Name'. Make sure you have typed the name correctly, and try the operation again."}   System.Exception {System.Data.OleDb.OleDbException}

这令人沮丧,因为我直接从 colNames[i] = String.Format("[{0}]", dataTable.Columns[i].ColumnName) 获取的列名称中提取每个字段。我发现我需要 [] 来解释列名称中的空格,但此时我不确定问题是什么。当我查看 Excel 文件时,一切似乎都是正确的。

最佳答案

我实际上为您找到了一篇 Microsoft 文章,其中包含完整的代码 - 您可以复制并粘贴您最喜欢的任何解决方案。链接如下:

http://support.microsoft.com/kb/306023

似乎使用 CopyRecordset 的方法是最简单的方法,尽管它们确实解释了我提到的方法(使用制表符分隔的文件)。

编辑:为了完整起见,这是我原来的答案。请参阅上面的链接以获取更多详细信息和可能的更好解决方案。

这不是您问题的答案,而是改变您方法的建议(如果可以的话)。通过 COM 调用添加数据时,Excel 往往非常慢,我假设 OleDB 在内部使用 COM。根据我的经验,将数据输出到 Excel 的最快(同时也是最不痛苦的方法)是生成一个包含所有数据的制表符分隔的文本文件,然后将该文件导入到 Excel 中并使用 COM 互操作在工作表上执行任何格式设置。当我以这种方式生成 Excel 报告时,大多数报告的生成速度几乎比使用 Excel COM 对象模型快 100 倍。 (我不知道这对于 OleDB 调用是否相同,因为我从未在 Excel 中使用过 OleDB,但我愿意打赌 OleDB 适配器在内部使用 COM。)

这也可以解决您的嵌入空间问题,因为制表符将是列分隔符。

在您的特定情况下,我会将文本文件导入 Excel 到新工作表中,然后将其复制并粘贴到 IRS 工作表中的正确位置。完成后,可以删除临时表。

关于c# - 使用 OleDb 写入 Excel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12807362/

相关文章:

c# - 并发修改 double[][] 元素而不加锁

.net - ado net - 导入 Excel 数据 - 丢失数据

c# - ClosedXML - 创建多个数据透视表

asp.net - 将数据从 GridView 导出到 Excelsheet 时如何删除 Excel 工作表中的分页文本?

javascript - Excel 导出为 html 无法在 Excel 2016 中显示边框

c# - 我可以利用任何类型的 API/RSS 提要来查找 CefSharp 更新,尤其是安全更新吗?

c# - 是否可以复制具有相似字段的类型实例?

c# - 在数学方面,F# 真的比 C# 好吗?

ms-access - 有没有办法在 Azure 网站上使用 MS Access DB(MDB 文件)?

c# - 执行多个查询