C# NPOI 教學|Excel 資料設定|C# Excel 系列

更新 發佈閱讀 26 分鐘

如果你已經會用 C# 操作 Excel,下一步就是學習如何進行格式設定。本篇 C# NPOI 教學,將介紹如何使用 NPOI 套件來調整 Excel 樣式,例如字體、顏色、欄寬與儲存格格式,讓你的報表不只是能用,還能更專業。

C# 操作 Excel 教學|自動產生報表完整實作(.NET)(NPOI)|C# Excel 系列 我們收到生產部同事們自動產生Excel檔案的需求

vocus|新世代的創作平台

ChatGpt的範例檔產出的格式如下

vocus|新世代的創作平台

現在我們就開始從範例檔深入了解程式的運作。

開始程式進階調整修改

1 . 開啟前一篇文章建立的程式

找到button1的進入點

 private void button1_Click(object sender, EventArgs e)

如專案開啟時沒有自動幫你開啟頁面,只需要再方案總管對著Form1.cs右鍵,選擇檢視程式碼,就會跳出Form1.cs的程式碼頁面

vocus|新世代的創作平台

2 . 程式碼研究

private void button1_Click(object sender, EventArgs e)
{

IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("Sheet1");


IRow headerRow = sheet.CreateRow(0);
headerRow.CreateCell(0).SetCellValue("ID");
headerRow.CreateCell(1).SetCellValue("Name");
headerRow.CreateCell(2).SetCellValue("Age");


IRow row1 = sheet.CreateRow(1);
row1.CreateCell(0).SetCellValue(1);
row1.CreateCell(1).SetCellValue("John Doe");
row1.CreateCell(2).SetCellValue(30);

IRow row2 = sheet.CreateRow(2);
row2.CreateCell(0).SetCellValue(2);
row2.CreateCell(1).SetCellValue("Jane Smith");
row2.CreateCell(2).SetCellValue(25);


using (FileStream fs = new FileStream("exportedData.xlsx", FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}

MessageBox.Show("Excel 文件已成功生成!");
}

程式碼 第 4 行:

 IWorkbook workbook = new XSSFWorkbook();

IWorkbook 先跟程式宣告我們要一個Excel的工作簿,名稱就叫做workbook,屬於 XSSFWorkbook()這個型別。
IWorkbook XSSFWorkbook()這兩個沒什麼特別意思,就只是我們用NPOI要建Excel時,第一步就是要建立一個工作簿。NPOI套件規定建立工作簿要下

IWorkbook workbook = new XSSFWorkbook();這個指令,就會出現一個工作簿。

程式碼 第 5 行:

ISheet sheet = workbook.CreateSheet("Sheet1");

有了工作簿以後我們要在上面建立一個Sheet工作表,這整段程式碼也只是固定的格式,唯一需要注意的是"Sheet1",這個我們可以自己取想要的名稱,當這行指令下完就會產生Excel的工作表,如下圖紅框處,就會出現一個Sheet1的工作表,如果命名為Sheet2到時候紅框處就會顯示Sheet2。到這一步你就會發現程式其實是很直覺並且視覺化的。

vocus|新世代的創作平台

程式碼 第 8 行:

IRow headerRow = sheet.CreateRow(0);

有了工作表後,我們要在工作表裡面開始把每列(Row)的資料建立起來,透過第5行建立出來的sheet這個工作表,我們用sheet.CreateRow(0)建立出第一列並且命名為headerRow。

程式碼 第 9-11行:

headerRow.CreateCell(0).SetCellValue("ID");
headerRow.CreateCell(1).SetCellValue("Name");
headerRow.CreateCell(2).SetCellValue("Age");

建立出第一列headerRow後,我們要對列裡面的每一欄(Cell)設定值,這三行程式碼就是分別對第一列的A欄、B欄、C欄設定,先透過CreateCell建立Cell,在用SetCellValue設定裡面的值,這三行設定好後我們就有表頭了,分別是ID、Name、Age。

程式碼 第 14-22行:

IRow row1 = sheet.CreateRow(1);
row1.CreateCell(0).SetCellValue(1);
row1.CreateCell(1).SetCellValue("John Doe");
row1.CreateCell(2).SetCellValue(30);

IRow row2 = sheet.CreateRow(2);
row2.CreateCell(0).SetCellValue(2);
row2.CreateCell(1).SetCellValue("Jane Smith");
row2.CreateCell(2).SetCellValue(25);

這裡就很簡單,依據程式碼 第 8-11 行 舉一反三就會知道這些程式碼是在建立第二、三列,然後設定裡面的資料。

程式碼 第 25-29行:

using (FileStream fs = new FileStream("exportedData.xlsx", FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}

這個也是固定的用法,把我們的工作簿workbook的內容輸出成xlsx檔案,檔名為exportedData。

程式碼 第 30行:

MessageBox.Show("Excel 文件已成功生成!");

這個只是跳一個訊息告訴我們檔案產生好了。

3 . 依據需求調整範例程式碼

在研究完範例程式碼後你就會發現,原來程式很多都是既定的格式只要直接複製貼上。真正需要我們自己去調整的其實只有要產出來的內容,或者是一些計算的邏輯等等。目前我們只要調整範例程式碼的 8 - 22行,調整成符合使用者想要的Excel內容就完成開發工作了。

表頭調整:

(範例版)

IRow headerRow = sheet.CreateRow(0);
headerRow.CreateCell(0).SetCellValue("ID");
headerRow.CreateCell(1).SetCellValue("Name");
headerRow.CreateCell(2).SetCellValue("Age");

(新版)

IRow headerRow = sheet.CreateRow(0);
headerRow.CreateCell(0).SetCellValue("生產日期");
headerRow.CreateCell(1).SetCellValue("出貨日期");
headerRow.CreateCell(2).SetCellValue("貨品名稱");
headerRow.CreateCell(3).SetCellValue("出貨數量");
headerRow.CreateCell(4).SetCellValue("貨品價格");
headerRow.CreateCell(5).SetCellValue("生產人員");

我們前面三個Cell只需要把SetCellValue裡面的名稱改成正確的即可。因為範例程式碼只有三欄,使用者需要的表頭是六個,所以我們自己再增加三個Cell 3、4、5,SetCellValue填入正確的表頭名稱。

表身調整:

(範例版)

IRow row1 = sheet.CreateRow(1);
row1.CreateCell(0).SetCellValue(1);
row1.CreateCell(1).SetCellValue("John Doe");
row1.CreateCell(2).SetCellValue(30);

IRow row2 = sheet.CreateRow(2);
row2.CreateCell(0).SetCellValue(2);
row2.CreateCell(1).SetCellValue("Jane Smith");
row2.CreateCell(2).SetCellValue(25);

(新版)

IRow row1 = sheet.CreateRow(1);
row1.CreateCell(0).SetCellValue("20250901");
row1.CreateCell(1).SetCellValue("20250901");
row1.CreateCell(2).SetCellValue("測試貨1");
row1.CreateCell(3).SetCellValue(1);
row1.CreateCell(4).SetCellValue(1);
row1.CreateCell(5).SetCellValue("John");

IRow row2 = sheet.CreateRow(2);
row2.CreateCell(0).SetCellValue("20250902");
row2.CreateCell(1).SetCellValue("20250902");
row2.CreateCell(2).SetCellValue("測試貨2");
row2.CreateCell(3).SetCellValue(2);
row2.CreateCell(4).SetCellValue(2);
row2.CreateCell(5).SetCellValue("John");

IRow row3 = sheet.CreateRow(3);
row3.CreateCell(0).SetCellValue("20250903");
row3.CreateCell(1).SetCellValue("20250903");
row3.CreateCell(2).SetCellValue("測試貨3");
row3.CreateCell(3).SetCellValue(3);
row3.CreateCell(4).SetCellValue(3);
row3.CreateCell(5).SetCellValue("John");

IRow row4 = sheet.CreateRow(4);
row4.CreateCell(0).SetCellValue("20250904");
row4.CreateCell(1).SetCellValue("20250904");
row4.CreateCell(2).SetCellValue("測試貨4");
row4.CreateCell(3).SetCellValue(4);
row4.CreateCell(4).SetCellValue(4);
row4.CreateCell(5).SetCellValue("John");

IRow row5 = sheet.CreateRow(5);
row5.CreateCell(0).SetCellValue("20250905");
row5.CreateCell(1).SetCellValue("20250905");
row5.CreateCell(2).SetCellValue("測試貨5");
row5.CreateCell(3).SetCellValue(5);
row5.CreateCell(4).SetCellValue(5);
row5.CreateCell(5).SetCellValue("John");

IRow row6 = sheet.CreateRow(6);
row6.CreateCell(0).SetCellValue("20250906");
row6.CreateCell(1).SetCellValue("20250906");
row6.CreateCell(2).SetCellValue("測試貨6");
row6.CreateCell(3).SetCellValue(6);
row6.CreateCell(4).SetCellValue(6);
row6.CreateCell(5).SetCellValue("John");

IRow row7 = sheet.CreateRow(7);
row7.CreateCell(0).SetCellValue("20250907");
row7.CreateCell(1).SetCellValue("20250907");
row7.CreateCell(2).SetCellValue("測試貨7");
row7.CreateCell(3).SetCellValue(7);
row7.CreateCell(4).SetCellValue(7);
row7.CreateCell(5).SetCellValue("John");

IRow row8 = sheet.CreateRow(8);
row8.CreateCell(0).SetCellValue("20250908");
row8.CreateCell(1).SetCellValue("20250908");
row8.CreateCell(2).SetCellValue("測試貨8");
row8.CreateCell(3).SetCellValue(8);
row8.CreateCell(4).SetCellValue(8);
row8.CreateCell(5).SetCellValue("John");

IRow row9 = sheet.CreateRow(9);
row9.CreateCell(0).SetCellValue("20250909");
row9.CreateCell(1).SetCellValue("20250909");
row9.CreateCell(2).SetCellValue("測試貨9");
row9.CreateCell(3).SetCellValue(9);
row9.CreateCell(4).SetCellValue(9);
row9.CreateCell(5).SetCellValue("John");

範例程式碼只有兩列的資料,我們先把這兩列前三欄改成正確的資料,因為使用者需要的是每一列有六欄資料,所以我們再把後面三欄補正確資料上去,做法也相當簡單,多增加Cell 3、4 、5然後一樣使用SetCellValue設定裡面的資料即可。

最後,再把剩下的七列資料也寫上去,因為格式都是固定的所以我們可以快速地把格式複製下來,然後貼上七次,再去改裡面的資料,整個功能就大功告成了!

4 . 開發完成,測試專案

完成上述所有步驟後,現在的private void button1_Click(object sender, EventArgs e)大括號裡面的程式碼會如下:

private void button1_Click(object sender, EventArgs e)
{

IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("Sheet1");


IRow headerRow = sheet.CreateRow(0);
headerRow.CreateCell(0).SetCellValue("生產日期");
headerRow.CreateCell(1).SetCellValue("出貨日期");
headerRow.CreateCell(2).SetCellValue("貨品名稱");
headerRow.CreateCell(3).SetCellValue("出貨數量");
headerRow.CreateCell(4).SetCellValue("貨品價格");
headerRow.CreateCell(5).SetCellValue("生產人員");


IRow row1 = sheet.CreateRow(1);
row1.CreateCell(0).SetCellValue("20250901");
row1.CreateCell(1).SetCellValue("20250901");
row1.CreateCell(2).SetCellValue("測試貨1");
row1.CreateCell(3).SetCellValue(1);
row1.CreateCell(4).SetCellValue(1);
row1.CreateCell(5).SetCellValue("John");

IRow row2 = sheet.CreateRow(2);
row2.CreateCell(0).SetCellValue("20250902");
row2.CreateCell(1).SetCellValue("20250902");
row2.CreateCell(2).SetCellValue("測試貨2");
row2.CreateCell(3).SetCellValue(2);
row2.CreateCell(4).SetCellValue(2);
row2.CreateCell(5).SetCellValue("John");

IRow row3 = sheet.CreateRow(3);
row3.CreateCell(0).SetCellValue("20250903");
row3.CreateCell(1).SetCellValue("20250903");
row3.CreateCell(2).SetCellValue("測試貨3");
row3.CreateCell(3).SetCellValue(3);
row3.CreateCell(4).SetCellValue(3);
row3.CreateCell(5).SetCellValue("John");

IRow row4 = sheet.CreateRow(4);
row4.CreateCell(0).SetCellValue("20250904");
row4.CreateCell(1).SetCellValue("20250904");
row4.CreateCell(2).SetCellValue("測試貨4");
row4.CreateCell(3).SetCellValue(4);
row4.CreateCell(4).SetCellValue(4);
row4.CreateCell(5).SetCellValue("John");

IRow row5 = sheet.CreateRow(5);
row5.CreateCell(0).SetCellValue("20250905");
row5.CreateCell(1).SetCellValue("20250905");
row5.CreateCell(2).SetCellValue("測試貨5");
row5.CreateCell(3).SetCellValue(5);
row5.CreateCell(4).SetCellValue(5);
row5.CreateCell(5).SetCellValue("John");

IRow row6 = sheet.CreateRow(6);
row6.CreateCell(0).SetCellValue("20250906");
row6.CreateCell(1).SetCellValue("20250906");
row6.CreateCell(2).SetCellValue("測試貨6");
row6.CreateCell(3).SetCellValue(6);
row6.CreateCell(4).SetCellValue(6);
row6.CreateCell(5).SetCellValue("John");

IRow row7 = sheet.CreateRow(7);
row7.CreateCell(0).SetCellValue("20250907");
row7.CreateCell(1).SetCellValue("20250907");
row7.CreateCell(2).SetCellValue("測試貨7");
row7.CreateCell(3).SetCellValue(7);
row7.CreateCell(4).SetCellValue(7);
row7.CreateCell(5).SetCellValue("John");

IRow row8 = sheet.CreateRow(8);
row8.CreateCell(0).SetCellValue("20250908");
row8.CreateCell(1).SetCellValue("20250908");
row8.CreateCell(2).SetCellValue("測試貨8");
row8.CreateCell(3).SetCellValue(8);
row8.CreateCell(4).SetCellValue(8);
row8.CreateCell(5).SetCellValue("John");

IRow row9 = sheet.CreateRow(9);
row9.CreateCell(0).SetCellValue("20250909");
row9.CreateCell(1).SetCellValue("20250909");
row9.CreateCell(2).SetCellValue("測試貨9");
row9.CreateCell(3).SetCellValue(9);
row9.CreateCell(4).SetCellValue(9);
row9.CreateCell(5).SetCellValue("John");


using (FileStream fs = new FileStream("exportedData.xlsx", FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}

MessageBox.Show("Excel 文件已成功生成!");
}

結論

接下來只要把程式跑起來,按下button1看一下產出的Excel格式有沒有正確,這樣我們就成功完成Excel自動產生的功能了!

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