使用C#實(shí)現(xiàn)數(shù)據(jù)自動(dòng)化寫(xiě)入Excel文件
在現(xiàn)代數(shù)據(jù)驅(qū)動(dòng)的世界中,Excel文件作為一種通用的數(shù)據(jù)存儲(chǔ)和交換格式,在企業(yè)運(yùn)營(yíng)和日常工作中扮演著舉足輕重的作用。無(wú)論是報(bào)表生成、數(shù)據(jù)分析還是系統(tǒng)集成,將應(yīng)用程序中的數(shù)據(jù)準(zhǔn)確、高效地寫(xiě)入Excel文件都是一個(gè)普遍且關(guān)鍵的需求。然而,手動(dòng)操作Excel不僅效率低下,還極易引入人為錯(cuò)誤,特別是當(dāng)數(shù)據(jù)量龐大或需要頻繁更新時(shí)。
本文將深入探討如何利用C#語(yǔ)言,結(jié)合一個(gè)功能強(qiáng)大且易于使用的庫(kù),實(shí)現(xiàn)數(shù)據(jù)的程序化寫(xiě)入Excel文件。我們將從環(huán)境搭建開(kāi)始,逐步講解如何創(chuàng)建新的Excel文件、寫(xiě)入各種類(lèi)型的數(shù)據(jù)、格式化單元格,以及處理現(xiàn)有文件。通過(guò)本文的學(xué)習(xí),您將掌握C#操作Excel的核心技能,從而極大地提升工作效率并確保數(shù)據(jù)的一致性。
為什么選擇程序化寫(xiě)入Excel
C#作為.NET平臺(tái)的核心語(yǔ)言,在文件I/O和數(shù)據(jù)處理方面擁有強(qiáng)大的能力。將數(shù)據(jù)程序化寫(xiě)入Excel,相比手動(dòng)操作,具有顯著的優(yōu)勢(shì):
- 自動(dòng)化與效率提升: 告別繁瑣的手動(dòng)復(fù)制粘貼,通過(guò)代碼實(shí)現(xiàn)數(shù)據(jù)自動(dòng)導(dǎo)出,尤其適用于周期性報(bào)表生成或大量數(shù)據(jù)處理場(chǎng)景。
- 數(shù)據(jù)一致性與準(zhǔn)確性: 避免人工輸入錯(cuò)誤,確保數(shù)據(jù)從源系統(tǒng)到Excel的轉(zhuǎn)換過(guò)程保持高度一致性和準(zhǔn)確性。
- 批量處理能力: 輕松處理成千上萬(wàn)行數(shù)據(jù),幾秒鐘內(nèi)完成手動(dòng)操作可能需要數(shù)小時(shí)甚至數(shù)天的工作。
- 集成與擴(kuò)展性: 可以將Excel導(dǎo)出功能無(wú)縫集成到現(xiàn)有應(yīng)用程序中,根據(jù)業(yè)務(wù)需求靈活擴(kuò)展功能,例如生成圖表、數(shù)據(jù)透 視表等。
盡管C#提供了基礎(chǔ)的文件操作API,但直接操作Excel的二進(jìn)制格式非常復(fù)雜。因此,引入一個(gè)專(zhuān)業(yè)的第三方庫(kù)是實(shí)現(xiàn)高效Excel操作的最佳實(shí)踐。
準(zhǔn)備工作與環(huán)境搭建
在開(kāi)始編寫(xiě)代碼之前,我們需要確保開(kāi)發(fā)環(huán)境中已安裝必要的庫(kù)。本文將使用一個(gè)高效的庫(kù)來(lái)簡(jiǎn)化Excel操作。
創(chuàng)建C#項(xiàng)目: 打開(kāi)Visual Studio,創(chuàng)建一個(gè)新的C#控制臺(tái)應(yīng)用程序(或您選擇的任何C#項(xiàng)目類(lèi)型)。
安裝NuGet包: 在Visual Studio中,右鍵點(diǎn)擊您的項(xiàng)目,選擇“管理NuGet程序包(Manage NuGet Packages...)”。在“瀏覽”選項(xiàng)卡中,搜索并安裝以下包:
Install-Package Spire.XLS
這個(gè)命令會(huì)在您的項(xiàng)目中添加所有必要的引用,使您能夠開(kāi)始使用該庫(kù)提供的功能。
核心操作:將數(shù)據(jù)寫(xiě)入Excel文件
現(xiàn)在,我們已經(jīng)準(zhǔn)備好環(huán)境,可以開(kāi)始編寫(xiě)代碼來(lái)操作Excel文件了。
創(chuàng)建新的Excel文件并寫(xiě)入數(shù)據(jù)
首先,我們將學(xué)習(xí)如何創(chuàng)建一個(gè)全新的Excel工作簿,并向其中寫(xiě)入基本數(shù)據(jù)和設(shè)置單元格格式。
using Spire.Xls;
using System.Drawing; // 用于顏色設(shè)置
public class ExcelWriter
{
public static void CreateNewExcel()
{
// 1. 創(chuàng)建一個(gè)新的Workbook對(duì)象
Workbook workbook = new Workbook();
// 2. 獲取第一個(gè)工作表(默認(rèn)會(huì)有一個(gè)Sheet1)
Worksheet sheet = workbook.Worksheets[0];
sheet.Name = "銷(xiāo)售數(shù)據(jù)"; // 設(shè)置工作表名稱(chēng)
// 3. 向單元格寫(xiě)入文本數(shù)據(jù)
sheet.Range["A1"].Text = "產(chǎn)品名稱(chēng)";
sheet.Range["B1"].Text = "銷(xiāo)售數(shù)量";
sheet.Range["C1"].Text = "單價(jià)";
sheet.Range["D1"].Text = "總金額";
// 4. 向單元格寫(xiě)入數(shù)字?jǐn)?shù)據(jù)
sheet.Range["A2"].Text = "筆記本電腦";
sheet.Range["B2"].NumberValue = 10;
sheet.Range["C2"].NumberValue = 8999.00;
sheet.Range["D2"].Formula = "=B2*C2"; // 寫(xiě)入公式
sheet.Range["A3"].Text = "智能手機(jī)";
sheet.Range["B3"].NumberValue = 25;
sheet.Range["C3"].NumberValue = 4599.50;
sheet.Range["D3"].Formula = "=B3*C3";
// 5. 設(shè)置單元格格式
// 設(shè)置表頭樣式
CellStyle headerStyle = workbook.Styles.Add("headerStyle");
headerStyle.Font.IsBold = true;
headerStyle.KnownColor = ExcelColors.LightGreen1;
headerStyle.HorizontalAlignment = HorizontalAlignType.Center;
headerStyle.VerticalAlignment = VerticalAlignType.Center;
sheet.Range["A1:D1"].Style = headerStyle;
// 設(shè)置金額列的貨幣格式
sheet.Range["C2:D3"].Style.NumberFormat = "¥#,##0.00";
// 自動(dòng)調(diào)整列寬以適應(yīng)內(nèi)容
sheet.AutoFitColumn(1);
sheet.AutoFitColumn(2);
sheet.AutoFitColumn(3);
sheet.AutoFitColumn(4);
// 6. 保存Excel文件
string filePath = "銷(xiāo)售報(bào)表_新.xlsx";
workbook.SaveToFile(filePath, ExcelVersion.Version2016);
Console.WriteLine($"Excel文件已保存到: {Path.GetFullPath(filePath)}");
// 7. 釋放資源
workbook.Dispose();
}
}
代碼解讀:
- 我們首先創(chuàng)建
Workbook對(duì)象,它代表一個(gè)Excel文件。 Worksheet對(duì)象代表工作簿中的一個(gè)工作表。Range["A1"]通過(guò)索引器訪(fǎng)問(wèn)特定單元格,可以設(shè)置其Text、NumberValue或Formula。CellStyle對(duì)象允許我們自定義字體、顏色、對(duì)齊方式等。AutoFitColumn方法能自動(dòng)調(diào)整列寬,使內(nèi)容完全顯示。SaveToFile方法用于保存文件,并指定Excel版本。
從集合或數(shù)據(jù)源寫(xiě)入數(shù)據(jù)
在實(shí)際應(yīng)用中,數(shù)據(jù)往往存儲(chǔ)在List<T>、DataTable或數(shù)據(jù)庫(kù)中。該庫(kù)提供了便捷的方法來(lái)批量導(dǎo)入這些數(shù)據(jù)。
using Spire.Xls;
using System.Data;
using System.Collections.Generic;
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
}
public class ExcelWriter
{
public static void WriteDataFromCollection()
{
Workbook workbook = new Workbook();
Worksheet sheet = workbook.Worksheets[0];
sheet.Name = "產(chǎn)品列表";
// 準(zhǔn)備數(shù)據(jù)
List<Product> products = new List<Product>
{
new Product { Id = 1, Name = "鍵盤(pán)", Price = 199.00m, Stock = 50 },
new Product { Id = 2, Name = "鼠標(biāo)", Price = 99.50m, Stock = 120 },
new Product { Id = 3, Name = "顯示器", Price = 1299.00m, Stock = 30 }
};
// 將List<T>數(shù)據(jù)寫(xiě)入Excel,并包含表頭
// 第一個(gè)參數(shù)是數(shù)據(jù)源,第二個(gè)參數(shù)表示是否包含列頭,
// 第三個(gè)和第四個(gè)參數(shù)表示從Excel的第幾行第幾列開(kāi)始寫(xiě)入
sheet.InsertCollection(products, true, 1, 1);
// 如果是DataTable,用法類(lèi)似
DataTable dataTable = new DataTable("用戶(hù)信息");
dataTable.Columns.Add("UserID", typeof(int));
dataTable.Columns.Add("UserName", typeof(string));
dataTable.Columns.Add("Email", typeof(string));
dataTable.Rows.Add(101, "張三", "zhangsan@example.com");
dataTable.Rows.Add(102, "李四", "lisi@example.com");
// 將DataTable數(shù)據(jù)寫(xiě)入Excel,從A5單元格開(kāi)始
sheet.InsertDataTable(dataTable, true, 5, 1);
// 自動(dòng)調(diào)整所有列寬
sheet.AutoFitColumns();
string filePath = "產(chǎn)品與用戶(hù)數(shù)據(jù).xlsx";
workbook.SaveToFile(filePath, ExcelVersion.Version2016);
Console.WriteLine($"Excel文件已保存到: {Path.GetFullPath(filePath)}");
workbook.Dispose();
}
}
代碼解讀:
InsertCollection方法可以直接將List<T>類(lèi)型的數(shù)據(jù)導(dǎo)入到工作表中,極大地簡(jiǎn)化了循環(huán)寫(xiě)入單元格的過(guò)程。InsertDataTable方法則用于將DataTable中的數(shù)據(jù)導(dǎo)入Excel。- 這兩個(gè)方法都支持指定是否包含列頭以及寫(xiě)入的起始位置。
處理現(xiàn)有Excel文件并追加/修改數(shù)據(jù)
有時(shí),我們可能需要修改或向一個(gè)已存在的Excel文件追加數(shù)據(jù),而不是創(chuàng)建一個(gè)新文件。
using Spire.Xls;
using System.IO;
public class ExcelWriter
{
public static void UpdateExistingExcel()
{
string existingFilePath = "銷(xiāo)售報(bào)表_新.xlsx"; // 假設(shè)這個(gè)文件已經(jīng)存在
// 檢查文件是否存在
if (!File.Exists(existingFilePath))
{
Console.WriteLine($"文件不存在: {Path.GetFullPath(existingFilePath)},請(qǐng)先運(yùn)行 CreateNewExcel 方法。");
return;
}
// 1. 加載現(xiàn)有的Workbook對(duì)象
Workbook workbook = new Workbook();
workbook.LoadFromFile(existingFilePath);
// 2. 獲取指定的工作表
Worksheet sheet = workbook.Worksheets["銷(xiāo)售數(shù)據(jù)"]; // 根據(jù)名稱(chēng)獲取
// 3. 追加新數(shù)據(jù)行
int lastRow = sheet.LastRow + 1; // 獲取當(dāng)前數(shù)據(jù)的最后一行,然后加1作為新行的起始行
sheet.Range[$"A{lastRow}"].Text = "無(wú)線(xiàn)耳機(jī)";
sheet.Range[$"B{lastRow}"].NumberValue = 50;
sheet.Range[$"C{lastRow}"].NumberValue = 399.00;
sheet.Range[$"D{lastRow}"].Formula = $"=B{lastRow}*C{lastRow}";
sheet.Range[$"C{lastRow}:D{lastRow}"].Style.NumberFormat = "¥#,##0.00"; // 重新應(yīng)用格式
// 4. 修改現(xiàn)有單元格數(shù)據(jù)
sheet.Range["B2"].NumberValue = 12; // 將筆記本電腦的銷(xiāo)售數(shù)量從10修改為12
sheet.CalculateAllValue(); // 重新計(jì)算所有公式
// 5. 添加超鏈接和注釋
sheet.Range["A" + (lastRow + 2)].Text = "訪(fǎng)問(wèn)官網(wǎng)";
HyperLink hyperlink = sheet.HyperLinks.Add(sheet.Range["A" + (lastRow + 2)]);
hyperlink.Type = HyperLinkType.Url;
hyperlink.Address = "https://www.e-iceblue.com/";
sheet.Range["A" + (lastRow + 3)].Text = "重要提示";
sheet.Range["A" + (lastRow + 3)].Comment.Text = "這是關(guān)于新產(chǎn)品的銷(xiāo)售提示!";
// 6. 保存修改
workbook.SaveToFile(existingFilePath, ExcelVersion.Version2016);
Console.WriteLine($"Excel文件已更新: {Path.GetFullPath(existingFilePath)}");
workbook.Dispose();
}
}
代碼解讀:
workbook.LoadFromFile(existingFilePath)用于加載現(xiàn)有文件。sheet.LastRow屬性可以方便地獲取當(dāng)前工作表中數(shù)據(jù)所在的最后一行行號(hào)。- 修改單元格數(shù)據(jù)后,如果存在公式,需要調(diào)用
workbook.CalculateAllValue()來(lái)重新計(jì)算所有公式的結(jié)果。 - HyperLink對(duì)象和Comment對(duì)象可以用來(lái)添加超鏈接和注釋。
保存Excel文件
保存文件是操作的最后一步,您可以看到在上述示例中已經(jīng)多次使用。SaveToFile方法允許您指定文件路徑和Excel版本。
// 保存為XLSX格式(推薦)
workbook.SaveToFile("MyReport.xlsx", ExcelVersion.Version2016);
// 保存為XLS格式(兼容舊版Excel)
// workbook.SaveToFile("MyReport.xls", ExcelVersion.Version97to2003);
進(jìn)階技巧與注意事項(xiàng)
性能優(yōu)化: 對(duì)于寫(xiě)入大量數(shù)據(jù)(例如數(shù)十萬(wàn)行)的場(chǎng)景,避免頻繁地訪(fǎng)問(wèn)單個(gè)單元格。優(yōu)先使用InsertCollection或InsertDataTable進(jìn)行批量寫(xiě)入,或者一次性獲取一個(gè)范圍(sheet.Range["A1:Z10000"])并設(shè)置其值。
錯(cuò)誤處理: 文件操作可能會(huì)遇到各種問(wèn)題,例如文件被占用、路徑不存在等。始終使用try-catch塊來(lái)捕獲和處理潛在的異常,提高程序的健壯性。
try
{
// Excel操作代碼
workbook.SaveToFile(filePath, ExcelVersion.Version2016);
}
catch (Exception ex)
{
Console.WriteLine($"保存Excel文件時(shí)發(fā)生錯(cuò)誤: {ex.Message}");
}
資源釋放: Workbook對(duì)象和Worksheet對(duì)象會(huì)占用內(nèi)存和文件句柄。為了避免內(nèi)存泄漏或文件鎖,務(wù)必在操作完成后調(diào)用Dispose()方法來(lái)釋放資源,或者使用using語(yǔ)句來(lái)確保資源被正確釋放。該庫(kù)的Workbook類(lèi)實(shí)現(xiàn)了IDisposable接口,因此可以使用using。
using (Workbook workbook = new Workbook())
{
// 所有Excel操作
// workbook.SaveToFile(...)
} // 在這里workbook會(huì)自動(dòng)Dispose
總結(jié)
通過(guò)本文的詳細(xì)教程,我們學(xué)習(xí)了如何使用C#結(jié)合一個(gè)高效的第三方庫(kù),將數(shù)據(jù)輕松、準(zhǔn)確地寫(xiě)入Excel文件。從創(chuàng)建新文件、寫(xiě)入各種類(lèi)型的數(shù)據(jù),到格式化單元格、批量導(dǎo)入集合數(shù)據(jù),再到修改現(xiàn)有文件,我們涵蓋了C#開(kāi)發(fā)者在日常工作中可能遇到的核心場(chǎng)景。
程序化寫(xiě)入Excel不僅能夠顯著提升數(shù)據(jù)處理的效率,還能確保數(shù)據(jù)的一致性和準(zhǔn)確性,是現(xiàn)代軟件開(kāi)發(fā)中不可或缺的技能?,F(xiàn)在,您已經(jīng)掌握了這些基礎(chǔ)知識(shí),鼓勵(lì)您根據(jù)自己的項(xiàng)目需求進(jìn)行實(shí)踐和擴(kuò)展,例如生成更復(fù)雜的圖表、處理多工作表數(shù)據(jù)等。通過(guò)自動(dòng)化Excel操作,您的應(yīng)用程序?qū)⒆兊酶訌?qiáng)大和靈活,為用戶(hù)帶來(lái)更好的體驗(yàn)。
到此這篇關(guān)于使用C#實(shí)現(xiàn)數(shù)據(jù)自動(dòng)化寫(xiě)入Excel文件的文章就介紹到這了,更多相關(guān)C#數(shù)據(jù)寫(xiě)入Excel內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#使用QRCode生成海報(bào)圖并嵌入定位帶logo的二維碼
這篇文章主要為大家詳細(xì)介紹了C#如何使用QRCode生成海報(bào)圖并嵌入定位帶logo的二維碼,文中的示例代碼講解詳細(xì),需要的小伙伴可以參考下2024-03-03
C#實(shí)現(xiàn)導(dǎo)出Word圖表通用方法之散點(diǎn)圖
文章介紹了C#實(shí)現(xiàn)數(shù)據(jù)導(dǎo)出生成Word圖表的通用方法,并詳細(xì)描述了如何處理散點(diǎn)圖表的特殊設(shè)置,通過(guò)將業(yè)務(wù)數(shù)據(jù)轉(zhuǎn)化為Json格式并添加查找關(guān)鍵字,可以實(shí)現(xiàn)圖表的正確呈現(xiàn),需要的朋友可以參考下2026-01-01
C#利用Refit實(shí)現(xiàn)JWT自動(dòng)續(xù)期詳解
Refit?是一個(gè)受到Square的Retrofit庫(kù)(Java)啟發(fā)的自動(dòng)類(lèi)型安全REST庫(kù),這篇文章主要為大家介紹了C#如何利用Refit實(shí)現(xiàn)JWT自動(dòng)續(xù)期,感興趣的可以了解下2023-08-08
算法練習(xí)之從String.indexOf的模擬實(shí)現(xiàn)開(kāi)始
這篇文章主要介紹了算法練習(xí)從String.indexOf的模擬實(shí)現(xiàn)開(kāi)始,需要的朋友可以參考下2014-12-12

