C#中使用MiniExcel讀寫.xlsx文件的代碼實現(xiàn)
背景介紹
報表繞不開 Excel。傳統(tǒng)方案用 Microsoft.Office.Interop,需要安裝 Office,且進程管理復雜。MiniExcel 是一個輕量級庫(< 1MB),通過直接操作 ZIP 壓縮包(.xlsx 本質(zhì)是 ZIP)實現(xiàn)讀寫,無需 Office 環(huán)境,支持 .NET Core / .NET Framework。
本篇覆蓋:
- 基本讀寫(DataTable / List ? Excel)
- 寫入優(yōu)化(避免內(nèi)存膨脹)
- 樣式設置(列寬、行高、背景色)
代碼實現(xiàn)
1. 安裝與基礎讀寫
dotnet add package MiniExcel
using MiniExcelLibs;
// ===== 讀 Excel =====
public void ReadExcel()
{
// 讀取整個 sheet
var rows = MiniExcel.Query("report.xlsx").ToList();
// 讀取指定 sheet
var rows2 = MiniExcel.Query("report.xlsx", sheetName: "Sheet2").ToList();
// 讀取為 DataTable(便于篩選)
var dt = MiniExcel.QueryAsDataTable("report.xlsx");
foreach (DataRow row in dt.Rows)
{
Console.WriteLine($"{row["DeviceId"]} - {row["Value"]}");
}
}
// ===== 寫 Excel =====
public void WriteSimpleExcel()
{
var devices = new[]
{
new { DeviceId = "INJ001", Temperature = 85.5, Pressure = 1.2 },
new { DeviceId = "INJ002", Temperature = 82.3, Pressure = 1.1 }
};
// 最簡單寫法:List 直接寫
MiniExcel.SaveAs("output.xlsx", devices);
// 指定 sheet 名
MiniExcel.SaveAs("output.xlsx", devices, sheetName: "生產(chǎn)數(shù)據(jù)");
}2. 寫入優(yōu)化:分批寫入大文件
public void WriteLargeFile(string filePath, IEnumerable<ReportRow> rows)
{
// MiniExcel 默認會把所有數(shù)據(jù)加載到內(nèi)存
// 大數(shù)據(jù)量時需要分批處理
var batchSize = 5000;
var batch = new List<ReportRow>();
using (var stream = File.Create(filePath))
{
bool firstBatch = true;
foreach (var row in rows)
{
batch.Add(row);
if (batch.Count >= batchSize)
{
if (firstBatch)
{
// 第一批:創(chuàng)建文件 + 寫入表頭
stream.Seek(0, SeekOrigin.Begin);
MiniExcel.SaveAs(stream, batch, printHeader: true);
firstBatch = false;
}
else
{
// 后續(xù)批次:追加到已有 sheet(通過 sheetName)
MiniExcel.AppendExcel(stream, batch, sheetName: "Data");
}
batch.Clear();
}
}
// 處理剩余數(shù)據(jù)
if (batch.Count > 0)
{
if (firstBatch)
MiniExcel.SaveAs(stream, batch, printHeader: true);
else
MiniExcel.AppendExcel(stream, batch, sheetName: "Data");
}
}
}
public class ReportRow
{
public string DeviceId { get; set; }
public DateTime Timestamp { get; set; }
public double Temperature { get; set; }
public double Pressure { get; set; }
}
3. 使用模板生成報表
// 報表模板(template.xlsx)包含:
// - A1: 標題(已合并單元格)
// - A3: 列頭(DeviceId, Timestamp, Temperature...)
// - A4 以下:數(shù)據(jù)區(qū)(空著,等我們填充)
public void GenerateFromTemplate()
{
string templatePath = "template.xlsx";
string outputPath = "report_20240421.xlsx";
// 1. 復制模板
File.Copy(templatePath, outputPath, overwrite: true);
// 2. 讀取模板內(nèi)容(不覆蓋格式)
var template = MiniExcel.QueryAsDataTable(outputPath);
// 3. 準備數(shù)據(jù)
var data = GetProductionData(); // List<ReportRow>
// 4. 寫入數(shù)據(jù)(從 A4 開始)
MiniExcel.SaveAsByTemplate(outputPath, new
{
Title = "2024年4月21日 生產(chǎn)報表",
GenerateDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm"),
Data = data // 這個 key 會對應模板中的 Data 區(qū)域
});
}
4. 樣式設置
public void WriteWithStyle()
{
var rows = new List<Dictionary<string, object>>
{
new Dictionary<string, object> { ["DeviceId"] = "INJ001", ["Value"] = 85.5 },
new Dictionary<string, object> { ["DeviceId"] = "INJ002", ["Value"] = 82.3 }
};
// 設置列配置
var columns = new Dictionary<string, MiniExcelColumnAttribute>
{
["DeviceId"] = new MiniExcelColumnAttribute { Name = "設備編號", Width = 15 },
["Value"] = new MiniExcelColumnAttribute { Name = "測量值", Width = 12, Format = "0.00" }
};
// 寫入并設置列寬
MiniExcel.SaveAs("styled.xlsx", rows, configurations: columns);
}
// 自定義樣式(需要底層操作)
public void WriteWithCustomStyle(string filePath)
{
var config = new MiniExcelConfiguration
{
SheetName = "Report"
};
using var stream = File.Create(filePath);
stream.Seek(0, SeekOrigin.Begin);
// MiniExcel 支持通過 .xlsx 的 shared strings 和 styles.xml
// 完整樣式控制建議用 ClosedXML 或 EPPlus
}
5. 讀取時處理合并單元格
public void ReadMergedCells()
{
// MiniExcel 默認會返回合并單元格的值到每一行
// 如果需要識別合并區(qū)域,手動解析
var cells = MiniExcel.GetCells("merged.xlsx").ToList();
var mergedRanges = cells
.Where(c => c.MergeCount > 0)
.Select(c => new
{
c.Value,
StartRow = c.Row,
EndRow = c.Row + c.MergeCount - 1,
StartCol = c.Column,
EndCol = c.Column + 1 // 簡化:默認橫向合并
})
.ToList();
foreach (var m in mergedRanges)
{
Console.WriteLine($"合并區(qū)域: {m.Value} ({m.StartRow}-{m.EndRow})");
}
}
到此這篇關于C#中使用MiniExcel讀寫.xlsx文件的代碼實現(xiàn)的文章就介紹到這了,更多相關C# MiniExcel讀寫.xlsx文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C#使用Consul集群進行服務注冊與發(fā)現(xiàn)
這篇文章主要介紹了C#使用Consul集群進行服務注冊與發(fā)現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12
VS2013創(chuàng)建Windows服務與調(diào)試服務的圖文方法
這篇文章主要介紹了VS2013創(chuàng)建Windows服務與調(diào)試服務的圖文方法,需要的朋友可以參考下2017-02-02
C#實現(xiàn)的自定義郵件發(fā)送類完整實例(支持多人多附件)
這篇文章主要介紹了C#實現(xiàn)的自定義郵件發(fā)送類,具有支持多人多附件的功能,涉及C#郵件操作的相關技巧,需要的朋友可以參考下2015-12-12

