21 Kasım 2017 Salı
Twitter

Excel'den veri okuma

Excel'i veritabanı olarak kullanmak mümkün.

Aramızda Excel'i kullanmayan yoktur.

Günlük işlerimizi bilgisayar başında yaparken illa ki ucundan kıyısından Excel'e bulaşmışsınızdır.

Excel'i, .NET projelerinde veritabanı olarak kullanabileceğinizi biliyor muydunuz?

Bunun için bize lazım olan ilk şey, güzel bir Connection String.

http://www.daltinkurt.com/Connection-Strings.aspx adresinden Connection String bilgilerine ulaşabilirsiniz.

Ben sitedeki bütün örnekleri ASP.NET üzerinden verdiğim için aşağıdaki örnekleri de aynı şekilde ASP.NET için vereceğim.

İsteyenler kendilerine uyarlayabilirler.

string dosya = "~/App_Data/Veriler.xlsx";
string connString = 
string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 12.0", Server.MapPath(dosya));

Bu stringi yazmaya çalışmayın. Direkt olarak kopyala-yapıştırı kullanın, zira aradaki bir tek boşluk / küçük-büyük harf bile önemli.

Dosyamız gördüğünüz üzere Excel 2007 / 2010 formatında. 2003 kullanan arkadaşlar (2012'deyiz ^_^) yukarıda verdiğim linke göz atmalıdırlar.

Sıra geldi Excel sayfamızı oluşturmaya. Hemen kafanıza göre bir dosya oluşturabilirsiniz.

  • Çalışma sayfamızın adı, tablomuzun adı (table),
  • En üst satırdaki başlıklar, sütunlarımız (Columns),
  • Gerisi de verilerin bulunduğu satırlarımız (Rows) oluyor.

SqlServer'a bağlanırken SqlConnection, SqlCommand, SqlDataAdapter, vd.,

MySql'e bağlanırken, MySqlConnection, MySqlCommand, MySqlDataAdapter, vd. nasıl kullanıyorsak,

Exel'e bağlanmak için de OleDbConnection, OleDbCommand, OleDbDataAdapter, vd. kullanıyoruz.

Örnek kodu inceleyiniz:

string dosya = "~/App_Data/Ogrenciler.xlsx";
string connString = string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 12.0;",
    Server.MapPath(dosya));

OleDbConnection conn = new OleDbConnection(connString);
conn.Open();
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [Sayfa1$]", conn);
OleDbDataAdapter da = new OleDbDataAdapter();
da.SelectCommand = cmd;
DataTable dt = new DataTable();
da.Fill(dt);

gv.DataSource = dt;
gv.DataBind();

Çıktı:

 

SqlServer'dan ve MySql'den tek farkı Connection Stringin ve sınıf isimlerinin değişmesi, gerisi gördüğünüz gibi aynı. :)

Şimdi gelelim detaylara:

1. Yukarıda da bahsettiğim gibi bu Excel 2007 / 2010 için geçerli. Eğer Excel 2003 (2012 yılında olduğumuzu tekrar hatırlatırım) kullanıyorsanız, connection stringi değiştirmeniz yeterli olacaktır.

2. Eğer çalıştırdığınız bilgisayarda, Office 2007 / 2010 yüklü ise kodun sorunsuz çalıştığını göreceksiniz. Ama ya Office kurulu olmayan bir bilgisayarda nasıl olacak?

Bu noktada söylemem gerekir ki; sitenizi host ettiğiniz serverda Office'in kurulu olmasını bekleyemezsiniz.

Bu durumda servera (nasıl yaparsınız bilmiyorum, ama hosting firması ile görüşmeniz gerekir) bir program kurmanız gerekiyor.

Microsoft Access Database Engine 2010 (Office 2010 için)

2007 Office System Driver: Data Connectivity Components (Office 2007 için)

3. Excel'den veriyi çekerken, DataAdapter'i kullanarak verileri DataTable'a aktardık, GridView'in DataSource'una bağladık.

Bu kodlar eskidi :)

Artık LINQ var.

Aşağıdaki kodu inceleyiniz:

