C# 讀取 Excel 範例解析|NPOI 程式碼逐步說明|C# Excel 系列

更新 發佈閱讀 15 分鐘

當你已經了解如何讀取 Excel,接下來最重要的是看懂程式碼。本篇將針對 C# 讀取 Excel 的完整範例進行解析,逐步說明 NPOI 程式碼的運作方式,幫助你真正理解每一段邏輯,而不是只會複製貼上。

開始範例程式碼解析

1 . 開啟 C# 讀取 Excel 教學|使用 NPOI 進行資料處理|C# Excel 系列 建立的程式

vocus|新世代的創作平台

2 . 程式碼研究

我們找到button1按下會執行的程式碼,開始一行一行解讀。

private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel Files|*.xlsx;*.xls";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = openFileDialog.FileName;
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{

XSSFWorkbook workbook = new XSSFWorkbook(fs);


ISheet sheet = workbook.GetSheetAt(0);


for (int rowIndex = 0;rowIndex <= sheet.LastRowNum; rowIndex++)
{
IRow row = sheet.GetRow(rowIndex);
if (row != null)
{

for (int colIndex = 0;colIndex < row.LastCellNum; colIndex++)
{
ICell cell = row.GetCell(colIndex);
if (cell != null)
{

string cellValue = cell.ToString();
Console.WriteLine($"Row {rowIndex + 1},Column {colIndex + 1}: {cellValue}");
}
}
}
}
}
}
}

