跳至页脚内容
使用 IRONXL

使用IronXL在 C# 中将数据集导出到 Excel | 无需 Office

在 C# 中将 DataSet 或 DataTable 导出到 Excel,为您提供了一种可靠的方法,可将内存中的结构化数据转换为 Professional 电子表格文件——且无需依赖目标机器上安装 Microsoft Office。无论您是从 SQL 数据库中提取记录、通过编程构建 DataSet,还是处理现有的 DataGrid,IronXL 都能通过简洁的"代码优先"API 处理整个流程。 本指南通过顶级 C# 语句和 .NET 10,详细介绍了从单表导出到多工作表工作簿,再到实时数据库查询结果等所有主要场景。

只需安装一次 IronXL,编写几行代码,您的数据即可保存为 XLSX 文件,且完全不依赖 Office。 以下章节涵盖安装、核心模式、高级格式化和数据库集成,内容可直接复制粘贴到您的项目中。

如何安装用于 Excel 导出的 IronXL?

在编写任何导出代码之前,请通过 NuGet 包管理器将 IronXL 添加到您的项目中。 在项目根目录下打开终端并运行 .NET CLI 命令,或者在 Visual Studio 中使用包管理器控制台并运行 Install-Package 命令:

dotnet add package IronXL.Excel
# Or in Visual Studio Package Manager Console:
# Install-Package IronXL.Excel
dotnet add package IronXL.Excel
# Or in Visual Studio Package Manager Console:
# Install-Package IronXL.Excel
SHELL

安装完成后,请添加一个顶级 using 语句以导入 IronXL 命名空间:

using IronXL;
using System.Data;
using IronXL;
using System.Data;
Imports IronXL
Imports System.Data
$vbLabelText   $csharpLabel

IronXL 支持 .NET 8、.NET 9 和 .NET 10,以及较早的 .NET Framework 版本(4.6.2 及以上)。 无论是在服务器、桌面还是云端,任何设备均无需安装 Office。 安装该软件包后,您即可完全在托管代码中创建、读取和写入 XLSX、XLS 及 CSV 文件。

有关详细的安装选项,请参阅 IronXL 安装指南;有关版本历史,请参阅 NuGet 包页面

如何将单个 DataTable 导出到 Excel 文件?

最常见的场景是将一个 DataTable 导出到单个工作表中。 IronXL 的 WorkBookWorkSheet 类可以自然地映射到 Excel 对象模型。 您创建一个工作簿,添加一个工作表,然后遍历 DataTable 的列和行。

以下示例创建一个内存中的 Employees 数据表,并将其写入 EmployeeData.xlsx:

using IronXL;
using System.Data;

// Build an in-memory DataTable
DataTable dt = new DataTable("Employees");
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Department", typeof(string));

dt.Rows.Add(1, "John Smith", "Engineering");
dt.Rows.Add(2, "Sarah Jones", "Marketing");
dt.Rows.Add(3, "Mike Wilson", "Sales");

// Create a workbook and a named worksheet
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Employees");

// Write column headers in row 0
for (int col = 0; col < dt.Columns.Count; col++)
{
    worksheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
}

// Write data rows starting at row 1
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        worksheet.SetCellValue(row + 1, col, dt.Rows[row][col].ToString());
    }
}

workbook.SaveAs("EmployeeData.xlsx");
using IronXL;
using System.Data;

// Build an in-memory DataTable
DataTable dt = new DataTable("Employees");
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Department", typeof(string));

dt.Rows.Add(1, "John Smith", "Engineering");
dt.Rows.Add(2, "Sarah Jones", "Marketing");
dt.Rows.Add(3, "Mike Wilson", "Sales");

// Create a workbook and a named worksheet
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Employees");

// Write column headers in row 0
for (int col = 0; col < dt.Columns.Count; col++)
{
    worksheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
}

// Write data rows starting at row 1
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        worksheet.SetCellValue(row + 1, col, dt.Rows[row][col].ToString());
    }
}

workbook.SaveAs("EmployeeData.xlsx");
Imports IronXL
Imports System.Data

' Build an in-memory DataTable
Dim dt As New DataTable("Employees")
dt.Columns.Add("ID", GetType(Integer))
dt.Columns.Add("Name", GetType(String))
dt.Columns.Add("Department", GetType(String))

