- 1. C# ile Excel Dosyasından Veri Okuma ve Yazma Neden Önemli?
- 1.1. ClosedXML Nedir?
- 1.2. C# Excel Kütüphaneleri Nasıl Ayrılır?
- 2. Proje Kurulumu
- 3. Örnek Excel Dosyasını Hazırlama
- 4. C# ile Excel Dosyasından Veri Okuma
- 4.1. Belirli Bir Hücre Nasıl Okunur?
- 5. C# ile Excel Dosyasına Veri Yazma
- 6. Mevcut Excel Dosyasına Yeni Satır Ekleme
- 7. Hata Yönetimi Nasıl Kurulur?
- 8. Performans ve Güvenlik Önerileri
- 8.1. ASP.NET Core Projesinde Excel Dosyası Okuma
- 9. Sık Sorulan Sorular
C# ile Excel Dosyasından Veri Okuma ve Yazma Neden Önemli?
Excel, küçük işletmelerden kurumsal yazılım ekiplerine kadar pek çok çalışma alanında veri taşır. Stok listeleri, fiyat raporları, müşteri kayıtları ve sipariş dökümleri çoğu zaman .xlsx formatında tutulur. C# geliştiricileri bu dosyaları kodla yöneterek tekrarlayan işleri azaltır. Bir otomasyon uygulaması Excel satırlarını okuyabilir, verileri doğrulayabilir ve sonuçları veritabanına aktarabilir. Aynı uygulama rapor dosyası üretebilir, hücreleri biçimlendirebilir ve kullanıcının açabileceği temiz bir tablo sunabilir. Bu rehber stok verileri üzerinden ilerler. Örnek dosya ürün kodu, ürün adı, stok miktarı ve fiyat alanlarını taşır. Kod yapısı farklı projelere kolayca uyarlanabilir.
ClosedXML Nedir?
ClosedXML, Excel 2007 ve yeni sürümlerin .xlsx ile .xlsm dosyalarını C# üzerinden yönetir. Kütüphane Open XML altyapısını daha anlaşılır sınıflarla sunar. Bilgisayarda Microsoft Excel kurulumuna ihtiyaç duymaz. XLWorkbook sınıfı çalışma kitabını temsil eder. IXLWorksheet yapısı çalışma sayfasını yönetir. Hücre erişimi satır ve sütun numarasıyla ya da A1 biçimindeki adresle sağlanır.
C# Excel Kütüphaneleri Nasıl Ayrılır?
Projenin boyutu, dosya biçimi ve sunucu ortamı kütüphane seçimini etkiler. Aşağıdaki karşılaştırma yaygın üç yaklaşımı özetler.

