【问题标题】:Fast way of going from Excel to a DataSet or DataGridView从 Excel 到 DataSet 或 DataGridView 的快速方法
【发布时间】:2011-03-22 06:19:35
【问题描述】:

我从 Excel 工作表中获取数据,最终目标是在 DataGridView 中显示。

目前我只是检查 Excel 数据的 UsedRange 并将其插入 datagridview。这工作正常,但当有 100 多行数据时可能会陷入困境。

我也玩过从 excel 进入数据集(使用相同的浪费方法),并且正如预期的那样,加载数据需要大约相同的时间。

我想知道是否有人有任何更好的方法的信息?也许使用 Excel 文件中的 XML?

编辑:

一些附加信息:

这是一个 WinForms 应用程序,用户将在运行时挑选和加载 excel 文件。

编辑

一些附加信息的返回:

Excel 文件位于用户的电脑上。一般的假设是他们每次使用应用程序时都会加载不同的文件。 [不确定这是否有帮助,但可能很高兴知道:)]

【问题讨论】:

    标签: .net vb.net winforms excel dataset


    【解决方案1】:

    我最近遇到了同样的问题...我无法真正找到一个开箱即用的解决方案来为我解决这个问题,所以我最终手动编写了一些代码。

    我的代码库中实际上有两种不同的解决方案:一种使用 OLEDB,另一种使用 Excel Interop。根据您的问题,我猜您一直在尝试使用互操作解决方案,而且速度太慢。如果您只想直接从 Excel 中读取表格,其中每个工作表有一个表格,那么 OLEDB 解决方案可能更清洁、更快。但是,如果您需要写入 Excel 文件,您可能会发现 OLEDB 太有限了。这是我在一个项目中的经验。

    无论如何,我将发布一些我的 OLEDB 解决方案中的点点滴滴,希望能帮助您入门:

        public void FillDataTables(DataSet dataSet)
        {
            var worksheetNames = GetWorksheetNames();
            foreach (DataTable table in dataSet.Tables)
            {
                if (!worksheetNames.Contains(table.TableName + "$")) continue;
                FillDataTable(table);
            }
        }
    
        public void FillDataTable(DataTable table)
        {
            using (var connection = ConnectionProvider.GetNew())
            {
                var adapter = GetNewDataAdapter(table, connection);
                adapter.Fill(table);
            }
        }
    
        private IEnumerable<string> GetWorksheetNames()
        {
            return GetSchemaTable()
                .AsEnumerable()
                .Select(dr => dr.Field<string>("TABLE_NAME"));
        }
    
        public DataTable GetSchemaTable()
        {
            using (var connection = (OleDbConnection)ConnectionProvider.GetNew())
            {
                connection.Open();
                return connection.GetSchema("Tables");
            }
        }
    

    这是ExcelConnectionProvider的代码:

    public class ExcelConnectionProvider : IConnectionProvider
    {
        private readonly string _connectionString;
        private readonly string _workbookPath;
    
        public string ConnectionString
        {
            get { return _connectionString; }
        }
    
        public string WorkbookPath
        {
            get { return _workbookPath; }
        }
    
        public ExcelConnectionProvider(string workbookPath)
        {
            _workbookPath = workbookPath;
            _connectionString = GetConnectionString();
        }
    
        private string GetConnectionString()
        {
            var builder = new OleDbConnectionStringBuilder { Provider = "Microsoft.ACE.OLEDB.12.0", DataSource = _workbookPath };
            builder.Add("Extended Properties", "Excel 12.0 Xml;HDR=Yes");
            return builder.ConnectionString;
        }
    
        public DbConnection GetNew()
        {
            return new OleDbConnection(_connectionString);
        }
    }
    

    如果您在此编译过程中遇到任何问题,请尝试在您的项目中包含“System.Data.DataSetExtensions”程序集。

    编辑: 不需要: IConnectionProvider - 这是我添加到库中的接口,因为除了 Excel 之外我还有其他连接提供程序。

    【讨论】:

    • 关于您的代码的两个问题:1) IConnectionProvider 的命名空间是什么?我找不到它。 2)由于您的成员变量是私有只读的,您如何设置它们的值?
    • 没关系,我想通了(Doh!时刻)。我打算做一些测试,但现在这似乎工作得很好。
    • 这个效果比预期的要好。将 500 多行数据的加载时间缩短一分钟。非常感谢。
    【解决方案2】:

    是这些办公室打开XML文档吗?如果是,您可以使用 System.IO.Packaging 命名空间或 Open XML SDK 2.0 来浏览数据。这应该很快,因为它只处理 XML 文件。当然,如果它们不是 OOXML,那么这真的没有用,我很抱歉。

    【讨论】:

    • 你竟敢给我虚假的希望!!大声笑只是玩。我可能会将其视为一种选择,但我的直觉说它也行不通。当前规范要求支持 Excel 文件,我无法知道或强制使用文件的版本(它们来自外部来源 - 即:客户端)。
    【解决方案3】:

    如果您可以选择,我会先将 excel 数据导出到数据库或 xml 文件中(仅一次,而不是每次应用程序运行时)。除非您的用户定期更新此 Excel 文件,并且希望立即在您的应用中看到结果。

    以下是使用 Excel 作为数据源的方法(您可能已经拥有它,但值得验证,因为现在只是性能问题):http://support.microsoft.com/default.aspx?scid=kb;en-us;311731

    但是是的——在你的应用程序获取它之前将其转换为 sql-server 表或 xml 文件,我想你会更快乐。

    【讨论】:

    猜你喜欢
    • 2015-02-16
    • 2019-12-25
    • 2012-07-29
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多