dt.Rows.Add(1, "John Smith", "Engineering")
dt.Rows.Add(2, "Sarah Jones", "Marketing")
dt.Rows.Add(3, "Mike Wilson", "Sales")

' Create a workbook and a named worksheet
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet As WorkSheet = workbook.CreateWorkSheet("Employees")

' Write column headers in row 0
For col As Integer = 0 To dt.Columns.Count - 1
    worksheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
Next

' Write data rows starting at row 1
For row As Integer = 0 To dt.Rows.Count - 1
    For col As Integer = 0 To dt.Columns.Count - 1
        worksheet.SetCellValue(row + 1, col, dt.Rows(row)(col).ToString())
    Next
Next

workbook.SaveAs("EmployeeData.xlsx")
$vbLabelText   $csharpLabel

输出

如何使用 VB.NET 将数据集导出到 Excel:IronXL 完整指南:图 1 - VB.NET 中将简单 DataTable 导出到 Excel 的输出示例

SetCellValue 接受 int、double、string 和 bool 类型 -- 因此您可以获得原生的 Excel 单元格类型,而无需额外的类型转换。 循环模式适用于任何大小的表,因为 IronXL 直接写入内存,并且仅在调用 SaveAs 时才刷新到磁盘,即使对于数千行,也能保持高效的处理。

若需更全面地了解读写技术,IronXL C# 教程除本导出模式外,还涵盖了完整的文件操作内容。

如何将 DataSet 导出到多个 Excel 工作表?

当 DataSet 包含多个相关表(例如 Products 和 Orders)时,您可以将每个 DataTable 映射到同一工作簿中的独立工作表中。 这使接收者能够在一个文件中查看所有相关数据,而无需打开多个文档。

下面的循环遍历 ds.Tables,并为每个表格创建一个工作表:

using IronXL;
using System.Data;

// Build a DataSet with two related tables
DataSet ds = new DataSet("CompanyData");

DataTable dtProducts = new DataTable("Products");
dtProducts.Columns.Add("ProductID", typeof(int));
dtProducts.Columns.Add("ProductName", typeof(string));
dtProducts.Columns.Add("Price", typeof(decimal));
dtProducts.Rows.Add(101, "Widget A", 29.99m);
dtProducts.Rows.Add(102, "Widget B", 49.99m);
ds.Tables.Add(dtProducts);

DataTable dtOrders = new DataTable("Orders");
dtOrders.Columns.Add("OrderID", typeof(int));
dtOrders.Columns.Add("Customer", typeof(string));
dtOrders.Columns.Add("Total", typeof(decimal));
dtOrders.Rows.Add(1001, "Acme Corp", 599.90m);
dtOrders.Rows.Add(1002, "Tech Inc", 299.95m);
ds.Tables.Add(dtOrders);

// Create one workbook and iterate each DataTable
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);

foreach (DataTable table in ds.Tables)
{
    WorkSheet sheet = workbook.CreateWorkSheet(table.TableName);

    // Write headers
    for (int col = 0; col < table.Columns.Count; col++)
    {
        sheet.SetCellValue(0, col, table.Columns[col].ColumnName);
    }

    // Write rows
    for (int row = 0; row < table.Rows.Count; row++)
    {
        for (int col = 0; col < table.Columns.Count; col++)
        {
            sheet.SetCellValue(row + 1, col, table.Rows[row][col].ToString());
        }
    }
}

workbook.SaveAs("CompanyReport.xlsx");
using IronXL;
using System.Data;

// Build a DataSet with two related tables
DataSet ds = new DataSet("CompanyData");

DataTable dtProducts = new DataTable("Products");
dtProducts.Columns.Add("ProductID", typeof(int));
dtProducts.Columns.Add("ProductName", typeof(string));
dtProducts.Columns.Add("Price", typeof(decimal));
dtProducts.Rows.Add(101, "Widget A", 29.99m);
dtProducts.Rows.Add(102, "Widget B", 49.99m);
ds.Tables.Add(dtProducts);

DataTable dtOrders = new DataTable("Orders");
dtOrders.Columns.Add("OrderID", typeof(int));
dtOrders.Columns.Add("Customer", typeof(string));
dtOrders.Columns.Add("Total", typeof(decimal));
dtOrders.Rows.Add(1001, "Acme Corp", 599.90m);
dtOrders.Rows.Add(1002, "Tech Inc", 299.95m);
ds.Tables.Add(dtOrders);

