عنوان:

‫خواندن سریع اطلاعات فایل اکسل و ذخیره در بانک SQL


نویسنده: مجتبی فخاری
تاریخ: ۱۳۹۲/۱۱/۱۷ ۱۸:۳۵
آدرس: www.dntips.ir
یکی از زمانبرترین عملیاتها در نرم افزار‌های اتوماسیون، خواندن اطلاعات از فایل‌های اکسل با حجم بالا است. در صورتی که این کار را می‌توان با استفاده از کلاس SqlBulkCopy  به سرعت انجام داد. در ادامه نحوه استفاده از این کلاس، همراه نمونه کدها آورده شده است.
توضیحات به صورت Comment است.
            try
            {
//انتخاب فایل اکسل
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Title = "انتخاب فایل اکسل حاوی اطلاعات";
                ofd.Filter = "فایل اکسل 2003 (*.xls)|*.xls|فایل اکسل 2007 به بعد(*.xlsx)|*.xlsx";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    string excelConnectionString = "";
                    string SourceFilePath = ofd.FileName;
//ایجاد کانکشن استرینگ برا خواندن کل اطلاعات از فایل اکسل و ریختن آنها در یک دیتاتیبل به نام dt
                    if (System.IO.Path.GetExtension(ofd.FileName) == ".xlsx")
//تشخیص نوع فایل اکسل برای ایجاد کانکشن استرینگ برای نسخه‌های مختلف اکسل
                        excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + SourceFilePath + ";Extended Properties=Excel 12.0";
                    else if (System.IO.Path.GetExtension(ofd.FileName) == ".xls")
                        excelConnectionString = "Provider=Microsoft.Jet.Oledb.4.0;Data Source=" + SourceFilePath + ";Extended Properties=Excel 8.0";

                    DataTable dt = new DataTable("tblinfos");


                    using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(excelConnectionString))
                    {
                       
                        connection.Open();

                        System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM [List$]", connection);//List نام شیت در فایل اکسل است

                        da.Fill(dt);
                        connection.Close();

                    }

                    using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(excelConnectionString))
                    {
                        this.Cursor = Cursors.WaitCursor;

                        connection.Open();
//ایجاد ارتباط با بانک اس کیو ال
                        string sqlConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\BankDPR.mdf;Max Pool Size=6000; Connection Timeout=50;Integrated Security=True;User Instance=True";
                        

                        Dataaccess db = new Dataaccess();
                        DataTable dtr = db.select("Select Top(1) * From tblinfos");//بدست آورن نام ستون‌های جدول مورد نظر برای تطبیق با ستونهای فایل اکسل
                        //*******************   Fast Copy
                        using (System.Data.SqlClient.SqlBulkCopy bulkCopy = new System.Data.SqlClient.SqlBulkCopy(sqlConnectionString, System.Data.SqlClient.SqlBulkCopyOptions.KeepIdentity))//تعریف یک شی از کلاس SqlBulkCopy 
                        {
                            for (int i = 1; i < dtr.Columns.Count; i++)
                            {
                                bulkCopy.ColumnMappings.Add(dt.Columns[i - 1].Caption, dtr.Columns[i].Caption);//با استفاده از خاصیت ColumnMappings نام ستونهای فایل اکسل با نام ستونهای جدول مورد نظر بانک sql تطبیق داده می‌شود
                            }

                            bulkCopy.DestinationTableName = "tblinfos";//مشخص نمودن نام جدول که قرار است اطلاعات درون ان کپی گردد
                            bulkCopy.WriteToServer(dt);//انجام عملیات کپی اطلاعات از دیتاتیبل با نام dt به بانک

                        }

                        this.Cursor = Cursors.Arrow;
                        MessageBox.Show("اطلاعات از فایل شما خوانده شد");

                    }
                }
            }
            catch (Exception ex)
            {
                this.Cursor = Cursors.Arrow;

                MessageBox.Show(ex.Message, "error");
            }