var ogrenciler = from o in dt.AsEnumerable()
                 select new
                 {
                     SiraNo = o.Field<double>("Sıra No"),
                     Numara = o.Field<double>("Numara"),
                     AdSoyad = o.Field<string>("Adı Soyadı"),
                     Y1 = o.Field<double>("Y1"),
                     Y2 = o.Field<double>("Y2"),
                     S1 = o.Field<double>("S1"),
                     Ortalama = o.Field<double>("Ortalama")
                 };

//   Sınıf ortalaması
var ort = ogrenciler.Average(x => x.Ortalama);

// Y1'den en yüksek alan öğrenci
var ogr = (from o in ogrenciler
           where o.Y1 == ogrenciler.Max(x => x.Y1)
           select o).First();

//Y1-Y2 ortalaması en yüksek ilk 3 öğrenci:
var ogr2 = (from o in ogrenciler.AsEnumerable()
            let ortalama = (o.Y1 + o.Y2) / 2
            orderby ortalama descending
            select o).Take(3);

LINQ ifadelerini DataTable üzerinde kullanmak için DataTableIEnumerable interface'ini destekleyen bir tipe dönüştürdük, sonra da sorgularımızı rahatlıkla yazabildik.

BİLGİ: Bunun için de dt'nin sonuna .AsEnumerable() ekledik. dt den sonra . (nokta) ya basınca bu genişletme metodunu göremiyorsanız, Add Reference'tan .NET sekmesi altında System.Data.DataSetExtensions u bulup ekleyin.

İKAZ: Ben bir uygulamada, (Entity Framework ve LINQ kullandığım bir uygulamada) localhost'ta sorunsuz çalıştırırken, hosta attığımda bir hata mesajı aldım. Çözüm olarak da bu sefer ayrıca bir de System.Data.Entity de referans olarak ekledim, sorun çözüldü.

DİKKAT: Excel'den bilgileri okurken, sayıların double, metinlerin de string olarak geldiğine dikkat edin!

Örnek uygulama için buraya tıklayınız.

Herkese kolay gelsin.

Değerlendirme

Yazım dilinin sadeliği ve anlaşılabilirliği Puan: 5,00 (1 oy)
Yazıdaki kodların kalitesi Puan: 5,00 (1 oy)
İhtiyaca cevap verme Puan: 4,53 (2 oy)
Tavsiye edilebilirlik Puan: 4,70 (1 oy)
Genel değerlendirme Puan: 5,00 (1 oy)
Puanlamalar 5 üzerindendir.
  • Site Yorumlarý
  • Facebook Yorumlarý Facebook Yorumlarý
Yeni yorum yaz Toplam: 4, Onay bekleyen: 0.
  1. Mesut odemis

    C# programlamada Visual studio da yazıyorum. Excel dosyasındaki veriyi dosyayı seçerek sistemime yüklüyorum.Dosyasındaki sütunların birinde fatura sıra no diye bir alan var.Fatura sıra no en az 13 haneden oluşuyor örneğin 2016000000123 yada daha uzun olabiliyor. Bunu excel dosyasındaki ilgili hücreye yazınca bu şekilde değil örneğin 2,0000+E0000 vb. şekilde oluyor. Böyle bir veriyi hürce biçimlendirmesi yapmadan hatasız olarak nasıl yükleyebiliriz, kod lazım, hücrenin içini alsın.

  2. Mehmet Gürel

    Cannot cast DBNull.Value to type `System.Double`. Please use a nullable type. Hocam selam excelde hiçbir alan boş olmamasına rağmen böyle bir hata alıyorum. Double olarak istediğim her alan da double. linq ile kullanıyorum. Nedeni nedir?

  3. Sefa

    bu kodlar eskidi ama hocam linq adodan 2,25 kat daha yavaş değilmi

  4. ekrem

    entity yi linqle beraber acces te kullanmanın yolunu ararken, bunu paylaşmanız süper. ekstradan list sınıfı ile çeşitlik linq komutlarını kullanarak yaptığınız paylaşım daha da güzel. süpersiniz. süpersiniz. süpersiniz. teşekkürler ;)