// Create one workbook and iterate each DataTable
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);

foreach (DataTable table in ds.Tables)
{
    WorkSheet sheet = workbook.CreateWorkSheet(table.TableName);

    // Write headers
    for (int col = 0; col < table.Columns.Count; col++)
    {
        sheet.SetCellValue(0, col, table.Columns[col].ColumnName);
    }

    // Write rows
    for (int row = 0; row < table.Rows.Count; row++)
    {
        for (int col = 0; col < table.Columns.Count; col++)
        {
            sheet.SetCellValue(row + 1, col, table.Rows[row][col].ToString());
        }
    }
}

workbook.SaveAs("CompanyReport.xlsx");
Imports IronXL
Imports System.Data

' Build a DataSet with two related tables
Dim ds As New DataSet("CompanyData")

Dim dtProducts As New DataTable("Products")
dtProducts.Columns.Add("ProductID", GetType(Integer))
dtProducts.Columns.Add("ProductName", GetType(String))
dtProducts.Columns.Add("Price", GetType(Decimal))
dtProducts.Rows.Add(101, "Widget A", 29.99D)
dtProducts.Rows.Add(102, "Widget B", 49.99D)
ds.Tables.Add(dtProducts)

Dim dtOrders As New DataTable("Orders")
dtOrders.Columns.Add("OrderID", GetType(Integer))
dtOrders.Columns.Add("Customer", GetType(String))
dtOrders.Columns.Add("Total", GetType(Decimal))
dtOrders.Rows.Add(1001, "Acme Corp", 599.90D)
dtOrders.Rows.Add(1002, "Tech Inc", 299.95D)
ds.Tables.Add(dtOrders)

' Create one workbook and iterate each DataTable
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)

For Each table As DataTable In ds.Tables
    Dim sheet As WorkSheet = workbook.CreateWorkSheet(table.TableName)

    ' Write headers
    For col As Integer = 0 To table.Columns.Count - 1
        sheet.SetCellValue(0, col, table.Columns(col).ColumnName)
    Next

    ' Write rows
    For row As Integer = 0 To table.Rows.Count - 1
        For col As Integer = 0 To table.Columns.Count - 1
            sheet.SetCellValue(row + 1, col, table.Rows(row)(col).ToString())
        Next
    Next
Next

workbook.SaveAs("CompanyReport.xlsx")
$vbLabelText   $csharpLabel

输出

如何使用 VB.NET 将数据集导出到 Excel:IronXL 完整指南:图 2 - 生成的 Excel 文件,其中导出的数据集以单独的工作表形式呈现

每个工作表均以源 DataTable 命名,使在 Excel 中的导航变得直观简便。 因为 WorkBook.Create 在内存中分配工作簿,所以您可以在循环中不断添加工作表而无需重新打开文件 -- IronXL 在写入磁盘之前构建整个 XLSX 结构。

IronXL WorkBook 文档列出了 WorkBook 对象上所有可用方法,包括工作表重新排序、密码保护以及保存为 XLSX 以外的格式。

如何为 Excel 导出文件添加页眉格式?

纯文本导出虽能满足基本需求,但添加加粗标题和设置列宽后,生成的数据在商业场景中即可直接使用。 IronXL 通过附加到任何 Style 范围的 WorkSheet 对象公开单元格和范围样式。

下面的代码片段将标题行设置为粗体,并在写入数据后自动调整列宽:

using IronXL;
using System.Data;

DataTable dt = new DataTable("Sales");
dt.Columns.Add("Region", typeof(string));
dt.Columns.Add("Q1", typeof(decimal));
dt.Columns.Add("Q2", typeof(decimal));
dt.Columns.Add("Q3", typeof(decimal));
dt.Columns.Add("Q4", typeof(decimal));

dt.Rows.Add("无rth", 120000m, 135000m, 142000m, 158000m);
dt.Rows.Add("South", 98000m, 104000m, 112000m, 121000m);
dt.Rows.Add("East",  87000m, 93000m,  99000m,  108000m);
dt.Rows.Add("West",  145000m, 152000m, 161000m, 174000m);

WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Sales");

