将 DataTable/DataSet 写入 Excel 工作簿

Writing DataTable/DataSet to Excel Workbook

我正在遍历数据库并按月查询,然后将此数据插入到 DataTable 中,用于用户指定年份的每个月。我想将此 DataTable 插入到 Excel 工作簿的新 sheet 中。因此,在我的单个 Excel 工作簿中,我最终得到 12 sheet。

所以我有几个问题由此而来。

Would it be better to have a DataSet containing my 12 DataTables (one for each month)? And then is there a quick and easy way of creating an Excel spreadsheet from my DataSet and being that there are 12 DataTables in that set it would create a separate sheet for each DataTable?

然后另一个问题是

Is it more simple or easier to just create 12 different DataTables and create a workbook and a separate sheet for each DataTable in the workbook and fill that sheet from the DataTable one by one?

您可以将所有数据放入一个数据表中,查询不同的月份,然后遍历数据行,创建 sheet 并插入数据。下面的示例使用放置在 DataTable 中的模拟数据来执行此操作。有两个 sql 语句,一个用于创建 sheet,一个用于插入数据。完成后,对于此示例,将有三个月的 sheet,而不是 12,除非每个月至少有一个记录或更多。如果您必须返回并插入更多行,那么将需要额外的逻辑,这不是要求的,但我们需要首先查看 sheet 是否存在,这可以通过简单地尝试创建现有的 sheet 会抛出异常。我让这个例子非常简单。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo1_CS
{
    public class MonthDemo
    {
        /// <summary>
        /// Let's look at this as data coming back from a database table
        /// </summary>
        /// <returns></returns>
        public DataTable Table()
        {
            DataTable dt = new DataTable();

            dt.Columns.Add(new DataColumn()
            {
                ColumnName = "ID",
                DataType = typeof(int),
                AutoIncrement = true
            });
            dt.Columns.Add(new DataColumn()
            {
                ColumnName = "Month",
                DataType = typeof(string)
            });
            dt.Columns.Add(new DataColumn()
            {
                ColumnName = "Name",
                DataType = typeof(string)
            });

            dt.Rows.Add(new object[] { null, "January", "Karen Payne" });
            dt.Rows.Add(new object[] { null, "January", "Bill Smith" });
            dt.Rows.Add(new object[] { null, "March", "George Jones" });
            dt.Rows.Add(new object[] { null, "April", "Frank White" });

            return dt;

        }
        /// <summary>
        /// Get a list of distinct month names
        /// </summary>
        /// <returns></returns>
        public List<string> MonthNames()
        {
            return Table()
                .AsEnumerable()
                .Select(row => row.Field<string>("Month"))
                .Distinct()
                .ToList();
        }
        public void Work()
        {
            // SQL responsible for creating sheets
            string createCommandText =
                        @"
                            CREATE TABLE {0}
                            (
                                ID INT,
                                Name CHAR(255)
                            )";

            // SQL responsible for inserting rows of data
            string insertCommandText = @"
                        INSERT INTO {0}
                        (
                            ID,
                            Name
                        )
                        VALUES
                        (
                            @ID,
                            @Name
                        )
                    ";

            // assumes this file exists
            string FileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DemoMonths.xlsx");

            List<DataRow> result;

            using (OleDbConnection cn = new OleDbConnection { ConnectionString = "TODO"})
            {
                using (OleDbCommand cmd = new OleDbCommand { Connection = cn })
                {
                    cmd.Parameters.Add(new OleDbParameter() { ParameterName = "@ID", DbType = DbType.Int32 });
                    cmd.Parameters.Add(new OleDbParameter() { ParameterName = "@MonthName", DbType = DbType.String });
                    cmd.Parameters.Add(new OleDbParameter() { ParameterName = "@Name", DbType = DbType.String });

                    // assume the file will open else use a try-catch
                    cn.Open();

                    // Iterate months, get rows and insert rows into proper sheet
                    foreach (string monthName in MonthNames())
                    {
                        result = Table().AsEnumerable().Where(row => row.Field<string>("Month") == monthName).ToList();
                        if (result.Count > 0)
                        {
                            foreach (DataRow row in result)
                            {
                                // assumes sheet does not exists, create it
                                cmd.CommandText = string.Format(createCommandText, monthName);

                                try
                                {
                                    // test if create sheet worked
                                    if (cmd.ExecuteNonQuery() == 1)
                                    {

                                        // load values into command object parameters
                                        cmd.CommandText = string.Format(insertCommandText, monthName);
                                        cmd.Parameters["@ID"].Value = row.Field<int>("ID");
                                        cmd.Parameters["@Name"].Value = row.Field<string>("Name");

                                        // insert row data
                                        cmd.ExecuteNonQuery();
                                    }
                                }
                                catch (Exception ex)
                                {
                                    // simply an example, best to say write to a log file
                                    Console.WriteLine("Failed to create or insert: {0}", ex.Message);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

This 正是我所需要的。