| Yöntem | Excel kurulumu | Güçlü yön | Uygun kullanım |
| ClosedXML | Gerekmez | Okunaklı API, hızlı geliştirme | .xlsx raporları, stok ve sipariş dosyaları |
| Open XML SDK | Gerekmez | Dosya yapısında ayrıntılı kontrol | Çok büyük dosyalar, özel XML işlemleri |
| Excel Interop | Gerekir | Masaüstü Excel özelliklerine erişim | Windows masaüstü otomasyonu |
Proje Kurulumu
Bilgisayarda güncel .NET SDK bulunmalıdır. Aşağıdaki komutlar yeni bir konsol projesi açar ve ClosedXML paketini projeye ekler.
dotnet new console -n ExcelOrnegi cd ExcelOrnegi dotnet add package ClosedXML.NET 10 ve yeni SDK sürümleri aynı paket için dotnet package add ClosedXML biçimini de destekler. NuGet işlemi paket başvurusunu proje dosyasına ekler ve bağımlılıkları indirir.
- Proje türü: Console App, ASP.NET Core, WinForms veya WPF
- Paket: ClosedXML
- Dosya biçimi: .xlsx
- Çalışma sayfası adı: Urunler
Örnek Excel Dosyasını Hazırlama
urunler.xlsx adlı dosyada Urunler isimli bir çalışma sayfası açın. Birinci satıra sütun başlıklarını yazın. Veri satırlarını ikinci satırdan başlatın.
| Sütun | Başlık | C# tipi | Görev |
| A | UrunKodu | string | Ürünü benzersiz kodla tanımlar. |
| B | UrunAdi | string | Ürünün görünen adını taşır. |
| C | Stok | int | Mevcut ürün adedini tutar. |
| D | Fiyat | decimal | Ürün satış fiyatını saklar. |
C# ile Excel Dosyasından Veri Okuma
Okuma işlemi üç temel görev içerir. Kod dosyanın varlığını denetler, çalışma kitabını açar ve dolu satırları Urun nesnelerine çevirir.
- BaseDirectory uygulamanın çalıştığı klasörü verir.
- XLWorkbook seçilen Excel dosyasını belleğe alır.
- Worksheet metodu Urunler sayfasını seçer.
- RowsUsed yalnızca veri taşıyan satırları döndürür.
- Skip(1) başlık satırını veri listesinin dışında tutar.
- TryGetValue sayısal hücreleri güvenli biçimde int ve decimal türlerine çevirir.
using ClosedXML.Excel; using System; using System.Collections.Generic; using System.IO; using System.Linq; string dosyaYolu = Path.Combine( AppContext.BaseDirectory, "urunler.xlsx" ); if (!File.Exists(dosyaYolu)) { throw new FileNotFoundException( "Excel dosyası bulunamadı.", dosyaYolu ); } var urunler = new List(); using (var calismaKitabi = new XLWorkbook(dosyaYolu)) { var sayfa = calismaKitabi.Worksheet("Urunler"); foreach (var satir in sayfa.RowsUsed().Skip(1)) { string kod = satir.Cell(1).GetString().Trim(); string ad = satir.Cell(2).GetString().Trim(); if (string.IsNullOrWhiteSpace(kod)) { continue; } satir.Cell(3).TryGetValue(out int stok); satir.Cell(4).TryGetValue(out decimal fiyat); urunler.Add(new Urun(kod, ad, stok, fiyat)); } } foreach (var urun in urunler) { Console.WriteLine( $"{urun.UrunKodu} | {urun.UrunAdi} | " + $"{urun.Stok} | {urun.Fiyat:N2} TL" ); } public record Urun( string UrunKodu, string UrunAdi, int Stok, decimal Fiyat );GetString hücrenin değerini metin olarak döndürür. Trim baştaki ve sondaki boşlukları temizler. Boş ürün kodu taşıyan satır listeye girmez. TryGetValue dönüşüm başarısız olduğunda false değeri üretir. out değişkeni varsayılan sayısal değeri alır. Gerçek projede hatalı satırı kayıt altına almak veri kalitesini korur.
Belirli Bir Hücre Nasıl Okunur?
Tek bir hücre için tüm satırları dolaşmak gerekmez. Cell metodu A1 adresini ya da satır-sütun numarasını kabul eder.
using var calismaKitabi = new XLWorkbook("urunler.xlsx"); var sayfa = calismaKitabi.Worksheet("Urunler"); string urunAdi = sayfa.Cell("B2").GetString(); int stok = sayfa.Cell(2, 3).GetValue(); Console.WriteLine($"{urunAdi}: {stok} adet");GetValue geçersiz veri tipinde hata fırlatır. Kullanıcı tarafından doldurulan dosyalarda TryGetValue daha güvenli bir seçim sunar.
C# ile Excel Dosyasına Veri Yazma
Yeni bir XLWorkbook nesnesi boş çalışma kitabını temsil eder. Kod bir çalışma sayfası ekler, başlıkları yazar, ürün listesini satırlara taşır ve dosyayı SaveAs ile kaydeder.
using ClosedXML.Excel; using System; using System.Collections.Generic; using System.IO; var urunler = new List { new("TS001", "C# Developer Tişört", 18, 499.90m), new("TS002", "Excel Formül Tişört", 9, 459.90m), new("TS003", "Kod Temalı Kupa", 24, 229.90m) }; string ciktiYolu = Path.Combine( AppContext.BaseDirectory, "stok-raporu.xlsx" ); using var calismaKitabi = new XLWorkbook(); var sayfa = calismaKitabi.Worksheets.Add("Urunler"); string[] basliklar = { "UrunKodu", "UrunAdi", "Stok", "Fiyat" }; for (int sutun = 0; sutun < basliklar.Length; sutun++) { sayfa.Cell(1, sutun + 1).Value = basliklar[sutun]; } int satirNo = 2; foreach (var urun in urunler) { sayfa.Cell(satirNo, 1).Value = urun.UrunKodu; sayfa.Cell(satirNo, 2).Value = urun.UrunAdi; sayfa.Cell(satirNo, 3).Value = urun.Stok; sayfa.Cell(satirNo, 4).Value = urun.Fiyat; satirNo++; } var baslikAraligi = sayfa.Range("A1:D1"); baslikAraligi.Style.Font.Bold = true; baslikAraligi.Style.Font.FontColor = XLColor.White; baslikAraligi.Style.Fill.BackgroundColor = XLColor.FromHtml("#107C41"); sayfa.Column(4).Style.NumberFormat.Format = "#,##0.00"; sayfa.SheetView.FreezeRows(1); sayfa.Range(1, 1, satirNo - 1, 4) .CreateTable("UrunTablosu"); sayfa.Columns(1, 4).AdjustToContents(); calismaKitabi.SaveAs(ciktiYolu); Console.WriteLine($"Dosya hazır: {ciktiYolu}"); public record Urun( string UrunKodu, string UrunAdi, int Stok, decimal Fiyat );CreateTable hücre aralığını Excel tablosuna çevirir. Tablo başlıkları filtre denetimi kazanır. FreezeRows üst satırı kaydırma sırasında görünür tutar. AdjustToContents sütun genişliklerini içerik ölçüsüne göre ayarlar. Çok büyük veri kümelerinde bu işlem süreyi uzatabilir. Genişliği sabit değerlerle sınırlamak toplu raporlarda daha hızlı sonuç verir.
Mevcut Excel Dosyasına Yeni Satır Ekleme
Stok uygulaması çoğu zaman var olan çalışma kitabına yeni kayıt ekler. LastRowUsed son dolu satırı bulur. Kod bir alt satıra ürün değerlerini yazar ve Save çağrısıyla aynı dosyayı günceller.
using ClosedXML.Excel; string dosyaYolu = "urunler.xlsx"; using var calismaKitabi = new XLWorkbook(dosyaYolu); var sayfa = calismaKitabi.Worksheet("Urunler"); int sonSatir = sayfa.LastRowUsed()?.RowNumber() ?? 1; int yeniSatir = sonSatir + 1; sayfa.Cell(yeniSatir, 1).Value = "TS006"; sayfa.Cell(yeniSatir, 2).Value = "Yeni Ürün"; sayfa.Cell(yeniSatir, 3).Value = 12; sayfa.Cell(yeniSatir, 4).Value = 349.90m; calismaKitabi.Save();Hata Yönetimi Nasıl Kurulur?
Üretim ortamında dosya yolu, sayfa adı, hücre tipi ve erişim izni sık hata kaynaklarıdır. try-catch bloğu kullanıcıya anlaşılır mesaj sunar ve uygulamanın denetimsiz biçimde kapanmasını önler.
try { using var calismaKitabi = new XLWorkbook("urunler.xlsx"); var sayfa = calismaKitabi.Worksheet("Urunler"); Console.WriteLine( sayfa.Cell("B2").GetString() ); } catch (FileNotFoundException ex) { Console.WriteLine( $"Dosya bulunamadı: {ex.FileName}" ); } catch (IOException ex) { Console.WriteLine( $"Dosya erişim hatası: {ex.Message}" ); } catch (Exception ex) { Console.WriteLine( $"İşlem tamamlanamadı: {ex.Message}" ); }| Sorun | Olası neden | Çözüm |
| Dosya bulunamadı | Yanlış klasör veya dosya adı | Path.Combine ile yolu kurun ve File.Exists çağrısını çalıştırın. |
| Sayfa bulunamadı | Worksheet adı farklı | Worksheets koleksiyonundaki adları denetleyin. |
| Sayı 0 geliyor | Hücre metin ya da boş değer taşıyor | TryGetValue sonucunu kontrol edin ve hatalı satırı kayda alın. |
| Dosya kaydolmuyor | Dosya açık veya klasör yazmaya kapalı | Dosyayı kapatın ya da yazılabilir çıktı klasörü seçin. |
| Bellek yükseliyor | Çalışma kitabı çok büyük | Dosyayı bölün veya düşük seviyeli akış yaklaşımını değerlendirin. |
Performans ve Güvenlik Önerileri
ClosedXML çalışma kitabını bellekte işler. On binlerce satır çoğu standart raporda rahat bir deneyim sunar. Yüz binlerce satır, çok sayıda stil ve büyük görseller bellek tüketimini yükseltir.
- Rows yerine RowsUsed çağrısını seçin.
- Her hücreye ayrı stil vermek yerine hücre aralığını biçimlendirin.
- AdjustToContents çağrısını yalnızca gereken sütunlarda çalıştırın.
- using yapısıyla XLWorkbook nesnesini zamanında serbest bırakın.
- Yüklenen dosyanın uzantısını, boyutunu ve gerçek içeriğini denetleyin.
- Web uygulamasında dosya adını sunucunun güvenli klasör kurallarına göre üretin.
- Kullanıcı mesajında sistem klasörü ve ayrıntılı sunucu yolunu göstermeyin.
Hücrelerden gelen metinleri SQL sorgusuna doğrudan eklemeyin. Parametreli komutlar SQL enjeksiyonu riskini azaltır. Excel verisini güvenilir kaynak gibi kabul etmeyin.
ASP.NET Core Projesinde Excel Dosyası Okuma
Web uygulaması IFormFile üzerinden yüklenen Excel dosyasını Stream olarak alabilir. XLWorkbook stream nesnesini açar. Sunucu diski geçici dosya için zorunlu hale gelmez.
[HttpPost] public IActionResult ExcelYukle(IFormFile dosya) { if (dosya is null || dosya.Length == 0) { return BadRequest("Dosya seçilmedi."); } using var stream = dosya.OpenReadStream(); using var calismaKitabi = new XLWorkbook(stream); var sayfa = calismaKitabi.Worksheet(1); int kayitSayisi = Math.Max(sayfa.RowsUsed().Count() - 1, 0); return Ok(new { kayitSayisi }); }Yükleme sınırı uygulama ayarlarında tanımlanmalıdır. Dosya uzantısı tek başına güvenlik kanıtı sunmaz. Boyut sınırı ve içerik kontrolü sunucu kaynaklarını korur.
Sık Sorulan Sorular
C# ile Excel okumak için Microsoft Excel gerekir mi?
ClosedXML .xls dosyasını açar mı?
Excel hücresindeki formül mü yoksa sonuç mu okunur?
C# ile Excel dosyasına resim eklenebilir mi?
Çok büyük Excel dosyasında hangi yöntem seçilir?
ClosedXML ticari projede kullanılabilir mi?
Debug ettikçe güzelleşen bir dünya için..




