首页 > 解决方案 > 使用 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)";
        }

标签: c#oledbexport-to-excel

解决方案


数据适配器使用DataRow.RowState来确定要运行的查询。行需要处于已添加的行状态才能触发 InsertCommand 的使用。如果您以未标记为已添加的方式加载包含行的数据表(例如 ImportRow 或通过导致调用 AcceptChanges 的某种方式,例如您调用它,即使您这样做Rows.Add了,或者您使用带有 的数据适配器填充AcceptChangesDuringFill = true),没有插入运行


推荐阅读