// Write and style headers
for (int col = 0; col < dt.Columns.Count; col++)
{
    sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
    sheet["A1:E1"].Style.Font.Bold = true;
    sheet["A1:E1"].Style.Font.Height = 12;
}

// Write data rows
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        sheet.SetCellValue(row + 1, col, dt.Rows[row][col]);
    }
}

workbook.SaveAs("SalesReport.xlsx");
using IronXL;
using System.Data;

DataTable dt = new DataTable("Sales");
dt.Columns.Add("Region", typeof(string));
dt.Columns.Add("Q1", typeof(decimal));
dt.Columns.Add("Q2", typeof(decimal));
dt.Columns.Add("Q3", typeof(decimal));
dt.Columns.Add("Q4", typeof(decimal));

dt.Rows.Add("无rth", 120000m, 135000m, 142000m, 158000m);
dt.Rows.Add("South", 98000m, 104000m, 112000m, 121000m);
dt.Rows.Add("East",  87000m, 93000m,  99000m,  108000m);
dt.Rows.Add("West",  145000m, 152000m, 161000m, 174000m);

WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Sales");

// Write and style headers
for (int col = 0; col < dt.Columns.Count; col++)
{
    sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
    sheet["A1:E1"].Style.Font.Bold = true;
    sheet["A1:E1"].Style.Font.Height = 12;
}

// Write data rows
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        sheet.SetCellValue(row + 1, col, dt.Rows[row][col]);
    }
}

workbook.SaveAs("SalesReport.xlsx");
Imports IronXL
Imports System.Data

Dim dt As New DataTable("Sales")
dt.Columns.Add("Region", GetType(String))
dt.Columns.Add("Q1", GetType(Decimal))
dt.Columns.Add("Q2", GetType(Decimal))
dt.Columns.Add("Q3", GetType(Decimal))
dt.Columns.Add("Q4", GetType(Decimal))

dt.Rows.Add("无rth", 120000D, 135000D, 142000D, 158000D)
dt.Rows.Add("South", 98000D, 104000D, 112000D, 121000D)
dt.Rows.Add("East", 87000D, 93000D, 99000D, 108000D)
dt.Rows.Add("West", 145000D, 152000D, 161000D, 174000D)

Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim sheet As WorkSheet = workbook.CreateWorkSheet("Sales")

' Write and style headers
For col As Integer = 0 To dt.Columns.Count - 1
    sheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
    sheet("A1:E1").Style.Font.Bold = True
    sheet("A1:E1").Style.Font.Height = 12
Next

' Write data rows
For row As Integer = 0 To dt.Rows.Count - 1
    For col As Integer = 0 To dt.Columns.Count - 1
        sheet.SetCellValue(row + 1, col, dt.Rows(row)(col))
    Next
Next

workbook.SaveAs("SalesReport.xlsx")
$vbLabelText   $csharpLabel

Style.Font.Bold 属性适用于单个语句中的整个标头范围。 IronXL 还支持背景颜色(Style.BackgroundColor)、边框样式(Style.Border)、数字格式(Style.NumberFormat.FormatCode)和水平对齐方式(Style.HorizontalAlignment)。 完整的样式参考请参阅 IronXL 单元格格式指南

如何将数据库查询结果导出到 Excel?

连接到 SQL 数据库并将结果直接导出到 Excel,涵盖了一个主要的实际应用场景——定时报告、数据快照和管理导出。 该方法使用 SqlDataAdapter 填充 DataSet,然后将生成的 DataTable 映射到 IronXL 工作表。

using IronXL;
using System.Data;
using System.Data.SqlClient;

string connectionString = "Server=localhost;Database=SalesDB;Integrated Security=True;";
string query = "SELECT CustomerID, CompanyName, ContactName, Country FROM Customers";

// Fill DataSet from SQL query
DataSet ds = new DataSet();
using (SqlConnection connection = new SqlConnection(connectionString))
{
    SqlDataAdapter adapter = new SqlDataAdapter(query, connection);
    adapter.Fill(ds, "Customers");
}

DataTable dt = ds.Tables["Customers"]!;

// Create workbook and export
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("CustomerData");

// Bold header row
for (int col = 0; col < dt.Columns.Count; col++)
{
    worksheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
}
worksheet["A1:D1"].Style.Font.Bold = true;

