Импорт данных из Excel в несколько таблиц - PullRequest
4 голосов
/ 08 сентября 2010

Я создаю автономное приложение 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);

        }

Ответы [ 4 ]

2 голосов
/ 08 сентября 2010

Вы можете попробовать архитектуру ETL (extract-transform-load):

Extract: один класс откроет файл и получит все данные в кусках, с которыми вы знаете, как работать (обычно вы берете одинстрока из файла и синтаксический анализ его данных в объект POCO, содержащий поля, которые содержат соответствующие данные), и помещают их в очередь, из которой могут работать другие рабочие процессы.В этом случае, возможно, первое, что вы сделаете, - это откроете файл в Excel и повторно сохраните его в формате CSV, чтобы вы могли снова открыть его как основной текст в вашем процессе и эффективно его нарезать.Вы также можете прочитать имена столбцов и создать «словарь сопоставления»;этот столбец называется так, поэтому он переходит к этому свойству объекта данных.Этот процесс должен происходить как можно быстрее, и единственная причина, по которой он должен потерпеть неудачу, состоит в том, что формат строки не соответствует тому, что вы ищете, учитывая структуру файла.

Преобразование: после извлечения содержимого файла в экземпляр базовой строки выполните любые проверки, вычисления или другие бизнес-правила, необходимые для превращения строки из файла в набор объектов домена, соответствующих вашемудоменная модель.Этот процесс может быть настолько сложным, насколько вам нужно, но, опять же, он должен быть настолько простым, насколько это возможно, при соблюдении всех бизнес-правил, указанных в ваших требованиях.

Загрузка: Теперь у вас естьГраф объектов в ваших собственных объектах домена, вы можете использовать ту же среду хранения, которую вы вызываете для обработки объектов домена, созданных любым другим способом.Это может быть базовый ADO, ORM, такой как NHibernate или MSEF, или шаблон Active Record, где объекты знают, как сохранить себя.Это не массовая загрузка, но избавляет вас от необходимости реализовывать совершенно другую модель персистентности только для того, чтобы загружать данные из файлов в БД.

Рабочий процесс ETL может помочь вам разделить повторяющиеся задачи на простые единицы работы,и оттуда вы можете определить задачи, которые занимают много времени, и рассмотреть параллельные процессы.

Кроме того, вы можете взять файл и поменять его формат, обнаружив столбцы, с которыми вы хотите работать, и расположив их в формате, который соответствует вашей спецификации массового ввода, прежде чем вызывать процедуру массовой вставки для обработки данных.Эта подпрограмма файлового процессора может делать все что угодно, включая разделение данных на несколько файлов.Однако это один большой процесс, который работает с целым файлом за раз и имеет ограниченные возможности для оптимизации или параллельной обработки.Однако, если ваш механизм загрузки медленный, или у вас есть МНОГО данных, которые легко переварить, это может закончиться быстрее, чем даже хорошо спроектированный ETL.

В любом случае, я бы получилкак можно скорее переместиться из формата Office в простой текстовый (или XML) формат, и я бы ОПРЕДЕЛЕННО избегал устанавливать Office на сервер.Если есть ЛЮБОЙ способ, которым вы можете потребовать, чтобы файлы были в каком-то легко разбираемом формате, таком как CSV, ДО того, как они будут загружены, тем лучше.В целом установка Office на сервере - это действительно плохо, и OLE-операции в серверном приложении не намного лучше.Приложение будет очень хрупким, и все, что скажет Office, заставит приложение зависать до тех пор, пока вы не войдете на сервер и не очистите диалоговое окно.

0 голосов
/ 09 сентября 2010

Если вы ищете ответ, связанный с большим количеством кода, вы можете использовать следующее, чтобы изменить свой код для работы со сложными именами столбцов / различными таблицами:

    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();

        DataTable dataTable = new DataTable();
        dataTable.Columns.Add("Id", typeof(System.Int32));
        dataTable.Columns.Add("Name", typeof(System.String));
        // TODO: Complete other table columns
        using(OleDbDataReader dReader = cmd.ExecuteReader())
        {
            DataRow dataRow = dataTable.NewRow();
            dataRow["Id"] = dReader.GetInt32(0);
            dataRow["Name"] = dReader.GetString(1);
            // TODO: Complete other table columns
            dataTable.Rows.Add(dataRow);
        }

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

Теперь вы можете контролировать имена столбцов и таблицы, в которые импортируются данные. SqlBulkCopy хорош для вставки больших объемов данных. Если у вас небольшое количество строк, вам лучше создать стандартный слой доступа к данным для вставки записей.

0 голосов
/ 08 сентября 2010

В зависимости от времени жизни программы, я бы порекомендовал один из двух вариантов.

  1. Если программа должна быть недолгой в использовании или, как правило, «выбрасывать» проект, я бы порекомендовал серию процедур, которые анализируют и вводят данные в другой набор таблиц, используя стандартный SQL с некоторой обработкой строк по мере необходимости.

  2. Если программа будет работать дольше и / или находить более широкое использование в повседневной жизни, я бы порекомендовал реализовать решение, аналогичное рекомендованному @KeithS. Благодаря набору четко определенных шагов для работы с данными достигается большая гибкость. В частности, .NET Entity Framework, вероятно, подойдет. В качестве бонуса, если вы еще не очень хорошо разбираетесь в этой области, вы можете многому научиться работать с данными между границами (xls -> sql -> и т. Д.) Во время вашего первого пребывания в ORM, например EF .

0 голосов
/ 08 сентября 2010

Если вас интересует только текст (не форматирование и т. Д.), В качестве альтернативы вы можете сохранить файл excel как файл CSV и вместо этого проанализировать файл CSV, это просто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...