c# - 将excel中的数据导入到多个表中

标签 c# sql excel import

我正在构建一个离线 C# 应用程序,它将从电子表格中导入数据并将它们存储在我创建的 SQL 数据库中(在项目中)。通过一些研究,我已经能够使用一些可以将静态表导入到与工作表中的列布局完全相同的数据库中的代码

我想做的是根据名称将特定列转到正确的表中。这样我就可以正确设计数据库,而不仅仅是一个巨大的表来存储所有内容。

下面是我用来将一些静态字段导入到一个表中的代码,我希望能够将导入的数据分成多个。

执行此操作的最佳方法是什么?

public partial class Form1 : Form
    {
        string strConnection = ConfigurationManager.ConnectionStrings
        ["Test3.Properties.Settings.Test3ConnectionString"].ConnectionString;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {


            //Create connection string to Excel work book
            string excelConnectionString =
            @"Provider=Microsoft.Jet.OLEDB.4.0;
            Data Source=C:\Test.xls;
            Extended Properties=""Excel 8.0;HDR=YES;""";

            //Create Connection to Excel work book
            OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);

            //Create OleDbCommand to fetch data from Excel
            OleDbCommand cmd = new OleDbCommand
            ("Select [Failure_ID], [Failure_Name], [Failure_Date], [File_Name], [Report_Name], [Report_Description], [Error] from [Failures$]", excelConnection);

            excelConnection.Open();
            OleDbDataReader dReader;
            dReader = cmd.ExecuteReader();

            SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection);
            sqlBulk.DestinationTableName = "Failures";
            sqlBulk.WriteToServer(dReader);

        }

最佳答案

您可以尝试 ETL(提取-转换-加载)架构:

提取:一个类将打开文件并获取您知道如何使用的 block 中的所有数据(通常您从文件中取出一行并将其数据解析为包含保存相关数据的字段的 POCO 对象),并将它们放入其他工作进程可以从中获取的队列中。在这种情况下,也许您要做的第一件事是让 Excel 打开该文件并将其重新保存为 CSV,这样您就可以在您的流程中将其作为基本文本重新打开并有效地将其切碎。您还可以读取列名并构建“映射字典”;此列被命名为那个,所以它转到数据对象的这个属性。这个过程应该尽可能快地发生,它失败的唯一原因是行的格式与你在给定文件结构时要查找的内容不匹配。

转换:一旦文件的内容被提取到一个基本行的实例中,执行任何验证、计算或其他必要的业务规则,将文件中的一行转换为一组符合您的域模型的域对象。这个过程可以像您需要的那样复杂,但它应该尽可能简单明了,同时遵守您的要求中给出的所有业务规则。

加载:现在您在自己的域对象中有了一个对象图,您可以使用您调用的相同持久性框架来处理以任何其他方式创建的域对象。这可能是基本的 ADO、NHibernate 或 MSEF 之类的 ORM,或者对象知道如何持久化自身的 Active Record 模式。它不是批量加载,但它使您不必实现完全不同的持久性模型,只是为了将基于文件的数据导入数据库。

ETL 工作流可以帮助您将重复性任务分成简单的工作单元,然后您可以从中识别出花费大量时间的任务并考虑并行流程。

或者,在调用批量插入例程来处理数据之前,您可以通过检测要使用的列并将它们排列成与批量输入规范匹配的格式来获取文件并修改其格式。这个文件处理器例程可以做任何你想做的事情,包括将数据分成几个文件。但是,这是一次处理整个文件的大型进程,优化或并行处理的机会有限。但是,如果您的加载机制很慢,或者您有大量易于消化的数据,它最终可能比设计良好的 ETL 更快。

在任何情况下,我都会尽快摆脱 Office 格式,转而使用纯文本(或 XML)格式,而且我绝对会避免在服务器上安装 Office。如果有任何方法可以要求文件在加载之前采用一些易于解析的格式,如 CSV,那就更好了。在服务器上安装 Office 通常是一件非常糟糕的事情,服务器应用程序中的 OLE 操作也好不了多少。该应用程序将非常脆弱,Office 想要告诉您的任何信息都会导致该应用程序挂起,直到您登录到服务器并清除对话框。

关于c# - 将excel中的数据导入到多个表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3664067/

相关文章:

MySQL,SQL如何获取所有行?

SQL Service Broker 示例不工作

excel - 在一台计算机上打开工作簿错误代码 32809,但在另一台计算机上打不开

sql - 将日期格式化为单词

excel - 选择列最后一个单元格上方的单元格

excel - 如何使用 Excel VBA 在多行单元格中的每行最后一个斜杠之后获取单词?

c# - 具有相同返回类型和名称的 MessageBodyMembers 导致异常 - 元素已导出

c# - 如何在不将页面加载到浏览器的情况下刷新页面?

c# - 将静态值分配给另一个类的类

C# - 如何从带有进度条的表单中取消后台工作?