// Write rows, handling DBNull values safely
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        object cellValue = dt.Rows[row][col];
        worksheet.SetCellValue(row + 1, col,
            cellValue == DBNull.Value ? "" : cellValue.ToString()!);
    }
}

workbook.SaveAs("CustomerExport.xlsx");
Console.WriteLine("Export complete.");
using IronXL;
using System.Data;
using System.Data.SqlClient;

string connectionString = "Server=localhost;Database=SalesDB;Integrated Security=True;";
string query = "SELECT CustomerID, CompanyName, ContactName, Country FROM Customers";

// Fill DataSet from SQL query
DataSet ds = new DataSet();
using (SqlConnection connection = new SqlConnection(connectionString))
{
    SqlDataAdapter adapter = new SqlDataAdapter(query, connection);
    adapter.Fill(ds, "Customers");
}

DataTable dt = ds.Tables["Customers"]!;

// Create workbook and export
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("CustomerData");

// Bold header row
for (int col = 0; col < dt.Columns.Count; col++)
{
    worksheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
}
worksheet["A1:D1"].Style.Font.Bold = true;

// Write rows, handling DBNull values safely
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        object cellValue = dt.Rows[row][col];
        worksheet.SetCellValue(row + 1, col,
            cellValue == DBNull.Value ? "" : cellValue.ToString()!);
    }
}

workbook.SaveAs("CustomerExport.xlsx");
Console.WriteLine("Export complete.");
Imports IronXL
Imports System.Data
Imports System.Data.SqlClient

Dim connectionString As String = "Server=localhost;Database=SalesDB;Integrated Security=True;"
Dim query As String = "SELECT CustomerID, CompanyName, ContactName, Country FROM Customers"

' Fill DataSet from SQL query
Dim ds As New DataSet()
Using connection As New SqlConnection(connectionString)
    Dim adapter As New SqlDataAdapter(query, connection)
    adapter.Fill(ds, "Customers")
End Using

Dim dt As DataTable = ds.Tables("Customers")

' Create workbook and export
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet As WorkSheet = workbook.CreateWorkSheet("CustomerData")

' Bold header row
For col As Integer = 0 To dt.Columns.Count - 1
    worksheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
Next
worksheet("A1:D1").Style.Font.Bold = True

' Write rows, handling DBNull values safely
For row As Integer = 0 To dt.Rows.Count - 1
    For col As Integer = 0 To dt.Columns.Count - 1
        Dim cellValue As Object = dt.Rows(row)(col)
        worksheet.SetCellValue(row + 1, col, If(cellValue Is DBNull.Value, "", cellValue.ToString()))
    Next
Next

workbook.SaveAs("CustomerExport.xlsx")
Console.WriteLine("Export complete.")
$vbLabelText   $csharpLabel

数据库导出的关键要点

空值检查(cellValue == DBNull.Value ? "" : cellValue.ToString()) prevents exceptions when the database returns NULL 值 -- 可选列中常见的情况。 标题行采用粗体格式,使报告接收者能够立即区分标题与数据。

若需了解将 Excel 数据读回 C# 对象的更多示例,请参阅 IronXL DataTable 导出教程,其中演示了如何反向执行此工作流。

IronXL 与其他 Excel 导出方案相比如何?

在选择库之前,了解主要选项在 DataSet 导出场景中最关键的方面如何相互比较,将有所帮助。

针对 .NET DataSet 场景的 Excel 导出库对比
方法 办公室要求 XLSX 支持 样式 API 多页 性能(大数据)
IronXL 完整 高的
Microsoft Office Interop 完整 低的
EPPlus 部分的 高的
ClosedXML 部分的 中等的
CSV(手动) 非常高

Microsoft Office Interop 仅在安装了 Office 的 Windows 计算机上运行,因此不适用于服务器部署和云函数。 IronXL、EPPlus 和 ClosedXML 均支持服务器端生成——其关键区别在于样式 API 的广度以及许可模式。 IronXL 的许可范围涵盖商业用途,并支持通过单一软件包覆盖所有 .NET Framework 目标框架。

关于第三方基准测试和对比分析,Microsoft 关于 Excel 文件格式的文档以及 EPPlus 项目页面提供了更多背景信息,有助于您为项目做出正确选择。

如何在不引发内存问题的情况下处理大型数据集?