نظرات

  • محسن خان در ۱۳۹۲/۱۱/۱۷ ۲۱:۲۲
    احتمالا این قطعه کد مستقیما از داخل سورس یکی از پروژه‌های شما بیرون آمده (مثال نیست؛ واقعی هست). می‌شد کمی اون رو refactor کرد مثلا یک متد از داخلش بیرون آورد که این متد داخلش مسیج باکس نباشه یا باز کردن یک صفحه دیالوگ و تغییر کرسر. try و catch هم نداشته باشه چون باید در یک سطح بالاتر catch بشه مشکلاتش. اون selectها مثلا می‌شدند چند پارامتر، برای اینکه این کد قابلیت استفاده مجدد بهتری پیدا کنه. یا مثلا اون sqlConnectionString از داخل کدها بیرون می‌اومد و می‌شد یک پارامتر جدید. نمایش کرسر هم داخل این متد قرار نمی‌گرفت. نام جدول نهایی هم مثلا یک پارامتر دیگر می‌شد برای سهولت استفاده مجدد و همچنین تست بهتر یک قطعه کوچک از کار. خود متد اصلی هم می‌شد دو متد کوچک‌تر؛ یکی کار load رو انجام می‌داد و دیگری کار insert سریع.
    • مهمان در ۱۳۹۲/۱۱/۱۹ ۱۳:۳۸
      من هم با دوستمون محسن خان موافقم. اتفاق‌ها زیادی در مورد این کد باید بیافته تا به یک کد خوب تبدیل بشه. شما کاملا به صورت Smart UI  کد زدید. امیدوارم وقت بزارید و این کد رو بهینه کنید. توی همین سایت مثال‌های خوبی واسه‌ی یادگیری هست..
    • مهمان در ۱۳۹۲/۱۱/۲۰ ۱۱:۳۶
      بله این کد رو من دقیقا از یکی از برنامه هام آوردم  و مال چندین سال پیشه.
      اما خوبیش اینه که بدون خطا جواب میده و فقط کافیه اسم جداول رو عوض کنید.
  • مهمان در ۱۳۹۲/۱۲/۱۲ ۱۰:۲۹
    با سلام و تشکر. این برنامه پیغام میدهد List وجود ندارد.
     SELECT * FROM [List$]
    لطفا راهنمایی بفرمایید من چطور میتوانم نام شیت‌ها را بدست بیاورم؟
    • وحید نصیری در ۱۳۹۲/۱۲/۱۲ ۱۰:۴۷
      در کد فوق اکثر قسمت‌ها بر اساس یک سری پیش فرض مشخص تهیه شده‌اند و آن‌ها را تبدیل به پارامتر متغیر نکرده‌اند. نام شیت، همان نام برگه جاری است:

  • مهمان در ۱۳۹۳/۰۴/۱۱ ۲۳:۴۰
    سلام. من از این روش برای خواندن فایل موجود در آدرس http://www.site.com/market/export.aspx?type=dtod&date=20120405  استفاده کردم، ولی متاسفانه فیلد‌های عددی را NULL مقدار میگیرد. مشکل از چیست و چه جوری برطرف میشود؟
    • وحید نصیری در ۱۳۹۳/۰۴/۱۲ ۰:۲۴
      این فایل استاندارد اکسل نیست. خروجی آن را با نوت پد باز کنید؛ یک فایل HTML معمولی است.
      • مهمان در ۱۳۹۳/۰۴/۱۲ ۳:۳۰
        الان من نیاز شدید دارم این فایل رو تبدیل به SQL کنم، و چون هر روز این فایل تغییر میکنه نمیتونم توی فایل تغییری بدم، چه راه حلی هست برای این کار؟
        • وحید نصیری در ۱۳۹۳/۰۴/۱۲ ۹:۱۹
          فایل‌های HTML را با استفاده از کتابخانه‌ی HTML Agility Pack پردازش می‌کنند.