C# WinForm讀取Excel的三種方法及對(duì)比詳解
什么是WinForm讀取Excel?
想象一下你的程序變成一個(gè)“魔法盒子”——點(diǎn)擊按鈕,它就能“吞掉”Excel文件,再“吐出”整齊的數(shù)據(jù)!這就是WinForm讀取Excel的神奇之處!
核心問題:
- 如何用C#快速讀取Excel文件?
- 為什么有時(shí)候程序會(huì)報(bào)錯(cuò)“找不到文件”?
- 為什么Excel文件打開后程序卡死?
3種主流方法對(duì)比
| 方法 | 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|---|
| Microsoft Interop | 功能強(qiáng)大、支持復(fù)雜操作 | 需安裝Office、性能差 |
| EPPlus | 無需Office、開源免費(fèi) | 僅支持.xlsx格式 |
| NPOI | 支持.xls/.xlsx、跨平臺(tái) | 代碼稍復(fù)雜 |
方法1:Microsoft Interop(需安裝Office)
1. 準(zhǔn)備工作
- 安裝Office(Windows系統(tǒng)必備?。?/li>
- 在Visual Studio中添加引用:
Microsoft.Office.Interop.Excel
2. 代碼模板
using Excel = Microsoft.Office.Interop.Excel;
public class ExcelReader
{
public static void ReadExcelFile()
{
// 1. 打開文件對(duì)話框
OpenFileDialog openFileDialog = new OpenFileDialog
{
Filter = "Excel 文件 (*.xls, *.xlsx)|*.xls;*.xlsx",
Title = "請(qǐng)選擇Excel文件"
};
if (openFileDialog.ShowDialog() != DialogResult.OK) return;
string filePath = openFileDialog.FileName;
// 2. 創(chuàng)建Excel應(yīng)用實(shí)例
Excel.Application excelApp = new Excel.Application();
Excel.Workbook workbook = null;
Excel.Worksheet worksheet = null;
try
{
// 3. 打開工作簿
workbook = excelApp.Workbooks.Open(filePath);
worksheet = workbook.Sheets[1]; // 默認(rèn)讀取第一個(gè)工作表
// 4. 獲取已使用范圍
Excel.Range range = worksheet.UsedRange;
// 5. 遍歷單元格
for (int row = 1; row <= range.Rows.Count; row++)
{
for (int col = 1; col <= range.Columns.Count; col++)
{
// 6. 讀取單元格值
object cellValue = range.Cells[row, col].Value2;
Console.Write(cellValue?.ToString() ?? "NULL" + "\t");
}
Console.WriteLine();
}
}
catch (Exception ex)
{
Console.WriteLine("讀取失?。? + ex.Message);
}
finally
{
// 7. 釋放COM對(duì)象(非常重要!)
if (workbook != null) workbook.Close(false);
if (excelApp != null) excelApp.Quit();
ReleaseComObject(worksheet);
ReleaseComObject(workbook);
ReleaseComObject(excelApp);
}
}
private static void ReleaseComObject(object obj)
{
if (obj != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
}
}
代碼解析:
- OpenFileDialog:讓用戶選擇Excel文件路徑。
- Interop API:通過
Workbooks.Open()打開文件,UsedRange獲取數(shù)據(jù)范圍。 - COM對(duì)象釋放:必須手動(dòng)釋放,否則程序會(huì)殘留進(jìn)程!
方法2:EPPlus(無需Office)
1. 準(zhǔn)備工作
安裝NuGet包:
Install-Package EPPlus
2. 代碼模板
using OfficeOpenXml;
using System.IO;
public class EpplusReader
{
public static void ReadExcelFile()
{
OpenFileDialog openFileDialog = new OpenFileDialog
{
Filter = "Excel 文件 (*.xlsx)|*.xlsx",
Title = "請(qǐng)選擇Excel文件"
};
if (openFileDialog.ShowDialog() != DialogResult.OK) return;
string filePath = openFileDialog.FileName;
using (var package = new ExcelPackage(new FileInfo(filePath)))
{
// 1. 獲取第一個(gè)工作表
ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
int rowCount = worksheet.Dimension.Rows;
int colCount = worksheet.Dimension.Columns;
// 2. 遍歷單元格
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= colCount; col++)
{
// 3. 讀取單元格值
string cellValue = worksheet.Cells[row, col].Text;
Console.Write(cellValue + "\t");
}
Console.WriteLine();
}
}
}
}
代碼解析:
- ExcelPackage:直接加載文件,無需Office依賴。
- Dimension:自動(dòng)獲取行列數(shù),省心省力!
- Text屬性:自動(dòng)處理日期、數(shù)字等格式。
方法3:NPOI(兼容.xls/.xlsx)
1. 準(zhǔn)備工作
安裝NuGet包:
Install-Package NPOI
2. 代碼模板
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;
public class NpoiReader
{
public static void ReadExcelFile()
{
OpenFileDialog openFileDialog = new OpenFileDialog
{
Filter = "Excel 文件 (*.xls, *.xlsx)|*.xls;*.xlsx",
Title = "請(qǐng)選擇Excel文件"
};
if (openFileDialog.ShowDialog() != DialogResult.OK) return;
string filePath = openFileDialog.FileName;
IWorkbook workbook = null;
using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
// 1. 根據(jù)文件擴(kuò)展名選擇加載器
if (filePath.EndsWith(".xls"))
{
workbook = new HSSFWorkbook(file); // .xls格式
}
else if (filePath.EndsWith(".xlsx"))
{
workbook = new XSSFWorkbook(file); // .xlsx格式
}
}
if (workbook == null) return;
ISheet sheet = workbook.GetSheetAt(0); // 獲取第一個(gè)工作表
// 2. 遍歷行
for (int rowIndex = 0; rowIndex <= sheet.LastRowNum; rowIndex++)
{
IRow row = sheet.GetRow(rowIndex);
if (row == null) continue;
// 3. 遍歷單元格
for (int colIndex = 0; colIndex < row.LastCellNum; colIndex++)
{
ICell cell = row.GetCell(colIndex);
string cellValue = cell?.ToString() ?? "NULL";
Console.Write(cellValue + "\t");
}
Console.WriteLine();
}
}
}
代碼解析:
- HSSFWorkbook/XSSFWorkbook:分別處理.xls和.xlsx文件。
- GetRow/GetCell:靈活獲取行和單元格。
- ToString():自動(dòng)處理空值和格式。
常見問題與優(yōu)化技巧
1. 程序運(yùn)行后卡死?
場(chǎng)景:Interop方法中未正確關(guān)閉Excel進(jìn)程!
解決方案:
// 在finally塊中強(qiáng)制退出
if (excelApp != null)
{
excelApp.Quit();
ReleaseComObject(excelApp);
}
2. 文件路徑錯(cuò)誤?
場(chǎng)景:用戶選擇文件后未檢查路徑合法性!
解決方案:
if (!File.Exists(filePath))
{
MessageBox.Show("文件不存在!");
return;
}
3. Excel文件打不開?
場(chǎng)景:文件被其他程序占用!
解決方案:
try
{
workbook = excelApp.Workbooks.Open(filePath);
}
catch (Exception ex)
{
MessageBox.Show("文件被占用,請(qǐng)關(guān)閉Excel后再試!");
}
方法對(duì)比總結(jié)
| 方法 | 是否需要Office | 支持格式 | 性能 | 難度 |
|---|---|---|---|---|
| Interop | ? 必須 | .xls/.xlsx | ?? 慢 | ?? 中 |
| EPPlus | ? 不需要 | .xlsx | ? 快 | ? 簡(jiǎn)單 |
| NPOI | ? 不需要 | .xls/.xlsx | ? 快 | ?? 中 |
實(shí)戰(zhàn)場(chǎng)景:Excel數(shù)據(jù)導(dǎo)入DataGridView
private void ImportToDataGridView(string filePath)
{
dataGridView1.Rows.Clear();
dataGridView1.Columns.Clear();
using (var package = new ExcelPackage(new FileInfo(filePath)))
{
var worksheet = package.Workbook.Worksheets[0];
int colCount = worksheet.Dimension.Columns;
// 添加列頭
for (int col = 1; col <= colCount; col++)
{
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = worksheet.Cells[1, col].Text
});
}
// 添加數(shù)據(jù)行
for (int row = 2; row <= worksheet.Dimension.Rows; row++)
{
var cells = new List<string>();
for (int col = 1; col <= colCount; col++)
{
cells.Add(worksheet.Cells[row, col].Text);
}
dataGridView1.Rows.Add(cells.ToArray());
}
}
}
代碼解析:
- DataGridView綁定:動(dòng)態(tài)創(chuàng)建列和行,實(shí)時(shí)顯示Excel數(shù)據(jù)。
- 從第二行開始讀取:通常第一行為標(biāo)題。
最佳實(shí)踐建議
- 異步加載:
- 大文件讀取時(shí)使用
async/await,避免界面卡頓。
- 大文件讀取時(shí)使用
- 錯(cuò)誤提示:
- 用
try/catch捕獲文件路徑錯(cuò)誤、格式錯(cuò)誤等問題。
- 用
- 日志記錄:
- 記錄讀取過程中的關(guān)鍵信息,方便調(diào)試。
- 性能優(yōu)化:
- 優(yōu)先選擇EPPlus或NPOI,避免Interop的性能瓶頸。
- 用戶友好:
- 提供“打開文件”、“保存為CSV”等按鈕,提升交互體驗(yàn)。
以上就是C# WinForm讀取Excel的三種方法及對(duì)比詳解的詳細(xì)內(nèi)容,更多關(guān)于C# WinForm讀取Excel的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#使用Lazy實(shí)現(xiàn)延遲加載的方法示例
在C#中,Lazy< T> 類是一個(gè)非常有用的工具,它可以用于延遲加載值,在本文中,我們將詳細(xì)介紹 Lazy< T> 的實(shí)現(xiàn)機(jī)制和用法,并提供一些示例來展示它的優(yōu)勢(shì),文中通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-06-06
C#實(shí)現(xiàn)char字符數(shù)組與字符串相互轉(zhuǎn)換的方法
這篇文章主要介紹了C#實(shí)現(xiàn)char字符數(shù)組與字符串相互轉(zhuǎn)換的方法,結(jié)合實(shí)例形式簡(jiǎn)單分析了C#字符數(shù)組轉(zhuǎn)字符串及字符串轉(zhuǎn)字符數(shù)組的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-02-02
基于C#實(shí)現(xiàn)的三層架構(gòu)實(shí)例
這篇文章主要介紹了基于C#實(shí)現(xiàn)的三層架構(gòu)實(shí)例,非常實(shí)用,需要的朋友可以參考下2014-08-08
c# 面試必備線程基礎(chǔ)知識(shí)點(diǎn)
這篇文章主要介紹了c# 面試必備線程基礎(chǔ)知識(shí)點(diǎn),幫助大家更好的鞏固,掌握線程的基礎(chǔ)知識(shí),感興趣的朋友可以了解下2020-11-11

