خواندن اطلاعات از فایل اکسل با استفاده از LinqToExcel
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: دو دقیقه

در این مقاله مروری سریع و کاربردی خواهیم داشت بر توانایی‌های مقدماتی LinqToExcel
در ابتدا می‌بایست LinqToExcel را از طریق NuGet به پروژه افزود.
PM> Install-Package LinqToExcel
و یا از طریق solution Explorer گزینه Manage NuGet Packages 

اکنون فایل اکسل ذیل را در نظر بگیرید.

روش خواندن اطلاعات از فایل اکسل فوق تحت فرامین Linq و با مشخص کردن نام sheet مورد نظر  توسط شئ ExcelQueryFactory  بصورت زیر است.

 string pathToExcelFile = @"C:\Users\MASOUD\Desktop\ExcelFile.xlsx";
var excel = new ExcelQueryFactory(pathToExcelFile);
            string sheetName = "Sheet1";
            var persons = from a in excel.Worksheet(sheetName) select a;
            foreach (var a in persons)
            {
                MessageBox.Show(a["Name"]+" "+a["Family"]);
            }


در صورتیکه بخواهیم انتقال اطلاعات فایل اکسل به جداول بانک اطلاعاتی مانند Sql Server بطور مثال با روش EF Entity Framework را انجام دهیم کلاس زیر با نام person را فرض نمایید.

 public class Person
        {
            public string Name { get; set; }
            public string Family { get; set; }
        }
باید بدانید که بصورت پیشفرض سطر اول از فایل اکسل به عنوان نام ستون انتخاب می‌شود و می‌بایست جهت نگاشت با نام property‌های کلاس ما دقیقاً همنام باشد.

 string pathToExcelFile = @"C:\Users\MASOUD\Desktop\ExcelFile.xlsx";
            var excel = new ExcelQueryFactory(pathToExcelFile);
            string sheetName = "Sheet1";
            var persons = from a in excel.Worksheet<Person>(sheetName) select a;
            foreach (var a in persons)
            {
                MessageBox.Show(a.Name+" "+a.Family);
            }
  اگر فایل اکسل ما ستون‌های بیشتری داشته باشد تنها ستونهای همنام با propertyهای کلاس ما به کلاس نگاشت پیدا می‌کند و سایر ستونها نادیده گرفته می‌شود.
در صورتیکه نام ستونهای فایل اکسل(سطر اول) با نام property‌های کلاس یکسان نباشد جهت نگاشت آنها در کلاس می‌توان از متد AddMapping استفاده نمود.
 

 string pathToExcelFile = @"C:\Users\MASOUD\Desktop\ExcelFile.xlsx";
            var excel = new ExcelQueryFactory(pathToExcelFile);
            string sheetName = "Sheet1";
            excel.AddMapping("Name","نام");
            excel.AddMapping("Family", "نام خانوادگی");
            var persons = from a in excel.Worksheet<Person>(sheetName) select a;
            foreach (var a in persons)
            {
                MessageBox.Show(a.Name+" "+a.Family);
            }

در کدهای بالا در صورتی که sheetName قید نشود بصورت پیشفرض Sheet1 از فایل اکسل  انتخاب می‌شود.

var persons = from a in excel.Worksheet<Person>() select a;
همچنین می‌توان از اندیس جهت مشخص نمودن Sheet مورد نظر استفاده نمود که اندیس‌ها از صفر شروع می‌شوند.

var persons = from a in excel.Worksheet<Person>(0) select a;
توسط متد GetWorksheetNames می توان نام sheet‌ها را بدست آورد.

public IEnumerable<string> getWorkSheets()
{
string pathToExcelFile = @"C:\Users\MASOUD\Desktop\ExcelFile.xlsx";
    
    var excel = new ExcelQueryFactory(pathToExcelFile);

    return excel.GetWorksheetNames();
}
و توسط متد GetColumnNames   می توان نام ستونها را بدست آورد.  

