Web Analytics

MiniExcel

⭐ 3234 stars Turkish by mini-software

NuGet Build durumu star GitHub yıldızları sürüm DeepWiki'ye Sor


Bu proje .NET Foundation'ın bir parçasıdır ve onların davranış kuralları kapsamında çalışmaktadır.


English | 简体中文 | 繁體中文 | 日本語 | 한국어 | हिन्दी | ไทย | Français | Deutsch | Español | Italiano | Русский | Português | Nederlands | Polski | العربية | فارسی | Türkçe | Tiếng Việt | Bahasa Indonesia


Sizin Yıldızlarınız veya Bağışlarınız MiniExcel'i daha iyi yapabilir


Giriş

MiniExcel, .NET için özel olarak tasarlanmış, hafıza kullanımını en aza indirmek üzere geliştirilmiş basit ve verimli bir Excel işleme aracıdır.

Mevcut durumda, çoğu popüler framework, Excel belgesindeki tüm verileri belleğe yükleyerek işlem yapmayı kolaylaştırır, ancak bu durum hafıza tüketimi sorunlarına yol açabilir. MiniExcel'in yaklaşımı ise farklıdır: veriler satır satır akış halinde işlenir, böylece orijinalde yüzlerce megabayt olabilecek tüketim sadece birkaç megabayta düşer ve bellek taşması (OOM) sorunlarının önüne etkin bir şekilde geçilir.