在导出包含数万行数据的 DataTables 时,确保内存使用量可预测至关重要。 以下模式直接从 IDataReader 流式传输数据,而不是先将整个结果集加载到 DataTable 中。这样可以避免同时保存读取缓冲区和 DataTable 而造成的双倍内存开销。

using IronXL;
using System.Data;
using System.Data.SqlClient;

string connectionString = "Server=localhost;Database=InventoryDB;Integrated Security=True;";
string query = "SELECT ProductID, SKU, Description, StockLevel, UnitCost FROM Products";

WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Inventory");

using SqlConnection conn = new SqlConnection(connectionString);
conn.Open();

using SqlCommand cmd = new SqlCommand(query, conn);
using SqlDataReader reader = cmd.ExecuteReader();

// Write schema-derived headers
for (int col = 0; col < reader.FieldCount; col++)
{
    sheet.SetCellValue(0, col, reader.GetName(col));
}

// Stream rows directly into IronXL without buffering a DataTable
int excelRow = 1;
while (reader.Read())
{
    for (int col = 0; col < reader.FieldCount; col++)
    {
        sheet.SetCellValue(excelRow, col,
            reader.IsDBNull(col) ? "" : reader.GetValue(col).ToString()!);
    }
    excelRow++;
}

workbook.SaveAs("InventoryExport.xlsx");
Console.WriteLine($"Exported {excelRow - 1} rows.");
using IronXL;
using System.Data;
using System.Data.SqlClient;

string connectionString = "Server=localhost;Database=InventoryDB;Integrated Security=True;";
string query = "SELECT ProductID, SKU, Description, StockLevel, UnitCost FROM Products";

WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Inventory");

using SqlConnection conn = new SqlConnection(connectionString);
conn.Open();

using SqlCommand cmd = new SqlCommand(query, conn);
using SqlDataReader reader = cmd.ExecuteReader();

// Write schema-derived headers
for (int col = 0; col < reader.FieldCount; col++)
{
    sheet.SetCellValue(0, col, reader.GetName(col));
}

// Stream rows directly into IronXL without buffering a DataTable
int excelRow = 1;
while (reader.Read())
{
    for (int col = 0; col < reader.FieldCount; col++)
    {
        sheet.SetCellValue(excelRow, col,
            reader.IsDBNull(col) ? "" : reader.GetValue(col).ToString()!);
    }
    excelRow++;
}

workbook.SaveAs("InventoryExport.xlsx");
Console.WriteLine($"Exported {excelRow - 1} rows.");
Imports IronXL
Imports System.Data
Imports System.Data.SqlClient

Dim connectionString As String = "Server=localhost;Database=InventoryDB;Integrated Security=True;"
Dim query As String = "SELECT ProductID, SKU, Description, StockLevel, UnitCost FROM Products"

Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim sheet As WorkSheet = workbook.CreateWorkSheet("Inventory")

Using conn As New SqlConnection(connectionString)
    conn.Open()

    Using cmd As New SqlCommand(query, conn)
        Using reader As SqlDataReader = cmd.ExecuteReader()

            ' Write schema-derived headers
            For col As Integer = 0 To reader.FieldCount - 1
                sheet.SetCellValue(0, col, reader.GetName(col))
            Next

            ' Stream rows directly into IronXL without buffering a DataTable
            Dim excelRow As Integer = 1
            While reader.Read()
                For col As Integer = 0 To reader.FieldCount - 1
                    sheet.SetCellValue(excelRow, col, If(reader.IsDBNull(col), "", reader.GetValue(col).ToString()))
                Next
                excelRow += 1
            End While

            workbook.SaveAs("InventoryExport.xlsx")
            Console.WriteLine($"Exported {excelRow - 1} rows.")
        End Using
    End Using
End Using
$vbLabelText   $csharpLabel

当结果集可能超过 50,000 行,或在内存受限的服务中运行时,建议采用此模式。IronXL 性能文档涵盖了针对海量导出的其他内存和吞吐量调优选项。

批量保存为 CSV 以处理超大导出数据

对于超过 500,000 行且内存极其紧张的导出操作,请考虑将输出拆分为多个工作簿,或改用 CSV 格式导出:

using IronXL;

// IronXL can save any workbook as CSV
workbook.SaveAs("LargeExport.csv");
using IronXL;