var SheetColumnNames = excel.GetColumnNames(sheetName);
همانطور که می‌بینید با روش توضیح داده شده در این مقاله به راحتی از فرامین Linq مانند where می‌توان در انتخاب اطلاعات از فایل اکسل استفاده نمود و سپس نتیجه را به جداول مورد نظر انتقال داد.
  • #
    ‫۱۰ سال و ۱۱ ماه قبل، سه‌شنبه ۷ آبان ۱۳۹۲، ساعت ۰۲:۱۲
    با تشکر از شما. این کتابخانه LinqToExcel کار کیست؟ سایت اصلی آن کجاست؟ مجوز استفاده از آن به چه صورتی است؟
    • #
      ‫۱۰ سال و ۱۱ ماه قبل، سه‌شنبه ۷ آبان ۱۳۹۲، ساعت ۰۳:۱۹
      یک ویدیوی آموزشی کوتاه جالب با توضیحات راجع به این کتابخانه اینجا  وجود داره که پیشنهاد میکنم ببینید. فقط من بدون فیلترشکن نتونستم صفحه اش و باز کنم.
  • #
    ‫۱۰ سال و ۱۱ ماه قبل، سه‌شنبه ۷ آبان ۱۳۹۲، ساعت ۱۳:۴۹
    سلام
    اگر نام ستون‌ها رو نداشته باشیم و فقط بخواهیم اطلاعات داخل شیت رو بدست بیاریم چیکار باید کرد در ضمن آیا باز نیازی به اسمبلی Microsoft.Office.Interop.Excel هست یا نه ؟
    • #
      ‫۱۰ سال و ۱۱ ماه قبل، چهارشنبه ۸ آبان ۱۳۹۲، ساعت ۰۲:۰۹
      با استفاده از متد WorksheetNoHeader و با وارد کردن شماره اندیس می‌توانید به اطلاعات سلولها دست پیدا کنید. در مثال زیر تمام سطرهایی که ستون دوم آنها شهر مشهد است انتخاب می‌شوند و سپس سلولهای آن سطرها نمایش داده می‌شوند.  
               var excel = new ExcelQueryFactory(pathToExcelFile);
                  string sheetName = "Sheet1";
                  var persons = from a in excel.WorksheetNoHeader(sheetName)
                                where a[1] == "Mashhad" //مقدار در ستون دوم 
                                select a;
                  foreach (var a in persons)
                    {
                        for(int i=0;i<a.Count;i++)
                              MessageBox.Show(a[i]); 
                    }
      به اسمبلی Microsoft.Office.Interop.Excel نیازی نیست و
      LinqToExcel.dll  و  Remotion.Data.Linq.dll مورد نیاز است. 
       
  • #
    ‫۱۰ سال و ۱۱ ماه قبل، چهارشنبه ۸ آبان ۱۳۹۲، ساعت ۱۲:۱۹
    سلام من این خطا رو میگیرم
    The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
    • #
      ‫۱۰ سال و ۱۱ ماه قبل، چهارشنبه ۸ آبان ۱۳۹۲، ساعت ۱۴:۱۶
      مطابق توضیحات آن، نیاز به AccessDatabaseEngine نیز دارد (Microsoft.ACE.OLEDB.12.0 مربوط به اکسس 2010 است). احتمالا برای سازگاری با نگارش‌های قدیمی اکسل که با فرمت OpenXML نیستند از این نوع رشته اتصالی مخصوص اکسس 2010 در پشت صحنه استفاده کرده:
      Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=path to xls/xlsx/xlsm/xlsb file
  • #
    ‫۱۰ سال و ۱۰ ماه قبل، دوشنبه ۱۱ آذر ۱۳۹۲، ساعت ۱۴:۱۴
    بادرود
    ممنون از اطلاعات مفید شما .
    من در یک پروژه تحت وب از طریق فایل اکسل اطلاعات را از کاربر دریافت می‌کنم و نیاز دارم این اطلاعات را در داخل دیتابیس ذخیره کنم از آنجا که تعداد رکورد‌های فایل اکسل نامشخص است به چه صورت باید این کد را بنویسم
    ممنون
  • #
    ‫۸ سال و ۹ ماه قبل، شنبه ۲۸ آذر ۱۳۹۴، ساعت ۰۶:۰۴
    من از روش Oledb برای اتصال استفاده کردم و بعد از اون از یک کامپوننت و بعد از اونم از این روش و حتی از طریق خود sql server هم همین کار رو انجام دادم و فایلی که من تست می‌کنم یک میلیون سطر اطلاعات دارد در صورتی که در همه روش‌های بالا نهایتا 65535 سطر خوانده میشه، در مورد باقی اطلاعات چکاری میشه انجام داد؟
    • #
      ‫۸ سال و ۹ ماه قبل، شنبه ۲۸ آذر ۱۳۹۴، ساعت ۱۴:۰۳
      - محدودیت 65535 سطر در هر worksheet، تا اکسل 2003 وجود داشت. از 2007 به بعد این محدودیت 1,048,576 سطر است.
      - پروژه‌ی « ExcelDataReader » را هم بررسی کنید. برای حالت‌های تعداد سطر بالا، متد AsDataSet آن‌را باید با حالت IDataReader یا IExcelReaderDataReader جایگزین کنید تا با مشکل کمبود حافظه مواجه نشوید؛ مانند آزمون DataReader_NextResult_Test آن.
  • #
    ‫۸ سال و ۱ ماه قبل، یکشنبه ۱۷ مرداد ۱۳۹۵، ساعت ۱۸:۱۸
    همه چیز رو مطابق مستندات انجام دادم ولی خطای زیر رخ میده
    Additional information: Could not load file or assembly 'log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a' or one of its dependencies. The located assembly's manifest definition does not  
  • #
    ‫۷ سال و ۴ ماه قبل، دوشنبه ۱ خرداد ۱۳۹۶، ساعت ۰۲:۴۲
    با عرض سلام و وقت بخیر 
    بنده دارم با فایلی کار می‌کنم که شبیه فیش حقوقی هست که یه سری title هایی داره و هر title ایی تو فایل یه سری زیر مجموعه داره . عکس ضمیمه شده . لطفا راهنمایی بفرمایید که برای این مورد باید چی کار کنیم که اطلاعات به درستی تو دیتابیس ذخیره بشه ؟ 
    سوال دوم هم در رابطه با نرمال سازی یه فایل اکسل هست . مثلا وقتی یه فایلی رو داریم از کاربر میگیریم ممکنه که اطلاعات از وسط صفحه شروع شده باشه یا این که یه سری متن‌های اضافی در اون فایل باشه . برای این مورد چه طور میشه اون فایل اکسل رو استاندارد کرد .
    با تشکر از شما

    • #
      ‫۷ سال و ۴ ماه قبل، دوشنبه ۱ خرداد ۱۳۹۶، ساعت ۰۴:۵۱
      برای دیباگ فایل‌های اکسل از کتابخانه‌ی EPPlus هم می‌توانید استفاده کنید:
      using System;
      using System.IO;
      using OfficeOpenXml;
      
      namespace ExcelDataReader
      {
          class Program
          {
              /// <summary>
              /// PM> Install-Package EPPlus
              /// </summary>
              static void Main(string[] args)
              {
                  var filePath = "sample.xlsx";
                  var fileInfo = new FileInfo(filePath);
                  if (!fileInfo.Exists)
                  {
                      throw new FileNotFoundException($"{filePath} file not found.");
                  }
      
                  var worksheetName = "Sheet1";
                  using (var package = new ExcelPackage(fileInfo))
                  {
                      var worksheet = package.Workbook.Worksheets[worksheetName];
                      var startCell = worksheet.Dimension.Start;
                      var endCell = worksheet.Dimension.End;
      
                      for (var row = startCell.Row; row < endCell.Row + 1; row++)
                      {
                          for (var col = startCell.Column; col <= endCell.Column; col++)
                          {
                              var header = worksheet.Cells[1, col].Value ?? worksheet.Cells[2, col].Value;
                              var name = header?.ToString();
                              var value = worksheet.Cells[row, col].Value;
                              //var intValue = Convert.ChangeType(value, typeof(int)) as int?;
                              Console.WriteLine($" row[{row}]:col[{col}] -> {name} : {value}");
                          }
                          Console.WriteLine();
                      }
                  }
              }
          }
      }
      سطر به سطر و ستون به ستون آن‌را به صورت key/value خوانده و نمایش می‌دهد.
      این key/valueها هم از نوع object هستند. بنابراین تبدیل آن‌ها و یا اعتبارسنجی مقادیر آن‌ها را به سادگی می‌توانید انجام دهید:
      var intValue = Convert.ChangeType(value, typeof(int)) as int?;