flowchart LR
    A1(["Excel analysis
process"]) --> A2{{"Unzipping
XLSX file"}} --> A3{{"Parsing
OpenXML"}} --> A4{{"Model
conversion"}} --> A5(["Output"])

B1(["Other Excel
Frameworks"]) --> B2{{"Memory"}} --> B3{{"Memory"}} --> B4{{"Workbooks &
Worksheets"}} --> B5(["All rows at
the same time"])

C1(["MiniExcel"]) --> C2{{"Stream"}} --> C3{{"Stream"}} --> C4{{"POCO or dynamic"}} --> C5(["Deferred execution
row by row"])

classDef analysis fill:#D0E8FF,stroke:#1E88E5,color:#0D47A1,font-weight:bold; classDef others fill:#FCE4EC,stroke:#EC407A,color:#880E4F,font-weight:bold; classDef miniexcel fill:#E8F5E9,stroke:#388E3C,color:#1B5E20,font-weight:bold;

class A1,A2,A3,A4,A5 analysis; class B1,B2,B3,B4,B5 others; class C1,C2,C3,C4,C5 miniexcel;

Özellikler

Sürüm 2.0 önizlemesi

Gelecekteki MiniExcel sürümü üzerinde çalışıyoruz; yeni, modüler ve odaklanmış bir API, Core ve Csv işlevleri için ayrı nuget paketleri, IAsyncEnumerable ile tam asenkron akışlı sorgu desteği ve yakında daha fazlası! Paketler ön sürüm olarak sunulacak, dilediğinizde deneyebilir ve bize geri bildirim verebilirsiniz!

Bunu yaparsanız, lütfen yeni dokümanları ve güncelleme notlarını da inceleyin.

Başlarken

Kurulum

Paketi NuGet üzerinden yükleyebilirsiniz

Sürüm Notları

Lütfen Sürüm Notlarına bakın

YAPILACAKLAR

Lütfen TODO adresini kontrol edin

Performans

Karşılaştırmalar için kullanılan kod MiniExcel.Benchmarks adresinde bulunabilir.

Performans testi için kullanılan dosya Test1,000,000x10.xlsx dosyasıdır; hücrelerinde "HelloWorld" yazılı 1.000.000 satır * 10 sütun içeren 32MB büyüklüğünde bir belgedir.

Tüm karşılaştırmaları çalıştırmak için şunu kullanın:

dotnet run -project .\benchmarks\MiniExcel.Benchmarks -c Release -f net9.0 -filter * --join
En son sürümün karşılaştırma sonuçlarını buradan bulabilirsiniz.

Excel Sorgulama/İçe Aktarma

#### 1. Bir sorgu çalıştırın ve sonuçları güçlü türde bir IEnumerable'a eşleyin [[Deneyin]](https://dotnetfiddle.net/w5WD1J)

Daha iyi verimlilik için Stream.Query kullanılması önerilir.

public class UserAccount
{
    public Guid ID { get; set; }
    public string Name { get; set; }
    public DateTime BoD { get; set; }
    public int Age { get; set; }
    public bool VIP { get; set; }
    public decimal Points { get; set; }
}

var rows = MiniExcel.Query(path);

// or

using (var stream = File.OpenRead(path)) var rows = stream.Query();

image

#### 2. Bir sorgu yürütün ve başlık kullanmadan dinamik nesneler listesine eşleyin [[Deneyin]](https://dotnetfiddle.net/w5WD1J)

| MiniExcel | 1 | |-----------|---| | Github | 2 |


var rows = MiniExcel.Query(path).ToList();

// or using (var stream = File.OpenRead(path)) { var rows = stream.Query().ToList();

Assert.Equal("MiniExcel", rows[0].A); Assert.Equal(1, rows[0].B); Assert.Equal("Github", rows[1].A); Assert.Equal(2, rows[1].B); }

#### 3. İlk başlık satırı ile bir sorgu çalıştırın [[Deneyin]](https://dotnetfiddle.net/w5WD1J)

not : aynı sütun adında en sağdaki kullanılır

Girdi Excel :

| Sütun1 | Sütun2 | |-----------|---------| | MiniExcel | 1 | | Github | 2 |


var rows = MiniExcel.Query(useHeaderRow:true).ToList();

// or

using (var stream = File.OpenRead(path)) { var rows = stream.Query(useHeaderRow:true).ToList();

Assert.Equal("MiniExcel", rows[0].Column1); Assert.Equal(1, rows[0].Column2); Assert.Equal("Github", rows[1].Column1); Assert.Equal(2, rows[1].Column2); }

#### 4. Sorgu Desteği LINQ Uzantısı First/Take/Skip ...vb.

Sorgu First

var row = MiniExcel.Query(path).First();
Assert.Equal("HelloWorld", row.A);

// or

using (var stream = File.OpenRead(path)) { var row = stream.Query().First(); Assert.Equal("HelloWorld", row.A); }

MiniExcel/ExcelDataReader/ClosedXML/EPPlus arasındaki performans queryfirst

#### 5. Sayfa adına göre sorgulama

MiniExcel.Query(path, sheetName: "SheetName");
//or
stream.Query(sheetName: "SheetName");
#### 6. Tüm sayfa adlarını ve satırları sorgulama

var sheetNames = MiniExcel.GetSheetNames(path);
foreach (var sheetName in sheetNames)
{
    var rows = MiniExcel.Query(path, sheetName: sheetName);
}
#### 7. Sütunları Al

var columns = MiniExcel.GetColumns(path); // e.g result : ["A","B"...]

var cnt = columns.Count; // get column count

#### 8. Dinamik Sorguda satırı IDictionary tipine dökme

foreach(IDictionary row in MiniExcel.Query(path))
{
    //..
}

// or var rows = MiniExcel.Query(path).Cast>(); // or Query specified ranges (capitalized) // A2 represents the second row of column A, C3 represents the third row of column C // If you don't want to restrict rows, just don't include numbers var rows = MiniExcel.QueryRange(path, startCell: "A2", endCell: "C3").Cast>();

#### 9. Excel sorgusu ile DataTable döndürme

Önerilmez, çünkü DataTable tüm verileri belleğe yükler ve MiniExcel'in düşük bellek tüketimi özelliğini kaybeder.

``C# var table = MiniExcel.QueryAsDataTable(path, useHeaderRow: true);

image

#### 10. Verilerin okunmaya başlanacağı hücreyi belirtin

csharp MiniExcel.Query(path,useHeaderRow:true,startCell:"B3")
image

#### 11. Birleştirilmiş Hücreleri Doldur

Not: Verimlilik, birleştirme doldurma kullanılmadığında daha hızlıdır

Sebep: OpenXml standardı, mergeCells'i dosyanın en altına koyar, bu da sheetxml üzerinde iki kez dolaşmayı gerektirir

csharp var config = new OpenXmlConfiguration() { FillMergedCells = true }; var rows = MiniExcel.Query(path, configuration: config);
image

değişken uzunluk ve genişlikte çoklu satır ve sütun doldurma desteği

image

#### 12. Disk tabanlı önbellek ile büyük dosya okuma (Disk-Base Cache - SharedString)

Eğer SharedStrings boyutu 5 MB'ı aşarsa, MiniExcel varsayılan olarak yerel disk önbelleği kullanır, örn. 10x100000.xlsx(bir milyon satır veri), disk önbelleği devre dışı bırakıldığında maksimum bellek kullanımı 195MB olurken, disk önbelleği etkinleştirildiğinde yalnızca 65MB gerekir. Not: Bu optimizasyonun bir miktar verimlilik maliyeti vardır, bu nedenle bu durumda okuma süresi 7,4 saniyeden 27,2 saniyeye çıkar. Eğer buna ihtiyacınız yoksa, disk önbelleğini aşağıdaki kodla devre dışı bırakabilirsiniz:

csharp var config = new OpenXmlConfiguration { EnableSharedStringCache = false }; MiniExcel.Query(path,configuration: config)
SharedStringCacheSize'ı, disk önbellekleme için belirtilen boyutun ötesinde sharedString dosya boyutunu değiştirmek için kullanabilirsiniz.
csharp var config = new OpenXmlConfiguration { SharedStringCacheSize=50010241024 }; MiniExcel.Query(path, configuration: config);
image

image

Excel Oluştur/Export Et

  • Genel parametresiz kurucuya sahip soyut olmayan bir tip olmalıdır.
  • MiniExcel, IEnumerable Parametresiyle Ertelenmiş Yürütmeyi destekler. En az hafıza kullanımı için, lütfen ToList gibi metodları çağırmayın.
örneğin: ToList veya değil hafıza kullanımı image

#### 1. Anonim veya güçlü tip [[Deneyin]](https://dotnetfiddle.net/w5WD1J)

csharp var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.xlsx"); MiniExcel.SaveAs(path, new[] { new { Column1 = "MiniExcel", Column2 = 1 }, new { Column1 = "Github", Column2 = 2} });
#### 2. IEnumerable>

csharp var values = new List>() { new Dictionary{{ "Column1", "MiniExcel" }, { "Column2", 1 } }, new Dictionary{{ "Column1", "Github" }, { "Column2", 2 } } }; MiniExcel.SaveAs(path, values);
Dosya Sonucu Oluştur :

| Sütun1 | Sütun2 | |-----------|---------| | MiniExcel | 1 | | Github | 2 |

#### 3. IDataReader

  • Önerilir, tüm verinin belleğe yüklenmesini önleyebilir
csharp MiniExcel.SaveAs(path, reader);
image

DataReader birden fazla sayfa dışa aktarır (Dapper ExecuteReader tarafından önerilir)

csharp using (var cnn = Connection) { cnn.Open(); var sheets = new Dictionary(); sheets.Add("sheet1", cnn.ExecuteReader("select 1 id")); sheets.Add("sheet2", cnn.ExecuteReader("select 2 id")); MiniExcel.SaveAs("Demo.xlsx", sheets); }
#### 4. Veri Tablosu

  • Tavsiye edilmez, tüm veriyi belleğe yükler
  • VeriTablosu önce Sütun Adı olarak Başlık kullanır, sonra sütun adını kullanır
csharp var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.xlsx"); var table = new DataTable(); { table.Columns.Add("Column1", typeof(string)); table.Columns.Add("Column2", typeof(decimal)); table.Rows.Add("MiniExcel", 1); table.Rows.Add("Github", 2); }

MiniExcel.SaveAs(path, table);

####  5. Dapper Sorgusu

Teşekkürler @shaofing #552 , lütfen CommandDefinition + CommandFlags.NoCache kullanın

csharp using (var connection = GetConnection(connectionString)) { var rows = connection.Query( new CommandDefinition( @"select 'MiniExcel' as Column1,1 as Column2 union all select 'Github',2" , flags: CommandFlags.NoCache) ); // Note: QueryAsync will throw close connection exception MiniExcel.SaveAs(path, rows); }
Aşağıdaki kod tüm verileri belleğe yükleyecektir

csharp using (var connection = GetConnection(connectionString)) { var rows = connection.Query(@"select 'MiniExcel' as Column1,1 as Column2 union all select 'Github',2"); MiniExcel.SaveAs(path, rows); }
#### 6. MemoryStream'e SaveAs  [[Deneyin]](https://dotnetfiddle.net/JOen0e)

csharp using (var stream = new MemoryStream()) //support FileStream,MemoryStream ect. { stream.SaveAs(values); }
ör. : excel dışa aktarma api'si

csharp public IActionResult DownloadExcel() { var values = new[] { new { Column1 = "MiniExcel", Column2 = 1 }, new { Column1 = "Github", Column2 = 2} };

var memoryStream = new MemoryStream(); memoryStream.SaveAs(values); memoryStream.Seek(0, SeekOrigin.Begin); return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = "demo.xlsx" }; }

#### 7. Birden Fazla Sayfa Oluşturun

csharp // 1. Dictionary var users = new[] { new { Name = "Jack", Age = 25 }, new { Name = "Mike", Age = 44 } }; var department = new[] { new { ID = "01", Name = "HR" }, new { ID = "02", Name = "IT" } }; var sheets = new Dictionary { ["users"] = users, ["department"] = department }; MiniExcel.SaveAs(path, sheets);

// 2. DataSet var sheets = new DataSet(); sheets.Add(UsersDataTable); sheets.Add(DepartmentDataTable); //.. MiniExcel.SaveAs(path, sheets);

image

#### 8. TabloStil Seçenekleri

Varsayılan stil

image

Stil yapılandırması olmadan

csharp var config = new OpenXmlConfiguration() { TableStyles = TableStyles.None }; MiniExcel.SaveAs(path, value,configuration:config);
image

#### 9. Otomatik Filtre

v0.19.0 sürümünden itibaren OpenXmlConfiguration.AutoFilter ile Otomatik Filtre etkinleştirilebilir veya devre dışı bırakılabilir, varsayılan değeri true'dur ve Otomatik Filtre ayarlama şekli:

csharp MiniExcel.SaveAs(path, value, configuration: new OpenXmlConfiguration() { AutoFilter = false });

#### 10. Görüntü Oluştur

csharp var value = new[] { new { Name="github",Image=File.ReadAllBytes(PathHelper.GetFile("images/github_logo.png"))}, new { Name="google",Image=File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png"))}, new { Name="microsoft",Image=File.ReadAllBytes(PathHelper.GetFile("images/microsoft_logo.png"))}, new { Name="reddit",Image=File.ReadAllBytes(PathHelper.GetFile("images/reddit_logo.png"))}, new { Name="statck_overflow",Image=File.ReadAllBytes(PathHelper.GetFile("images/statck_overflow_logo.png"))}, }; MiniExcel.SaveAs(path, value);
image

#### 11. Bayt Dizisi Dosya Dışa Aktarımı

1.22.0'dan itibaren, değer türü byte[] olduğunda sistem varsayılan olarak hücrede dosya yolunu kaydeder ve içe aktarım sırasında sistem bunu byte[]'ye dönüştürebilir. Eğer bunu kullanmak istemiyorsanız, OpenXmlConfiguration.EnableConvertByteArray'i false olarak ayarlayabilirsiniz, bu sistem verimliliğini artırabilir.

image

1.22.0'dan itibaren, değer türü byte[] olduğunda sistem varsayılan olarak hücrede dosya yolunu kaydeder ve içe aktarım sırasında sistem bunu byte[]'ye dönüştürebilir. Eğer bunu kullanmak istemiyorsanız, OpenXmlConfiguration.EnableConvertByteArray'i false olarak ayarlayabilirsiniz, bu sistem verimliliğini artırabilir.

image

#### 12. Aynı Hücreleri Dikey Birleştirme

Bu işlevsellik yalnızca xlsx formatında desteklenir ve hücreleri @merge ve @endmerge etiketleri arasında dikey olarak birleştirir. @mergelimit kullanarak hücrelerin dikey olarak birleştirilme sınırlarını belirleyebilirsiniz.

csharp var mergedFilePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");

var path = @"../../../../../samples/xlsx/TestMergeWithTag.xlsx";

MiniExcel.MergeSameCells(mergedFilePath, path);

csharp var memoryStream = new MemoryStream();

var path = @"../../../../../samples/xlsx/TestMergeWithTag.xlsx";

memoryStream.MergeSameCells(path);

Birleştirme öncesi ve sonrası dosya içeriği:

Birleştirme limiti olmadan:

Screenshot 2023-08-07 at 11 59 24

Screenshot 2023-08-07 at 11 59 57

Birleştirme limitiyle:

Screenshot 2023-08-08 at 18 21 00

Screenshot 2023-08-08 at 18 21 40

#### 13. Null değerleri atla

Null değerler için boş hücre yazmak üzere yeni açık seçenek:

csharp DataTable dt = new DataTable();

/ ... /

DataRow dr = dt.NewRow();

dr["Name1"] = "Somebody once"; dr["Name2"] = null; dr["Name3"] = "told me.";

dt.Rows.Add(dr);

OpenXmlConfiguration configuration = new OpenXmlConfiguration() { EnableWriteNullValueCell = true // Default value. };

MiniExcel.SaveAs(@"C:\temp\Book1.xlsx", dt, configuration: configuration);

image

xml Somebody once told me.
Önceki davranış:

csharp / ... /

OpenXmlConfiguration configuration = new OpenXmlConfiguration() { EnableWriteNullValueCell = false // Default value is true. };

MiniExcel.SaveAs(@"C:\temp\Book1.xlsx", dt, configuration: configuration);

görsel

xml Somebody once told me.
Null ve DBNull değerleri için çalışır.

#### 14. Bölmeleri Dondur

csharp / ... /

OpenXmlConfiguration configuration = new OpenXmlConfiguration() { FreezeRowCount = 1, // default is 1 FreezeColumnCount = 2 // default is 0 };

MiniExcel.SaveAs(@"C:\temp\Book1.xlsx", dt, configuration: configuration);

image

Excel Şablonuna Veri Doldurma

  • Tanımlama, Vue şablonundaki gibi {{değişken adı}} veya koleksiyon gösterimi {{koleksiyon adı.alan adı}} şeklindedir
  • Koleksiyon gösterimi IEnumerable/DataTable/DapperRow destekler
#### 1. Temel Doldurma

Şablon: image

Sonuç: image

Kod:

csharp // 1. By POCO var value = new { Name = "Jack", CreateDate = new DateTime(2021, 01, 01), VIP = true, Points = 123 }; MiniExcel.SaveAsByTemplate(path, templatePath, value);

// 2. By Dictionary var value = new Dictionary() { ["Name"] = "Jack", ["CreateDate"] = new DateTime(2021, 01, 01), ["VIP"] = true, ["Points"] = 123 }; MiniExcel.SaveAsByTemplate(path, templatePath, value);

#### 2. IEnumerable Veri Doldurma

Not1: Liste doldurma için aynı sütunun ilk IEnumerable'ını temel olarak kullanın

Şablon: image

Sonuç: image

Kod:

csharp //1. By POCO var value = new { employees = new[] { new {name="Jack",department="HR"}, new {name="Lisa",department="HR"}, new {name="John",department="HR"}, new {name="Mike",department="IT"}, new {name="Neo",department="IT"}, new {name="Loan",department="IT"} } }; MiniExcel.SaveAsByTemplate(path, templatePath, value);

//2. By Dictionary var value = new Dictionary() { ["employees"] = new[] { new {name="Jack",department="HR"}, new {name="Lisa",department="HR"}, new {name="John",department="HR"}, new {name="Mike",department="IT"}, new {name="Neo",department="IT"}, new {name="Loan",department="IT"} } }; MiniExcel.SaveAsByTemplate(path, templatePath, value);

#### 3. Karmaşık Veri Doldurma

Not: Çoklu sayfa desteği ve aynı değişkenin kullanılması

Şablon:

image

Sonuç:

image

csharp // 1. By POCO var value = new { title = "FooCompany", managers = new[] { new {name="Jack",department="HR"}, new {name="Loan",department="IT"} }, employees = new[] { new {name="Wade",department="HR"}, new {name="Felix",department="HR"}, new {name="Eric",department="IT"}, new {name="Keaton",department="IT"} } }; MiniExcel.SaveAsByTemplate(path, templatePath, value);

// 2. By Dictionary var value = new Dictionary() { ["title"] = "FooCompany", ["managers"] = new[] { new {name="Jack",department="HR"}, new {name="Loan",department="IT"} }, ["employees"] = new[] { new {name="Wade",department="HR"}, new {name="Felix",department="HR"}, new {name="Eric",department="IT"}, new {name="Keaton",department="IT"} } }; MiniExcel.SaveAsByTemplate(path, templatePath, value);

#### 4. Büyük Veri Performansını Doldurma

NOT: MiniExcel'de IEnumerable gecikmeli yürütme kullanmak, ToList yerine maksimum bellek kullanımını azaltabilir

image

#### 5. Hücre değeri otomatik eşleme türü

Şablon

image

Sonuç

image

Sınıf

csharp public class Poco { public string @string { get; set; } public int? @int { get; set; } public decimal? @decimal { get; set; } public double? @double { get; set; } public DateTime? datetime { get; set; } public bool? @bool { get; set; } public Guid? Guid { get; set; } }
Kod

csharp var poco = new TestIEnumerableTypePoco { @string = "string", @int = 123, @decimal = decimal.Parse("123.45"), @double = (double)123.33, @datetime = new DateTime(2021, 4, 1), @bool = true, @Guid = Guid.NewGuid() }; var value = new { Ts = new[] { poco, new TestIEnumerableTypePoco{}, null, poco } }; MiniExcel.SaveAsByTemplate(path, templatePath, value);
#### 6. Örnek :  Github Projelerini Listele

Şablon

image

Sonuç

image

Kod

csharp var projects = new[] { new {Name = "MiniExcel",Link="https://github.com/mini-software/MiniExcel",Star=146, CreateTime=new DateTime(2021,03,01)}, new {Name = "HtmlTableHelper",Link="https://github.com/mini-software/HtmlTableHelper",Star=16, CreateTime=new DateTime(2020,02,01)}, new {Name = "PocoClassGenerator",Link="https://github.com/mini-software/PocoClassGenerator",Star=16, CreateTime=new DateTime(2019,03,17)} }; var value = new { User = "ITWeiHan", Projects = projects, TotalStar = projects.Sum(s => s.Star) }; MiniExcel.SaveAsByTemplate(path, templatePath, value);
#### 7. Gruplandırılmış Veri Doldurma

csharp var value = new Dictionary() { ["employees"] = new[] { new {name="Jack",department="HR"}, new {name="Jack",department="HR"}, new {name="John",department="HR"}, new {name="John",department="IT"}, new {name="Neo",department="IT"}, new {name="Loan",department="IT"} } }; await MiniExcel.SaveAsByTemplateAsync(path, templatePath, value);
##### 1. @group etiketiyle ve @header etiketiyle

Önce

before_with_header

Sonra

after_with_header

##### 2. Sadece @group etiketiyle ve @header etiketi olmadan

Önce

before_without_header

Sonra

after_without_header

##### 3. @group etiketi olmadan

Önce

without_group

Sonra

without_group_after

#### 8. Hücre içinde If/ElseIf/Else İfadeleri

Kurallar:

  • DateTime, Double, Int için ==, !=, >, >=, <, <= operatörlerini destekler.
  • String için ==, != operatörlerini destekler.
  • Her ifade yeni satırda olmalıdır.
  • Operatörlerin öncesinde ve sonrasında birer boşluk olmalıdır.
  • İfadelerin içinde yeni satır olmamalıdır.
  • Hücre tam olarak aşağıdaki formatta olmalıdır.
csharp @if(name == Jack) {{employees.name}} @elseif(name == Neo) Test {{employees.name}} @else {{employees.department}} @endif
Önce

if_before

Sonra

if_after

#### 9. Parametre olarak DataTable

csharp var managers = new DataTable(); { managers.Columns.Add("name"); managers.Columns.Add("department"); managers.Rows.Add("Jack", "HR"); managers.Rows.Add("Loan", "IT"); } var value = new Dictionary() { ["title"] = "FooCompany", ["managers"] = managers, }; MiniExcel.SaveAsByTemplate(path, templatePath, value);
#### 10. Formüller

##### 1. Örnek Formülünüzün başına $ ekleyin ve yinelemeli başlangıç ve bitiş satırlarına referans vermek için $enumrowstart ve $enumrowend kullanın:

image

Şablon oluşturulduğunda, $ öneki kaldırılır ve $enumrowstart ile $enumrowend yinelemeli başlangıç ve bitiş satır numaraları ile değiştirilir:

image

##### 2. Diğer Örnek Formüller:

| | | |--------------|-------------------------------------------------------------------------------------------| | Toplam | $=SUM(C{{$enumrowstart}}:C{{$enumrowend}}) | | Alternatif Ortalama | $=SUM(C{{$enumrowstart}}:C{{$enumrowend}}) / COUNT(C{{$enumrowstart}}:C{{$enumrowend}}) | | Aralık | $=MAX(C{{$enumrowstart}}:C{{$enumrowend}}) - MIN(C{{$enumrowstart}}:C{{$enumrowend}}) |

#### 11. Diğer

##### 1. Şablon parametre anahtarını kontrol etme

V1.24.0'dan itibaren, varsayılan olarak eksik şablon parametre anahtarı yoksayılır ve boş dizeyle değiştirilir, IgnoreTemplateParameterMissing istisna fırlatılıp fırlatılmayacağını kontrol edebilir.

csharp var config = new OpenXmlConfiguration() { IgnoreTemplateParameterMissing = false, }; MiniExcel.SaveAsByTemplate(path, templatePath, value, config)
image

Excel Sütun Adı/İndeks/Yoksay Özelliği

#### 1. Sütun adını, sütun indeksini, sütunu yoksaymayı belirtin

Excel Örneği

image

Kod

csharp public class ExcelAttributeDemo { [ExcelColumnName("Column1")] public string Test1 { get; set; } [ExcelColumnName("Column2")] public string Test2 { get; set; } [ExcelIgnore] public string Test3 { get; set; } [ExcelColumnIndex("I")] // system will convert "I" to 8 index public string Test4 { get; set; } public string Test5 { get; } //wihout set will ignore public string Test6 { get; private set; } //un-public set will ignore [ExcelColumnIndex(3)] // start with 0 public string Test7 { get; set; } }

var rows = MiniExcel.Query(path).ToList(); Assert.Equal("Column1", rows[0].Test1); Assert.Equal("Column2", rows[0].Test2); Assert.Null(rows[0].Test3); Assert.Equal("Test7", rows[0].Test4); Assert.Null(rows[0].Test5); Assert.Null(rows[0].Test6); Assert.Equal("Test4", rows[0].Test7);

#### 2. Özel Format (ExcelFormatAttribute)

V0.21.0'dan itibaren, ToString(string content) metodunu içeren sınıf formatı desteklenmektedir

Sınıf

csharp public class Dto { public string Name { get; set; }

[ExcelFormat("MMMM dd, yyyy")] public DateTime InDate { get; set; } }

Kod

csharp var value = new Dto[] { new Issue241Dto{ Name="Jack",InDate=new DateTime(2021,01,04)}, new Issue241Dto{ Name="Henry",InDate=new DateTime(2020,04,05)}, }; MiniExcel.SaveAs(path, value);
Sonuç

image

Sorgu özel format dönüşümünü destekler

image

#### 3. Sütun Genişliğini Ayarlama (ExcelColumnWidthAttribute)

csharp public class Dto { [ExcelColumnWidth(20)] public int ID { get; set; } [ExcelColumnWidth(15.50)] public string Name { get; set; } }
#### 4. Birden fazla sütun adının aynı özelliğe eşlenmesi.

csharp public class Dto { [ExcelColumnName(excelColumnName:"EmployeeNo",aliases:new[] { "EmpNo","No" })] public string Empno { get; set; } public string Name { get; set; } }

#### 5. System.ComponentModel.DisplayNameAttribute = ExcelColumnName.excelColumnNameAttribute

1.24.0'dan itibaren, sistem System.ComponentModel.DisplayNameAttribute = ExcelColumnName.excelColumnNameAttribute desteğini sağlar.

C# public class TestIssueI4TXGTDto { public int ID { get; set; } public string Name { get; set; } [DisplayName("Specification")] public string Spc { get; set; } [DisplayName("Unit Price")] public decimal Up { get; set; } }
#### 6. ExcelColumnAttribute

V1.26.0'dan itibaren, birden fazla özellik aşağıdaki gibi sadeleştirilebilir:

csharp public class TestIssueI4ZYUUDto { [ExcelColumn(Name = "ID",Index =0)] public string MyProperty { get; set; } [ExcelColumn(Name = "CreateDate", Index = 1,Format ="yyyy-MM",Width =100)] public DateTime MyProperty2 { get; set; } }
#### 7. DynamicColumnAttribute

V1.26.0 sürümünden itibaren, Sütunun özelliklerini dinamik olarak ayarlayabiliriz

csharp var config = new OpenXmlConfiguration { DynamicColumns = new DynamicExcelColumn[] { new DynamicExcelColumn("id"){Ignore=true}, new DynamicExcelColumn("name"){Index=1,Width=10}, new DynamicExcelColumn("createdate"){Index=0,Format="yyyy-MM-dd",Width=15}, new DynamicExcelColumn("point"){Index=2,Name="Account Point"}, } }; var path = PathHelper.GetTempPath(); var value = new[] { new { id = 1, name = "Jack", createdate = new DateTime(2022, 04, 12) ,point = 123.456} }; MiniExcel.SaveAs(path, value, configuration: config);
image

#### 8. DinamikSayfaÖzniteliği

V1.31.4 sürümünden itibaren, Sayfa'nın özniteliklerini dinamik olarak ayarlayabiliriz. Sayfa adını ve durumunu (görünürlüğünü) ayarlayabiliriz.

csharp var configuration = new OpenXmlConfiguration { DynamicSheets = new DynamicExcelSheet[] { new DynamicExcelSheet("usersSheet") { Name = "Users", State = SheetState.Visible }, new DynamicExcelSheet("departmentSheet") { Name = "Departments", State = SheetState.Hidden } } };

var users = new[] { new { Name = "Jack", Age = 25 }, new { Name = "Mike", Age = 44 } }; var department = new[] { new { ID = "01", Name = "HR" }, new { ID = "02", Name = "IT" } }; var sheets = new Dictionary { ["usersSheet"] = users, ["departmentSheet"] = department };

var path = PathHelper.GetTempPath(); MiniExcel.SaveAs(path, sheets, configuration: configuration);

Ayrıca yeni ExcelSheetAttribute özniteliğini de kullanabiliriz:

C# [ExcelSheet(Name = "Departments", State = SheetState.Hidden)] private class DepartmentDto { [ExcelColumn(Name = "ID",Index = 0)] public string ID { get; set; } [ExcelColumn(Name = "Name",Index = 1)] public string Name { get; set; } }
### Ekle, Sil, Güncelle

#### Ekle

v1.28.0 CSV'ye son satırdan sonra N satır veri eklemeyi destekler

csharp // Origin { var value = new[] { new { ID=1,Name ="Jack",InDate=new DateTime(2021,01,03)}, new { ID=2,Name ="Henry",InDate=new DateTime(2020,05,03)}, }; MiniExcel.SaveAs(path, value); } // Insert 1 rows after last { var value = new { ID=3,Name = "Mike", InDate = new DateTime(2021, 04, 23) }; MiniExcel.Insert(path, value); } // Insert N rows after last { var value = new[] { new { ID=4,Name ="Frank",InDate=new DateTime(2021,06,07)}, new { ID=5,Name ="Gloria",InDate=new DateTime(2022,05,03)}, }; MiniExcel.Insert(path, value); }
image

v1.37.0 excel mevcut bir çalışma kitabına yeni bir sayfa eklemeyi destekler

csharp // Origin excel { var value = new[] { new { ID=1,Name ="Jack",InDate=new DateTime(2021,01,03)}, new { ID=2,Name ="Henry",InDate=new DateTime(2020,05,03)}, }; MiniExcel.SaveAs(path, value, sheetName: "Sheet1"); } // Insert a new sheet { var value = new { ID=3,Name = "Mike", InDate = new DateTime(2021, 04, 23) }; MiniExcel.Insert(path, table, sheetName: "Sheet2"); }
#### Sil(beklemede)

#### Güncelle(beklemede)

Excel Türü Otomatik Kontrol

  • MiniExcel varsayılan olarak dosya uzantısına göre xlsx veya csv olup olmadığını kontrol eder, ancak bu yöntemde hata olabilir, lütfen elle belirtin.
  • Akışın hangi excel türünden olduğu bilinememektedir, lütfen elle belirtin.
csharp stream.SaveAs(excelType:ExcelType.CSV); //or stream.SaveAs(excelType:ExcelType.XLSX); //or stream.Query(excelType:ExcelType.CSV); //or stream.Query(excelType:ExcelType.XLSX);
 

CSV

#### Not

  • Varsayılan olarak string türü döner ve değer sayılara veya tarih-saat'e dönüştürülmez, ancak tür güçlü tip tanımlaması ile belirtilirse dönüştürülür.
#### Özel ayırıcı

Varsayılan olarak ayırıcı ,'dır, özelleştirme için Seperator özelliğini değiştirebilirsiniz.

csharp var config = new MiniExcelLibs.Csv.CsvConfiguration() { Seperator=';' }; MiniExcel.SaveAs(path, values,configuration: config);
V1.30.1 sürümünden itibaren özel ayırıcı fonksiyonunu destekler (teşekkürler @hyzx86)

csharp var config = new CsvConfiguration() { SplitFn = (row) => Regex.Split(row, $"\"" target="_blank" rel="noopener noreferrer">\t,$)") .Select(s => Regex.Replace(s.Replace("\"\"", "\""), "^\"|\"$", "")).ToArray() }; var rows = MiniExcel.Query(path, configuration: config).ToList();
#### Özel satır sonu

Varsayılan olarak satır sonu karakteri \r\n'dir, özelleştirme için NewLine özelliğini değiştirebilirsiniz

csharp var config = new MiniExcelLibs.Csv.CsvConfiguration() { NewLine='\n' }; MiniExcel.SaveAs(path, values,configuration: config);
#### Özel kodlama

  • Varsayılan kodlama "Bayt Sırası İşaretlerinden Kodlamayı Algıla"dır (detectEncodingFromByteOrderMarks: true)
  • Eğer özel kodlama gereksinimleriniz varsa, lütfen StreamReaderFunc / StreamWriterFunc özelliğini değiştirin
csharp // Read var config = new MiniExcelLibs.Csv.CsvConfiguration() { StreamReaderFunc = (stream) => new StreamReader(stream,Encoding.GetEncoding("gb2312")) }; var rows = MiniExcel.Query(path, true,excelType:ExcelType.CSV,configuration: config);

// Write var config = new MiniExcelLibs.Csv.CsvConfiguration() { StreamWriterFunc = (stream) => new StreamWriter(stream, Encoding.GetEncoding("gb2312")) }; MiniExcel.SaveAs(path, value,excelType:ExcelType.CSV, configuration: config);

#### Boş dizeyi null olarak oku

Varsayılan olarak, boş değerler string.Empty'ye eşlenir. Bu davranışı değiştirebilirsiniz

csharp var config = new MiniExcelLibs.Csv.CsvConfiguration() { ReadEmptyStringAsNull = true };
### DataReader

#### 1. GetReader 1.23.0'dan itibaren, GetDataReader kullanabilirsiniz

csharp using (var reader = MiniExcel.GetReader(path,true)) { while (reader.Read()) { for (int i = 0; i < reader.FieldCount; i++) { var value = reader.GetValue(i); } } }

Async

  • v0.17.0 Async desteği (teşekkürler isdaniel ( SHIH,BING-SIOU)](https://github.com/isdaniel))
csharp public static Task SaveAsAsync(string path, object value, bool printHeader = true, string sheetName = "Sheet1", ExcelType excelType = ExcelType.UNKNOWN, IConfiguration configuration = null) public static Task SaveAsAsync(this Stream stream, object value, bool printHeader = true, string sheetName = "Sheet1", ExcelType excelType = ExcelType.XLSX, IConfiguration configuration = null) public static Task> QueryAsync(string path, bool useHeaderRow = false, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, string startCell = "A1", IConfiguration configuration = null) public static Task> QueryAsync(this Stream stream, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, string startCell = "A1", IConfiguration configuration = null) where T : class, new() public static Task> QueryAsync(string path, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, string startCell = "A1", IConfiguration configuration = null) where T : class, new() public static Task>> QueryAsync(this Stream stream, bool useHeaderRow = false, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, string startCell = "A1", IConfiguration configuration = null) public static Task SaveAsByTemplateAsync(this Stream stream, string templatePath, object value) public static Task SaveAsByTemplateAsync(this Stream stream, byte[] templateBytes, object value) public static Task SaveAsByTemplateAsync(string path, string templatePath, object value) public static Task SaveAsByTemplateAsync(string path, byte[] templateBytes, object value) public static Task QueryAsDataTableAsync(string path, bool useHeaderRow = true, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, string startCell = "A1", IConfiguration configuration = null)
-  v1.25.0 cancellationToken desteği.

Diğerleri

#### 1. Enum

Excel ve özellik adının aynı olduğundan emin olun, sistem otomatik olarak eşleyecektir (büyük/küçük harf duyarsız)

image

V0.18.0'dan itibaren Enum Açıklama desteği

csharp public class Dto { public string Name { get; set; } public I49RYZUserType UserType { get; set; } }

public enum Type { [Description("General User")] V1, [Description("General Administrator")] V2, [Description("Super Administrator")] V3 }

image

1.30.0 sürümünden itibaren excel Açıklamasını Enum'a destekleme eklendi, teşekkürler @KaneLeung

#### 2. CSV'yi XLSX'e Dönüştür veya XLSX'i CSV'ye Dönüştür

csharp MiniExcel.ConvertXlsxToCsv(xlsxPath, csvPath); MiniExcel.ConvertXlsxToCsv(xlsxStream, csvStream); MiniExcel.ConvertCsvToXlsx(csvPath, xlsxPath); MiniExcel.ConvertCsvToXlsx(csvStream, xlsxStream);
`csharp
using (var excelStream = new FileStream(path: filePath, FileMode.Open, FileAccess.Read))
using (var csvStream = new MemoryStream())
{
   MiniExcel.ConvertXlsxToCsv(excelStream, csvStream);
}
#### 3. Özel CultureInfo

1.22.0 sürümünden itibaren, aşağıdaki gibi özel CultureInfo kullanabilirsiniz, sistem varsayılanı CultureInfo.InvariantCulture'dır.

var config = new CsvConfiguration()
{
    Culture = new CultureInfo("fr-FR"),
};
MiniExcel.SaveAs(path, value, configuration: config);

// or MiniExcel.Query(path, configuration: config);

#### 4. Özel Tampon Boyutu

    public abstract class Configuration : IConfiguration
    {
        public int BufferSize { get; set; } = 1024 * 512;
    }
#### 5. HızlıMod

Sistem belleği kontrol etmeyecek, ancak daha hızlı kayıt hızı elde edebilirsiniz.

var config = new OpenXmlConfiguration() { FastMode = true };
MiniExcel.SaveAs(path, reader,configuration:config);
#### 6. Toplu Resim Ekleme (MiniExcel.AddPicture)

Lütfen toplu olarak satır verisi oluşturmadan önce resimleri ekleyin, aksi takdirde AddPicture çağrıldığında sistem yüksek bellek kullanımıyla karşılaşabilir.

var images = new[]
{
    new MiniExcelPicture
    {
        ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/github_logo.png")),
        SheetName = null, // default null is first sheet
        CellAddress = "C3", // required
    },
    new MiniExcelPicture
    {
        ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png")),
        PictureType = "image/png", // default PictureType = image/png
        SheetName = "Demo",
        CellAddress = "C9", // required
        WidthPx = 100,
        HeightPx = 100,
    },
};
MiniExcel.AddPicture(path, images);
Görsel

#### 7. Sayfa Boyutlarını Al

var dim = MiniExcel.GetSheetDimensions(path);

Örnekler:

#### 1. SQLite & Dapper Büyük Boyutlu Dosya SQL Ekleme ile OOM'dan Kaçınma

not: Lütfen Query'den sonra ToList/ToArray metodlarını çağırmayın, tüm veriler belleğe yüklenir

using (var connection = new SQLiteConnection(connectionString))
{
    connection.Open();
    using (var transaction = connection.BeginTransaction())
    using (var stream = File.OpenRead(path))
    {
       var rows = stream.Query();
       foreach (var row in rows)
             connection.Execute("insert into T (A,B) values (@A,@B)", new { row.A, row.B }, transaction: transaction);
       transaction.Commit();
    }
}
performans: image

#### 2. ASP.NET Core 3.1 veya MVC 5 Excel Xlsx İndirme/Yükleme API Demo Deneyin

public class ApiController : Controller
{
    public IActionResult Index()
    {
        return new ContentResult
        {
            ContentType = "text/html",
            StatusCode = (int)HttpStatusCode.OK,
            Content = @"
DownloadExcel
DownloadExcelFromTemplatePath
DownloadExcelFromTemplateBytes

Upload Excel


public IActionResult DownloadExcel() { var values = new[] { new { Column1 = "MiniExcel", Column2 = 1 }, new { Column1 = "Github", Column2 = 2} }; var memoryStream = new MemoryStream(); memoryStream.SaveAs(values); memoryStream.Seek(0, SeekOrigin.Begin); return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = "demo.xlsx" }; }

public IActionResult DownloadExcelFromTemplatePath() { string templatePath = "TestTemplateComplex.xlsx";

Dictionary value = new Dictionary() { ["title"] = "FooCompany", ["managers"] = new[] { new {name="Jack",department="HR"}, new {name="Loan",department="IT"} }, ["employees"] = new[] { new {name="Wade",department="HR"}, new {name="Felix",department="HR"}, new {name="Eric",department="IT"}, new {name="Keaton",department="IT"} } };

MemoryStream memoryStream = new MemoryStream(); memoryStream.SaveAsByTemplate(templatePath, value); memoryStream.Seek(0, SeekOrigin.Begin); return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = "demo.xlsx" }; }

private static Dictionary TemplateBytesCache = new Dictionary();

static ApiController() { string templatePath = "TestTemplateComplex.xlsx"; byte[] bytes = System.IO.File.ReadAllBytes(templatePath); TemplateBytesCache.Add(templatePath, bytes); }

public IActionResult DownloadExcelFromTemplateBytes() { byte[] bytes = TemplateBytesCache["TestTemplateComplex.xlsx"];

Dictionary value = new Dictionary() { ["title"] = "FooCompany", ["managers"] = new[] { new {name="Jack",department="HR"}, new {name="Loan",department="IT"} }, ["employees"] = new[] { new {name="Wade",department="HR"}, new {name="Felix",department="HR"}, new {name="Eric",department="IT"}, new {name="Keaton",department="IT"} } };

MemoryStream memoryStream = new MemoryStream(); memoryStream.SaveAsByTemplate(bytes, value); memoryStream.Seek(0, SeekOrigin.Begin); return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = "demo.xlsx" }; }

public IActionResult UploadExcel(IFormFile excel) { var stream = new MemoryStream(); excel.CopyTo(stream);

foreach (var item in stream.Query(true)) { // do your logic etc. }

return Ok("File uploaded successfully"); } }

#### 3. Sayfalama Sorgusu

void Main()
{
    var rows = MiniExcel.Query(path);

Console.WriteLine("==== No.1 Page ===="); Console.WriteLine(Page(rows,pageSize:3,page:1)); Console.WriteLine("==== No.50 Page ===="); Console.WriteLine(Page(rows,pageSize:3,page:50)); Console.WriteLine("==== No.5000 Page ===="); Console.WriteLine(Page(rows,pageSize:3,page:5000)); }

public static IEnumerable Page(IEnumerable en, int pageSize, int page) { return en.Skip(page * pageSize).Take(pageSize); }

20210419

#### 4. WebForm ile Excel'i Memorystream kullanarak dışa aktarma

var fileName = "Demo.xlsx";
var sheetName = "Sheet1";
HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
response.AddHeader("Content-Disposition", $"attachment;filename=\"{fileName}\"");
var values = new[] {
    new { Column1 = "MiniExcel", Column2 = 1 },
    new { Column1 = "Github", Column2 = 2}
};
var memoryStream = new MemoryStream();
memoryStream.SaveAs(values, sheetName: sheetName);
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.CopyTo(Response.OutputStream);
response.End();
#### 5. Dinamik i18n çoklu dil ve rol yetki yönetimi

Örnekteki gibi, i18n ve yetki yönetimini ele almak için bir yöntem oluşturun ve dinamik ve düşük bellekli işleme etkileri elde etmek için yield return ile IEnumerable> döndürün

void Main()
{
    var value = new Order[] {
        new Order(){OrderNo = "SO01",CustomerID="C001",ProductID="P001",Qty=100,Amt=500},
        new Order(){OrderNo = "SO02",CustomerID="C002",ProductID="P002",Qty=300,Amt=400},
    };

Console.WriteLine("en-Us and Sales role"); { var path = Path.GetTempPath() + Guid.NewGuid() + ".xlsx"; var lang = "en-US"; var role = "Sales"; MiniExcel.SaveAs(path, GetOrders(lang, role, value)); MiniExcel.Query(path, true).Dump(); }

Console.WriteLine("zh-CN and PMC role"); { var path = Path.GetTempPath() + Guid.NewGuid() + ".xlsx"; var lang = "zh-CN"; var role = "PMC"; MiniExcel.SaveAs(path, GetOrders(lang, role, value)); MiniExcel.Query(path, true).Dump(); } }

private IEnumerable> GetOrders(string lang, string role, Order[] orders) { foreach (var order in orders) { var newOrder = new Dictionary();

if (lang == "zh-CN") { newOrder.Add("客户编号", order.CustomerID); newOrder.Add("订单编号", order.OrderNo); newOrder.Add("产品编号", order.ProductID); newOrder.Add("数量", order.Qty); if (role == "Sales") newOrder.Add("价格", order.Amt); yield return newOrder; } else if (lang == "en-US") { newOrder.Add("Customer ID", order.CustomerID); newOrder.Add("Order No", order.OrderNo); newOrder.Add("Product ID", order.ProductID); newOrder.Add("Quantity", order.Qty); if (role == "Sales") newOrder.Add("Amount", order.Amt); yield return newOrder; } else { throw new InvalidDataException($"lang {lang} wrong"); } } }

public class Order { public string OrderNo { get; set; } public string CustomerID { get; set; } public decimal Qty { get; set; } public string ProductID { get; set; } public decimal Amt { get; set; } }

image

SSS

#### S: Excel başlık adı, sınıf özelliği adı ile aynı değilse nasıl eşleştirme yapılır?

C. Lütfen ExcelColumnName özniteliğini kullanın

image

#### S. Birden fazla sayfayı nasıl sorgular veya dışa aktarırım?

C. GetSheetNames yöntemi ile Query sheetName parametresini kullanın.

var sheets = MiniExcel.GetSheetNames(path);
foreach (var sheet in sheets)
{
    Console.WriteLine($"sheet name : {sheet} ");
    var rows = MiniExcel.Query(path,useHeaderRow:true,sheetName:sheet);
    Console.WriteLine(rows);
}
image

#### S. Sayfa görünürlüğü hakkında bilgi nasıl sorgulanır veya dışa aktarılır?

C. GetSheetInformations yöntemi.

var sheets = MiniExcel.GetSheetInformations(path);
foreach (var sheetInfo in sheets)
{
    Console.WriteLine($"sheet index : {sheetInfo.Index} "); // next sheet index - numbered from 0
    Console.WriteLine($"sheet name : {sheetInfo.Name} ");   // sheet name
    Console.WriteLine($"sheet state : {sheetInfo.State} "); // sheet visibility state - visible / hidden
}
#### S. Count kullanmak tüm verileri belleğe yükler mi?

Hayır, görsel testte 1 milyon satır*10 sütun veri var, maksimum bellek kullanımı <60MB ve 13,65 saniye sürüyor

image

#### S. Query nasıl tamsayı indeksleri kullanır?

Query'nin varsayılan indeksi string Anahtar: A,B,C.... Eğer sayısal indeks kullanmak istiyorsanız, lütfen aşağıdaki yöntemi oluşturarak dönüştürün

void Main()
{
    var path = @"D:\git\MiniExcel\samples\xlsx\TestTypeMapping.xlsx";
    var rows = MiniExcel.Query(path,true);
    foreach (var r in ConvertToIntIndexRows(rows))
    {
        Console.Write($"column 0 : {r[0]} ,column 1 : {r[1]}");
        Console.WriteLine();
    }
}

private IEnumerable> ConvertToIntIndexRows(IEnumerable rows) { ICollection keys = null; var isFirst = true; foreach (IDictionary r in rows) { if(isFirst) { keys = r.Keys; isFirst = false; }

var dic = new Dictionary(); var index = 0; foreach (var key in keys) dic[index++] = r[key]; yield return dic; } } #### S. Başlıksız boş Excel, değer boş olduğunda dışa aktarılırken oluşturuluyor

MiniExcel, API işlemlerini basitleştirmek için JSON.NET'e benzer şekilde dinamik olarak değerden türü alır; veri olmadan tür bilinemediği için bu durum oluşur. Anlamak için issue #133 konusuna bakabilirsiniz.

image

Güçlü tip & DataTable başlık üretir, fakat Dictionary hâlâ boş Excel oluşturur

#### S. Boş satırda foreach nasıl durdurulur?

MiniExcel, foreach döngüsünü durdurmak için LINQ TakeWhile ile birlikte kullanılabilir.

Image

#### S. Boş satırlar nasıl kaldırılır?

image

IEnumerable :

public static IEnumerable QueryWithoutEmptyRow(Stream stream, bool useHeaderRow, string sheetName, ExcelType excelType, string startCell, IConfiguration configuration)
{
    var rows = stream.Query(useHeaderRow,sheetName,excelType,startCell,configuration);
    foreach (IDictionary row in rows)
    {
        if(row.Keys.Any(key=>row[key]!=null))
            yield return row;
    }
}

VeriTablosu :

public static DataTable QueryAsDataTableWithoutEmptyRow(Stream stream, bool useHeaderRow, string sheetName, ExcelType excelType, string startCell, IConfiguration configuration)
{
    if (sheetName == null && excelType != ExcelType.CSV) /Issue #279/
        sheetName = stream.GetSheetNames().First();

var dt = new DataTable(sheetName); var first = true; var rows = stream.Query(useHeaderRow,sheetName,excelType,startCell,configuration); foreach (IDictionary row in rows) { if (first) {

foreach (var key in row.Keys) { var column = new DataColumn(key, typeof(object)) { Caption = key }; dt.Columns.Add(column); }

dt.BeginLoadData(); first = false; }

var newRow = dt.NewRow(); var isNull=true; foreach (var key in row.Keys) { var _v = row[key]; if(_v!=null) isNull = false; newRow[key] = _v; }

if(!isNull) dt.Rows.Add(newRow); }

dt.EndLoadData(); return dt; }

#### S. SaveAs(path,value) ile mevcut dosyayı nasıl değiştirebilir ve "...xlsx dosyası zaten var" hatası almadan kaydedebilirim?

Lütfen özel dosya oluşturma mantığı için Stream sınıfını kullanın, örneğin:

`C# using (var stream = File.Create("Demo.xlsx")) MiniExcel.SaveAs(stream,value);

veya, V1.25.0'dan itibaren, SaveAs mevcut dosyanın üzerine yazmayı etkinleştirmek/devre dışı bırakmak için overwriteFile parametresini destekler

csharp MiniExcel.SaveAs(path, value, overwriteFile: true); ``

Sınırlamalar ve uyarılar

  • Şu anda xls ve şifreli dosyalar desteklenmiyor
  • xlsm yalnızca Sorgu'yu destekler

Referanslar

ExcelDataReader / ClosedXML / Dapper / ExcelNumberFormat

Teşekkürler

#### Jetbrains

jetbrains-variant-2

Bu proje için ücretsiz Tüm ürünler IDE'si sağladığınız için teşekkürler (Lisans)

Katkı paylaşımı bağışı

Bağlantı https://github.com/orgs/mini-software/discussions/754

Katkıda Bulunanlar

--- Tranlated By Open Ai Tx | Last indexed: 2025-10-09 ---