// IronXL can save any workbook as CSV
workbook.SaveAs("LargeExport.csv");
Imports IronXL

' IronXL can save any workbook as CSV
workbook.SaveAs("LargeExport.csv")
$vbLabelText   $csharpLabel

CSV 文件虽会丢失格式和多工作表支持,但对于处理原始分隔符数据的下游 ETL 流程而言,其数据仍具有有效性。

如何将 Excel 文件保存为不同格式并存储在不同位置?

IronXL 支持保存到文件路径,MemoryStreambyte[] -- 这对于返回 Excel 作为下载响应的 ASP.NET 应用程序来说很重要。

using IronXL;
using System.IO;

WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Report");
sheet.SetCellValue(0, 0, "Generated Report");

// Save to file path
workbook.SaveAs("Report.xlsx");

// Save as XLS (legacy format)
workbook.SaveAs("Report.xls");

// Save to MemoryStream for HTTP response
using MemoryStream ms = new MemoryStream();
workbook.SaveAs(ms);
byte[] fileBytes = ms.ToArray();
// fileBytes can be returned from an ASP.NET controller action
using IronXL;
using System.IO;

WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Report");
sheet.SetCellValue(0, 0, "Generated Report");

// Save to file path
workbook.SaveAs("Report.xlsx");

// Save as XLS (legacy format)
workbook.SaveAs("Report.xls");

// Save to MemoryStream for HTTP response
using MemoryStream ms = new MemoryStream();
workbook.SaveAs(ms);
byte[] fileBytes = ms.ToArray();
// fileBytes can be returned from an ASP.NET controller action
Imports IronXL
Imports System.IO

Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim sheet As WorkSheet = workbook.CreateWorkSheet("Report")
sheet.SetCellValue(0, 0, "Generated Report")

' Save to file path
workbook.SaveAs("Report.xlsx")

' Save as XLS (legacy format)
workbook.SaveAs("Report.xls")

' Save to MemoryStream for HTTP response
Using ms As New MemoryStream()
    workbook.SaveAs(ms)
    Dim fileBytes As Byte() = ms.ToArray()
    ' fileBytes can be returned from an ASP.NET controller action
End Using
$vbLabelText   $csharpLabel

对于 ASP.NET Core,从控制器操作返回 File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Report.xlsx") 以触发浏览器下载。 《IronXL ASP.NET Excel 指南》展示了完整的控制器集成模式。

关于其他 .NET Excel 库,Open XML SDK 是许多库构建的基础的开源框架。

支持的输出格式

IronXL 可在不依赖任何额外组件的情况下保存为以下格式:

  • XLSX -- OpenXML 格式,兼容 Excel 2007 及更高版本
  • XLS -- 旧版二进制格式,兼容 Excel 97-2003
  • CSV -- 逗号分隔值,被广泛支持
  • TSV -- 制表符分隔值
  • JSON -- 结构化数据导出

通过更改 SaveAs 路径中的文件扩展名或使用接受 ExcelFileFormat 枚举值的重载方法来切换格式。

如何验证导出的 Excel 文件是否正确?

导出后,您可以使用 IronXL 重新读取该文件,以验证行数、抽查数值,或在测试项目中运行自动化断言:

using IronXL;

WorkBook loaded = WorkBook.Load("EmployeeData.xlsx");
WorkSheet sheet = loaded.WorkSheets[0];

// Verify row count (header row + data rows)
int totalRows = sheet.Rows.Count();
Console.WriteLine($"Rows in file: {totalRows}");

// Spot-check specific cell values
string header = sheet["A1"].StringValue;
string firstEmployee = sheet["A2"].StringValue;

Console.WriteLine($"Header: {header}, First row: {firstEmployee}");
using IronXL;

WorkBook loaded = WorkBook.Load("EmployeeData.xlsx");
WorkSheet sheet = loaded.WorkSheets[0];

// Verify row count (header row + data rows)
int totalRows = sheet.Rows.Count();
Console.WriteLine($"Rows in file: {totalRows}");

// Spot-check specific cell values
string header = sheet["A1"].StringValue;
string firstEmployee = sheet["A2"].StringValue;

Console.WriteLine($"Header: {header}, First row: {firstEmployee}");
Imports IronXL

Dim loaded As WorkBook = WorkBook.Load("EmployeeData.xlsx")
Dim sheet As WorkSheet = loaded.WorkSheets(0)