程式碼片段:

  1. OpenFileDialog openFileDialog = new OpenFileDialog();
  2. openFileDialog.Filter = "Excel Files|*.xlsx;*.xls";
  3. if (openFileDialog.ShowDialog() == DialogResult.OK)
  4. {

-------------------------------------------------------------------------------------------------------

1 、2 行是使用Windows Forms裡面自己內建的原件,先創建一個出來並且限制檔案只能選取Excel檔案,這個元件可以用來彈跳出一個選擇檔案的視窗。

第3行 執行ShowDialog()會把彈跳視窗叫出來,並且它會等待你選好檔案後按下開啟去執行第4行大括弧裡面的動作。如果把這個視窗關閉則這個元件就不會收到DialogResult.OK的訊號,就不會執行大括弧裡面的動作。

這段執行後就會如下圖跳出視窗。

vocus|新世代的創作平台

(*補充: if 這是一個非常好用的語法,基本上它就是如字面上的意思一樣 "假設",假設條件成立就執行跟在if後面的大括號裡面的內容)

程式碼片段:

  1. string filePath = openFileDialog.FileName;
  2. using (FileStream fs = new FileStream(filePath,FileMode.Open, FileAccess.Read))
  3. {

-------------------------------------------------------------------------------------------------------

第 1 行 當彈跳視窗選完檔案按下開啟後,openFileDialog這個元件它裡面會有一個FileName儲存著你檔案的位置。我們就用一個字串型別(string)的變數(可以自己命名,但身為一個好的工程師會正確命名,所以我們叫這個變數為filePath)儲存這個檔案位置。

第 2 行 是固定的讀檔案格式,我們把filePath存的檔案位置丟到這個既定的讀檔案格式裡,電腦就會自動幫我們到那個位置讀取檔案,把檔案開啟後程式就會在第 3 行這個大括弧裡面做讀取檔案內容的操作。

(*補充: using 這個程式碼的功能,就是使用完後自動釋放資源。

例如:有時候我們有共用的Excel打開以後,Excel會跳出警告說有其他人開著,而這個using就是為了防止程式碼開啟檔案後沒有釋放掉資源,會造成其他人開啟或修改檔案時發生錯誤。

這只是一個防止資源被占用的用法,並不影響程式開發,以後看久了就會熟悉了,不必過於糾結。)

程式碼片段:

  1. XSSFWorkbook workbook = new XSSFWorkbook(fs);
  2. ISheet sheet = workbook.GetSheetAt(0);

-------------------------------------------------------------------------------------------------------

第 1 行 把讀到的檔案流 FileStream fs 放進來就能開始讀取裡面的內容。

第 2 行 我們先來讀取這個Excel的第一個工作表。如下圖紅框處這個就是Excel的工作表(Sheet)。workbook.GetSheetAt(0) 就如字面上的意思取得Excel的工作表(Sheet),0 代表取第一個工作表(Sheet)。


vocus|新世代的創作平台

*補充:

如果我們有多個工作表,就可以用以下方法取得對應的其他工作表。

ISheet sheet1 = workbook.GetSheetAt(1);

ISheet sheet2 = workbook.GetSheetAt(2);

程式碼片段:

  1. for (int rowIndex = 0; rowIndex <= sheet.LastRowNum; rowIndex++)
  2. {

-------------------------------------------------------------------------------------------------------

第 1 行 這時我們要取得整個Sheet裡面的資料,所以我們要一列一列(Row)的讓程式去抓裡面的資料。這時候就要使用for迴圈,for迴圈有固定的格式。

在小括號內的第一個分號(;)前面的這段 int rowIndex = 0 就是要放你想要從數字幾開始,這裡我們希望從數字 0 開始,於是我們就自己命名一個 rowIndex 整數(int)型態的容器放0這個數字。

第二個分號(;)前面就是看你想讓這個迴圈重複跑多少次,我們要跑完整個Excel的資料,所以我們用前面取得的工作表(sheet)取得它的最後一行資料 LastRowNum,rowIndex <= sheet.LastRowNum 這裡程式就會開始判斷,因此 0 <= 9 條件成立,就會執行for迴圈大括弧裡面的程式。

第三個分號(;)前面就是執行完迴圈裡面的程式後,把rowIndex++ 這個就是+1的意思,所以rowIndex 會變成 1 ,並且繼續執行for迴圈的rowIndex <= sheet.LastRowNum判斷,直到rowIndex<= sheet.LastRowNum不成立就會停止執行這個迴圈。

*補充:(因為怕前面講會太複雜所以放到補充,看不懂沒關係以後就會慢慢懂)

(sheet.LastRowNum這個取出來的數字是9,因為套件設計者設計LastRowNum取得最後一個資料的位置,程式的起始位置是0開始算,所以10行資料的最後一筆位置就是9)

程式碼片段:

  1. IRow row = sheet.GetRow(rowIndex);
  2. if (row != null)
  3. {

-------------------------------------------------------------------------------------------------------

第 1 行 我們用工作表 sheet.GetRow(rowIndex) 照字面意思GetRow就是取得工作表的列(Row),並且使用我們剛剛for 迴圈裡面定義的 rowIndex 整數(int)型態容器指定要取得第幾列(Row),我們一開始指定 rowIndex = 0 所以就是從第一列開始取資料,會取得如下圖的紅框處資料表頭的部分。
之後隨著迴圈跑,rowIndex會改變。
rowIndex = 1、rowIndex = 2、rowIndex = 3 … rowIndex = 9。
就會去一列一列取得表身的資料。

第 2 - 3 行 則是判斷這列是不是空的,如不等於空(null) 則執行大括號裡面的程式。

vocus|新世代的創作平台

程式碼片段:

  1. for (int colIndex = 0; colIndex < row.LastCellNum; colIndex++)
  2. {

-------------------------------------------------------------------------------------------------------

第 1-2 行 我們在前面取得列以後,要對每一個格子(cell)取出裡面的值,於是我們一樣使用for迴圈,指定一個名稱為 colIndex 的整數(int)容器並從 0 開始,然後我們要取到列裡面的最後一個格子的資料,所以就使用 row.LastCellNum,0 < 6 ,條件成立就執行迴圈裡面的程式碼,執行後colIndex++,直到colIndex =6 ,6 < 6 不成立才會跳出迴圈。

*補充:

(row.LastCellNum這個取出來的數字是6,因為套件設計者設計LastCellNum取得總共的格子數量不是最後一格子的位置,所以依據我們範例的Excel資料總共有6個格子,因此會得到6不是5,跟LastRowNum不太一樣。)

程式碼片段:

  1. ICell cell = row.GetCell(colIndex);
  2. if (cell != null)
  3. {
  4. string cellValue = cell.ToString();
  5. Console.WriteLine($"Row {rowIndex + 1},Column {colIndex + 1}: {cellValue}");
  6. }

-------------------------------------------------------------------------------------------------------

第 1 行 我們用列(Row) row.GetCell(colIndex) 照字面意思GetCell就是取得列裡面的格子(cell)。

第 2 行 一樣判斷格子是不是空的,不等於空(null) 則執行大括號裡面的程式。

第 4 行 cell.ToString()是把取得的cell轉成字串的格式,然後放在一個名字為cellValue的字串容器。

第 5 行 Console.WriteLine()則是.net內建提供的功能,可以用來顯示容器裡面的值,讓資料視覺化方便檢查結果。原本範例程式碼想把顯示的結果用得漂亮一點,因此你會看到$"....." 這個一串複雜的文字,我建議直接改成Console.WriteLine(cellValue); 只顯示格子裡面的值不顯示其他多餘的東西,後續對程式熟悉了再來了解範例的用法。


這些程式碼執行後會根據sheet裡面有幾列(Row)然後一列一列的執行迴圈,再對每一列的裡面有幾個格子(cell)一個一個的執行迴圈。最後再輸出的地方就會開始一個一個的顯示cell裡面的值。

依序顯示 : 生產日期、出貨日期、貨品名稱、出貨數量、貨品價格、生產人員、20250901…一直到最後一個John顯示後,程式才會停止。

vocus|新世代的創作平台

結論

到這裡我們已經對於讀取Excel的基本應用有了了解,離軟體工程師又更近了一大步!下一章我們就可以進階針對需求微調程式來符合使用者讀Excel的真正需求。








留言
avatar-img
ITT Fun
0會員
15內容數
主要內容會教大家如何快速有效轉職到中大型公司內部系統的軟體工程師。 程式真的沒有很困難,不論之前覺得學習太枯燥乏味或是其他因素而放棄或從未開始,這邊會帶給大家不同的體驗。 我們會用實際案例來當作教學主軸,用我親身的經歷讓大家快樂學習程式,過程中可以累積很多程式作品還會提升很多成就感,同時還能增加成功轉職的機會!
ITT Fun的其他內容
2026/03/19
除了寫入資料,C# 讀取 Excel 也是常見的開發需求。本篇將透過 NPOI 套件,帶你完成 Excel 資料讀取與處理的基本流程,適合剛接觸 Excel 自動化的新手,快速掌握資料匯入與解析技巧。
Thumbnail
2026/03/19
除了寫入資料,C# 讀取 Excel 也是常見的開發需求。本篇將透過 NPOI 套件,帶你完成 Excel 資料讀取與處理的基本流程,適合剛接觸 Excel 自動化的新手,快速掌握資料匯入與解析技巧。
Thumbnail
2026/03/17
如果你已經會用 C# 操作 Excel,下一步就是學習如何進行格式設定。本篇 C# NPOI 教學,將介紹如何使用 NPOI 套件來調整 Excel 樣式,例如字體、顏色、欄寬與儲存格格式,讓你的報表不只是能用,還能更專業。
Thumbnail
2026/03/17
如果你已經會用 C# 操作 Excel,下一步就是學習如何進行格式設定。本篇 C# NPOI 教學,將介紹如何使用 NPOI 套件來調整 Excel 樣式,例如字體、顏色、欄寬與儲存格格式,讓你的報表不只是能用,還能更專業。
Thumbnail
2026/03/12
在實務工作中,使用 C# 操作 Excel 來自動產生報表是非常常見的需求。本篇 C# 操作 Excel 教學,將帶你從零開始實作 Excel 自動化,包含資料寫入、報表生成等常見功能,讓你可以用 .NET 快速提升工作效率。
Thumbnail
2026/03/12
在實務工作中,使用 C# 操作 Excel 來自動產生報表是非常常見的需求。本篇 C# 操作 Excel 教學,將帶你從零開始實作 Excel 自動化,包含資料寫入、報表生成等常見功能,讓你可以用 .NET 快速提升工作效率。
Thumbnail
看更多
你可能也想看
Thumbnail
曾經因為工作上的衝突,體驗到被甲方的語言攻擊與情緒勒索的不適,引發我思索如何改變現況。朋友的建議點燃了我嘗試轉職的火苗:成為具有專業技能且不受他人左右的自己。由於在資訊服務產業從事PM工作,自然聯想到專注於程式碼的工程師,他們在工作上相對具有專業技能,更不受甲方干擾。
Thumbnail
曾經因為工作上的衝突,體驗到被甲方的語言攻擊與情緒勒索的不適,引發我思索如何改變現況。朋友的建議點燃了我嘗試轉職的火苗:成為具有專業技能且不受他人左右的自己。由於在資訊服務產業從事PM工作,自然聯想到專注於程式碼的工程師,他們在工作上相對具有專業技能,更不受甲方干擾。
Thumbnail
若說易卜生的《玩偶之家》為 19 世紀的女性,開啟了一扇離家的窄門,那麼《海妲.蓋柏樂》展現的便是門後的窒息世界。本篇文章由劇場演員 Amily 執筆,同為熟稔文本的演員,亦是深刻體察制度縫隙的當代女性,此文所看見的不僅僅是崩壞前夕的最後發聲,更是女人被迫置於冷酷的制度之下,步步陷入無以言說的困境。
Thumbnail
若說易卜生的《玩偶之家》為 19 世紀的女性,開啟了一扇離家的窄門,那麼《海妲.蓋柏樂》展現的便是門後的窒息世界。本篇文章由劇場演員 Amily 執筆,同為熟稔文本的演員,亦是深刻體察制度縫隙的當代女性,此文所看見的不僅僅是崩壞前夕的最後發聲,更是女人被迫置於冷酷的制度之下,步步陷入無以言說的困境。
Thumbnail
要轉換到另一個領域,需要投入相當的時間,一旦準備的時間拉得越長,轉職要面臨的壓力也就可能隨之增加。 這次就將 Podcast 先前邀請到多位軟體工程師分享的轉職經驗彙整成整理包,讓大家可以更快找到自己需要的轉職資訊,把更多時間留在提升專業技能上!
Thumbnail
要轉換到另一個領域,需要投入相當的時間,一旦準備的時間拉得越長,轉職要面臨的壓力也就可能隨之增加。 這次就將 Podcast 先前邀請到多位軟體工程師分享的轉職經驗彙整成整理包,讓大家可以更快找到自己需要的轉職資訊,把更多時間留在提升專業技能上!
Thumbnail
本文深度解析賽勒布倫尼科夫的舞臺作品《傳奇:帕拉贊諾夫的十段殘篇》,如何以十段殘篇,結合帕拉贊諾夫的電影美學、象徵意象與當代政治流亡抗爭,探討藝術在儀式消失的現代社會如何承接意義,並展現不羈的自由靈魂。
Thumbnail
本文深度解析賽勒布倫尼科夫的舞臺作品《傳奇:帕拉贊諾夫的十段殘篇》,如何以十段殘篇,結合帕拉贊諾夫的電影美學、象徵意象與當代政治流亡抗爭,探討藝術在儀式消失的現代社會如何承接意義,並展現不羈的自由靈魂。
Thumbnail
長期以來,西方美學以《維特魯威人》式的幾何比例定義「完美身體」,這種視覺標準無形中成為殖民擴張與種族分類的暴力工具。本文透過分析奈及利亞編舞家庫德斯.奧尼奎庫的舞作《轉轉生》,探討當代非洲舞蹈如何跳脫「標本式」的文化觀看。
Thumbnail
長期以來,西方美學以《維特魯威人》式的幾何比例定義「完美身體」,這種視覺標準無形中成為殖民擴張與種族分類的暴力工具。本文透過分析奈及利亞編舞家庫德斯.奧尼奎庫的舞作《轉轉生》,探討當代非洲舞蹈如何跳脫「標本式」的文化觀看。
Thumbnail
前言:重新定義「被取代」的真正意涵 當我們談論 AI 將在 2030 年「取代」軟體工程師時,這個論述往往過於簡化了一個複雜的轉型過程。真正的問題不是 AI 是否會取代程式設計師,而是哪些工程師會被淘汰,哪些會成為下一代的技術領導者。 歷史告訴我們,每一次技術革命都會重新定義職業的本質,而非簡單
Thumbnail
前言:重新定義「被取代」的真正意涵 當我們談論 AI 將在 2030 年「取代」軟體工程師時,這個論述往往過於簡化了一個複雜的轉型過程。真正的問題不是 AI 是否會取代程式設計師,而是哪些工程師會被淘汰,哪些會成為下一代的技術領導者。 歷史告訴我們,每一次技術革命都會重新定義職業的本質,而非簡單
Thumbnail
網路上提到自學程式的文章,都會說自學程式非常地辛苦,而且要很自律,決心夠強;而當自己踏上這條路後,才發現何止是辛苦,根本是佈滿荊棘,常常寸步難行,且被刺地遍體鱗傷(喂~是不是有點太浮誇了),但在每個寫出程式豁然開朗的當下,卻又成就感滿滿,所以想藉著寫部落格紀錄一下自己的學習過程!
Thumbnail
網路上提到自學程式的文章,都會說自學程式非常地辛苦,而且要很自律,決心夠強;而當自己踏上這條路後,才發現何止是辛苦,根本是佈滿荊棘,常常寸步難行,且被刺地遍體鱗傷(喂~是不是有點太浮誇了),但在每個寫出程式豁然開朗的當下,卻又成就感滿滿,所以想藉著寫部落格紀錄一下自己的學習過程!
Thumbnail
全新版本的《三便士歌劇》如何不落入「復刻經典」的巢臼,反而利用華麗的秀場視覺,引導觀眾在晚期資本主義的消費愉悅之中,而能驚覺「批判」本身亦可能被收編——而當絞繩升起,這場關於如何生存的黑色遊戲,又將帶領新時代的我們走向何種後現代的自我解構?
Thumbnail
全新版本的《三便士歌劇》如何不落入「復刻經典」的巢臼,反而利用華麗的秀場視覺,引導觀眾在晚期資本主義的消費愉悅之中,而能驚覺「批判」本身亦可能被收編——而當絞繩升起,這場關於如何生存的黑色遊戲,又將帶領新時代的我們走向何種後現代的自我解構?
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News