' Verify row count (header row + data rows)
Dim totalRows As Integer = sheet.Rows.Count()
Console.WriteLine($"Rows in file: {totalRows}")

' Spot-check specific cell values
Dim header As String = sheet("A1").StringValue
Dim firstEmployee As String = sheet("A2").StringValue

Console.WriteLine($"Header: {header}, First row: {firstEmployee}")
$vbLabelText   $csharpLabel

此验证模式在集成测试Suite中尤为有用,因为在将文件发送至外部系统之前,必须确认导出内容的正确性。 IronXL 读取教程展示了加载文件后可用的全部读取操作。

如需进一步了解 .NET 中的 DataSet 和 DataTable 模式,请参阅 Microsoft DataSet 文档,其中深入介绍了 ADO.NET 对象模型。

下一步计划是什么?

现在,您已掌握 C# 中所有主要 DataSet 转 Excel 导出场景的实现模式——从单个 DataTable 到多工作表工作簿、数据库驱动的导出、格式化标题以及大数据流处理。 根据您的目标,下一步操作如下:

  • 免费试用 IronXL -- 先获取免费试用许可证,在将代码投入生产环境之前,使用您自己的数据运行上述示例。
  • 阅读完整的 API 参考文档 -- IronXL 对象参考文档涵盖了 WorkBook、WorkSheet 以及单元格区域的所有方法。
  • 探索相关导出教程——《C# DataTable 转 Excel 指南》介绍了反向工作流——将 Excel 数据读回 DataTable 对象。
  • 查看格式设置选项 -- IronXL 单元格格式设置文档介绍了数字格式、边框、背景颜色和对齐方式等选项。
  • 查看许可协议——若用于生产环境部署,请访问 IronXL 许可页面,在开发者版、组织版和免版税版之间进行选择。
  • 与其他 Iron Software 工具对比——若您的项目还需 PDF 生成或 OCR 功能,Iron Software 产品套件可让您以优惠价格捆绑使用多个库。

基于此处介绍的模式,您可以完全使用托管 C# 实现定时任务自动化、ASP.NET Core 下载端点以及多格式输出管道——无需 Office、无需 COM,除 NuGet 包外不依赖任何运行时组件。

常见问题解答

如何使用 C# 将数据集导出到 Excel?

您可以使用IronXL库在 C# 中将数据集导出到 Excel,该库提供了一个代码优先的 API,用于创建、编辑和操作 Excel 文件,而无需 Microsoft Office。

我需要安装 Microsoft Office 来使用 IronXL 吗?

不, IronXL不需要在计算机上安装 Microsoft Office 即可导出或处理 Excel 文件。

我可以使用IronXL导出哪些类型的数据?

IronXL允许您将结构化数据(例如 DataTables 和 DataSets)导出到 Excel 文件,以及从 SqlDataReader 和其他.NET源导出数据。

IronXL能否处理 Excel 文件的创建和编辑?

是的, IronXL提供了使用 C# 以编程方式创建、编辑和操作 Excel 文件的功能。

IronXL是否适用于服务器端和云应用程序?

是的, IronXL非常适合需要在不安装任何 Office 的情况下生成 Excel 文件的服务器端应用程序和云函数。

使用IronXL导出数据集有哪些好处?

IronXL无需 Microsoft Office 等外部依赖项即可处理 Excel 文件的创建和操作,支持 XLSX、XLS 和 CSV 格式,并且可以在所有.NET目标框架上运行。

IronXL能否在ASP.NET Core中使用以返回 Excel 下载文件?

是的, IronXL可以将工作簿保存到 MemoryStream 中,生成的字节数组可以从ASP.NET Core控制器操作作为文件下载返回。

IronXL是否支持大型数据集?

是的, IronXL可以直接从 SqlDataReader 流式传输数据,而无需缓冲整个 DataTable,从而保持大型结果集的内存使用量可预测。

IronXL支持保存哪些 Excel 格式?

IronXL支持保存为 XLSX、XLS、CSV、TSV 和 JSON 格式,无需任何额外依赖项。

导出到 Excel 时,我可以应用粗体标题等格式吗?

是的, IronXL为单元格区域提供了样式 API,用于设置粗体字体、背景颜色、边框、数字格式和对齐方式。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我