如何在 C# 中将 GridView 导出到 Excel 并保留格式
在将 GridView 数据导出到 Excel 时,保留颜色、字体、交替行背景色和边框,是几乎所有数据驱动型 ASP.NET 或 Windows Forms 应用程序中都会出现的需求。 传统方法——使用 HtmlTextWriter 和 StringWriter 将控件渲染为 HTML——生成的文件在 Excel 中带有格式警告,并且对用户来说毫无反应。 IronXL 通过完全使用 C# 生成原生 XLSX 文件来解决这一问题,且不依赖 Microsoft Office,让您能够精确控制每个单元格的样式。
如何在.NET项目中安装库?
在编写任何导出代码之前,请先从 NuGet 安装 IronXL。 打开软件包管理器控制台并运行:
Install-Package IronXL
dotnet add package IronXL
Install-Package IronXL
dotnet add package IronXL
IronXL 支持 .NET 8、.NET 9 和 .NET 10,以及 .NET Framework 4.6.2 及更高版本。 安装完成后,将以下 using 指令添加到任何执行 Excel 操作的文件中:
using IronXL;
using IronXL.Styles;
using IronXL;
using IronXL.Styles;
Imports IronXL
Imports IronXL.Styles
无需额外的运行时环境或 Office 互操作支持。 该库生成的原生 XLSX 二进制文件可在 Microsoft Excel、LibreOffice Calc 和 Google 表格中完美打开。
如何将 Windows Forms 的 DataGridView 连同单元格格式一起导出到 Excel?
Windows Forms 应用程序使用 DataGridView 控件,而不是基于 Web 的 GridView 控件。 两种情况下的导出模式相同:从行和单元格中提取值,创建 IronXL 工作簿,应用样式,然后保存或流式传输结果。
最可靠的方法是将控件的 DataSource 属性强制转换为 DataTable,以避免遍历可能经过筛选或分页的可视行:
using IronXL;
using IronXL.Styles;
using System;
using System.Data;
using System.IO;
using System.Windows.Forms;
DataTable dt = (DataTable)dataGridView1.DataSource;
WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.DefaultWorkSheet;
// Header row -- bold, blue background, white text
for (int col = 0; col < dt.Columns.Count; col++)
{
sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
var cell = sheet.GetCellAt(0, col);
cell.Style.Font.Bold = true;
cell.Style.SetBackgroundColor("#4472C4");
cell.Style.Font.Color = "#FFFFFF";
cell.Style.BottomBorder.Type = BorderType.Thin;
}
// Data rows -- alternating row color
for (int row = 0; row < dt.Rows.Count; row++)
{
for (int col = 0; col < dt.Columns.Count; col++)
{
string value = dt.Rows[row][col]?.ToString() ?? string.Empty;
sheet.SetCellValue(row + 1, col, value);
var cell = sheet.GetCellAt(row + 1, col);
cell.Style.SetBackgroundColor(row % 2 == 0 ? "#D6DCE5" : "#FFFFFF");
cell.Style.BottomBorder.Type = BorderType.Thin;
}
}
// Save via dialog
using var saveDialog = new SaveFileDialog
{
Filter = "Excel Files|*.xlsx",
FileName = "GridViewExport.xlsx"
};
if (saveDialog.ShowDialog() == DialogResult.OK)
{
workBook.SaveAs(saveDialog.FileName);
MessageBox.Show("Export successful.", "Export",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
using IronXL;
using IronXL.Styles;
using System;
using System.Data;
using System.IO;
using System.Windows.Forms;
DataTable dt = (DataTable)dataGridView1.DataSource;
WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.DefaultWorkSheet;
// Header row -- bold, blue background, white text
for (int col = 0; col < dt.Columns.Count; col++)
{
sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
var cell = sheet.GetCellAt(0, col);
cell.Style.Font.Bold = true;
cell.Style.SetBackgroundColor("#4472C4");
cell.Style.Font.Color = "#FFFFFF";
cell.Style.BottomBorder.Type = BorderType.Thin;
}
// Data rows -- alternating row color
for (int row = 0; row < dt.Rows.Count; row++)
{
for (int col = 0; col < dt.Columns.Count; col++)
{
string value = dt.Rows[row][col]?.ToString() ?? string.Empty;
sheet.SetCellValue(row + 1, col, value);
var cell = sheet.GetCellAt(row + 1, col);
cell.Style.SetBackgroundColor(row % 2 == 0 ? "#D6DCE5" : "#FFFFFF");
cell.Style.BottomBorder.Type = BorderType.Thin;
}
}
// Save via dialog
using var saveDialog = new SaveFileDialog
{
Filter = "Excel Files|*.xlsx",
FileName = "GridViewExport.xlsx"
};
if (saveDialog.ShowDialog() == DialogResult.OK)
{
workBook.SaveAs(saveDialog.FileName);
MessageBox.Show("Export successful.", "Export",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Imports IronXL
Imports IronXL.Styles
Imports System
Imports System.Data
Imports System.IO
Imports System.Windows.Forms
Dim dt As DataTable = DirectCast(dataGridView1.DataSource, DataTable)
Dim workBook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim sheet As WorkSheet = workBook.DefaultWorkSheet
' Header row -- bold, blue background, white text
For col As Integer = 0 To dt.Columns.Count - 1
sheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
Dim cell = sheet.GetCellAt(0, col)
cell.Style.Font.Bold = True
cell.Style.SetBackgroundColor("#4472C4")
cell.Style.Font.Color = "#FFFFFF"
cell.Style.BottomBorder.Type = BorderType.Thin
Next
' Data rows -- alternating row color
For row As Integer = 0 To dt.Rows.Count - 1
For col As Integer = 0 To dt.Columns.Count - 1
Dim value As String = If(dt.Rows(row)(col)?.ToString(), String.Empty)
sheet.SetCellValue(row + 1, col, value)
Dim cell = sheet.GetCellAt(row + 1, col)
cell.Style.SetBackgroundColor(If(row Mod 2 = 0, "#D6DCE5", "#FFFFFF"))
cell.Style.BottomBorder.Type = BorderType.Thin
Next
Next
' Save via dialog
Using saveDialog As New SaveFileDialog With {
.Filter = "Excel Files|*.xlsx",
.FileName = "GridViewExport.xlsx"
}
If saveDialog.ShowDialog() = DialogResult.OK Then
workBook.SaveAs(saveDialog.FileName)
MessageBox.Show("Export successful.", "Export", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Using
WorkBook.Create 初始化一个新的内存中的 XLSX 格式工作簿。 DefaultWorkSheet 返回第一个工作表,您可以在保存之前通过其 Name 属性重命名该工作表。 SetCellValue 接受字符串、整数、双精度浮点数和 DateTime 值 -- IronXL 会自动选择正确的单元格类型。
交替行颜色模式 -- row % 2 == 0 选择 #D6DCE5,否则选择 #FFFFFF -- 反映了 Excel 内置的带状行表格样式。 您可以替换为任何与应用程序设计系统匹配的六位十六进制颜色代码。
输出图像
使用 IronXL 将 GridView 导出到 Excel 并设置格式(C#):图 1 - GridView 输出
如何将 ASP.NET GridView 导出到 Excel 并将文件流式传输到浏览器?
Web 应用程序需要不同的交付机制。 与其写入文件系统,不如将工作簿序列化为 MemoryStream,并将其连同正确的标头一起写入 HTTP 响应,以便浏览器将其视为文件下载。
分页 GridView 的重要预检步骤:在导出之前禁用分页 (AllowPaging = false) 并重新绑定数据源,以便捕获每个记录(而不仅仅是当前页)。
using IronXL;
using IronXL.Styles;
using System;
using System.Data;
using System.IO;
using System.Web.UI;
// Disable paging so all rows are captured
GridView1.AllowPaging = false;
GridView1.DataBind();
DataTable dt = (DataTable)GridView1.DataSource;
WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.DefaultWorkSheet;
// Header row
for (int col = 0; col < dt.Columns.Count; col++)
{
sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
var cell = sheet.GetCellAt(0, col);
cell.Style.Font.Bold = true;
cell.Style.SetBackgroundColor("#2E75B6");
cell.Style.Font.Color = "#FFFFFF";
cell.Style.HorizontalAlignment = HorizontalAlignment.Center;
cell.Style.BottomBorder.Type = BorderType.Medium;
}
// 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]?.ToString() ?? string.Empty);
var cell = sheet.GetCellAt(row + 1, col);
cell.Style.SetBackgroundColor(row % 2 == 0 ? "#DEEAF1" : "#FFFFFF");
cell.Style.BottomBorder.Type = BorderType.Thin;
cell.Style.LeftBorder.Type = BorderType.Thin;
cell.Style.RightBorder.Type = BorderType.Thin;
}
}
// Stream to browser
byte[] fileBytes = workBook.ToByteArray();
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=GridViewExport.xlsx");
Response.BinaryWrite(fileBytes);
Response.End();
using IronXL;
using IronXL.Styles;
using System;
using System.Data;
using System.IO;
using System.Web.UI;
// Disable paging so all rows are captured
GridView1.AllowPaging = false;
GridView1.DataBind();
DataTable dt = (DataTable)GridView1.DataSource;
WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.DefaultWorkSheet;
// Header row
for (int col = 0; col < dt.Columns.Count; col++)
{
sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
var cell = sheet.GetCellAt(0, col);
cell.Style.Font.Bold = true;
cell.Style.SetBackgroundColor("#2E75B6");
cell.Style.Font.Color = "#FFFFFF";
cell.Style.HorizontalAlignment = HorizontalAlignment.Center;
cell.Style.BottomBorder.Type = BorderType.Medium;
}
// 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]?.ToString() ?? string.Empty);
var cell = sheet.GetCellAt(row + 1, col);
cell.Style.SetBackgroundColor(row % 2 == 0 ? "#DEEAF1" : "#FFFFFF");
cell.Style.BottomBorder.Type = BorderType.Thin;
cell.Style.LeftBorder.Type = BorderType.Thin;
cell.Style.RightBorder.Type = BorderType.Thin;
}
}
// Stream to browser
byte[] fileBytes = workBook.ToByteArray();
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=GridViewExport.xlsx");
Response.BinaryWrite(fileBytes);
Response.End();
Imports IronXL
Imports IronXL.Styles
Imports System
Imports System.Data
Imports System.IO
Imports System.Web.UI
' Disable paging so all rows are captured
GridView1.AllowPaging = False
GridView1.DataBind()
Dim dt As DataTable = CType(GridView1.DataSource, DataTable)
Dim workBook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim sheet As WorkSheet = workBook.DefaultWorkSheet
' Header row
For col As Integer = 0 To dt.Columns.Count - 1
sheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
Dim cell = sheet.GetCellAt(0, col)
cell.Style.Font.Bold = True
cell.Style.SetBackgroundColor("#2E75B6")
cell.Style.Font.Color = "#FFFFFF"
cell.Style.HorizontalAlignment = HorizontalAlignment.Center
cell.Style.BottomBorder.Type = BorderType.Medium
Next
' 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, If(dt.Rows(row)(col)?.ToString(), String.Empty))
Dim cell = sheet.GetCellAt(row + 1, col)
cell.Style.SetBackgroundColor(If(row Mod 2 = 0, "#DEEAF1", "#FFFFFF"))
cell.Style.BottomBorder.Type = BorderType.Thin
cell.Style.LeftBorder.Type = BorderType.Thin
cell.Style.RightBorder.Type = BorderType.Thin
Next
Next
' Stream to browser
Dim fileBytes As Byte() = workBook.ToByteArray()
Response.Clear()
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Response.AddHeader("content-disposition", "attachment; filename=GridViewExport.xlsx")
Response.BinaryWrite(fileBytes)
Response.End()
使用 Response.AddHeader 和 content-disposition: attachment 会在所有现代浏览器中强制弹出文件下载对话框。 MIME 类型 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 是 XLSX 文件的注册类型,可防止浏览器尝试以内联方式显示二进制内容。
对于 ASP.NET Core 应用程序,在控制器操作中将 Response.BinaryWrite 替换为 File(fileBytes, contentType, fileName) -- 工作簿创建逻辑是相同的。
如何根据单元格值应用条件格式?
条件格式化功能可突出显示符合特定条件的单元格——例如,将逾期日期标记为红色,或将低于阈值的数值标记为橙色。 IronXL 在构建工作簿时会在单元格级别应用条件格式:
// Assume "DueDate" is column index 3 and "Amount" is column index 4
DateTime today = DateTime.Today;
for (int row = 0; row < dt.Rows.Count; row++)
{
// Highlight past-due dates
if (dt.Columns.Contains("DueDate") && dt.Rows[row]["DueDate"] != DBNull.Value)
{
DateTime dueDate = Convert.ToDateTime(dt.Rows[row]["DueDate"]);
var dueDateCell = sheet.GetCellAt(row + 1, 3);
if (dueDate < today)
{
dueDateCell.Style.SetBackgroundColor("#FF0000");
dueDateCell.Style.Font.Color = "#FFFFFF";
dueDateCell.Style.Font.Bold = true;
}
}
// Highlight amounts below threshold
if (dt.Columns.Contains("Amount") && dt.Rows[row]["Amount"] != DBNull.Value)
{
decimal amount = Convert.ToDecimal(dt.Rows[row]["Amount"]);
var amountCell = sheet.GetCellAt(row + 1, 4);
if (amount < 100m)
{
amountCell.Style.SetBackgroundColor("#FFC000");
}
}
}
// Assume "DueDate" is column index 3 and "Amount" is column index 4
DateTime today = DateTime.Today;
for (int row = 0; row < dt.Rows.Count; row++)
{
// Highlight past-due dates
if (dt.Columns.Contains("DueDate") && dt.Rows[row]["DueDate"] != DBNull.Value)
{
DateTime dueDate = Convert.ToDateTime(dt.Rows[row]["DueDate"]);
var dueDateCell = sheet.GetCellAt(row + 1, 3);
if (dueDate < today)
{
dueDateCell.Style.SetBackgroundColor("#FF0000");
dueDateCell.Style.Font.Color = "#FFFFFF";
dueDateCell.Style.Font.Bold = true;
}
}
// Highlight amounts below threshold
if (dt.Columns.Contains("Amount") && dt.Rows[row]["Amount"] != DBNull.Value)
{
decimal amount = Convert.ToDecimal(dt.Rows[row]["Amount"]);
var amountCell = sheet.GetCellAt(row + 1, 4);
if (amount < 100m)
{
amountCell.Style.SetBackgroundColor("#FFC000");
}
}
}
Imports System
' Assume "DueDate" is column index 3 and "Amount" is column index 4
Dim today As DateTime = DateTime.Today
For row As Integer = 0 To dt.Rows.Count - 1
' Highlight past-due dates
If dt.Columns.Contains("DueDate") AndAlso dt.Rows(row)("DueDate") IsNot DBNull.Value Then
Dim dueDate As DateTime = Convert.ToDateTime(dt.Rows(row)("DueDate"))
Dim dueDateCell = sheet.GetCellAt(row + 1, 3)
If dueDate < today Then
dueDateCell.Style.SetBackgroundColor("#FF0000")
dueDateCell.Style.Font.Color = "#FFFFFF"
dueDateCell.Style.Font.Bold = True
End If
End If
' Highlight amounts below threshold
If dt.Columns.Contains("Amount") AndAlso dt.Rows(row)("Amount") IsNot DBNull.Value Then
Dim amount As Decimal = Convert.ToDecimal(dt.Rows(row)("Amount"))
Dim amountCell = sheet.GetCellAt(row + 1, 4)
If amount < 100D Then
amountCell.Style.SetBackgroundColor("#FFC000")
End If
End If
Next row
此模式支持组合使用——可根据您的报表需求添加任意数量的条件检查。 由于 IronXL 采用逐单元格处理机制,您可以在基础行样式之后应用条件样式,从而将条件格式与交替行颜色逻辑相结合。
如何设置列宽并固定标题行?
Professional 格式的 Excel 导出文件应包含适当的列宽和固定标题行,以便用户在滚动浏览大型数据集时,列名始终可见。
IronXL 通过 WorkSheet 列访问器公开列宽,并通过 FreezeRows 方法冻结标题:
// Auto-size columns 0 through the last column index
for (int col = 0; col < dt.Columns.Count; col++)
{
// Set column width in character units (1 unit ≈ one default character width)
sheet.SetColumnWidth(col, 20);
}
// Freeze the first row (index 0) so the header stays visible while scrolling
sheet.FreezeRows(1);
// Optionally set row height for the header (in points)
sheet.SetRowHeight(0, 20);
// Auto-size columns 0 through the last column index
for (int col = 0; col < dt.Columns.Count; col++)
{
// Set column width in character units (1 unit ≈ one default character width)
sheet.SetColumnWidth(col, 20);
}
// Freeze the first row (index 0) so the header stays visible while scrolling
sheet.FreezeRows(1);
// Optionally set row height for the header (in points)
sheet.SetRowHeight(0, 20);
' Auto-size columns 0 through the last column index
For col As Integer = 0 To dt.Columns.Count - 1
' Set column width in character units (1 unit ≈ one default character width)
sheet.SetColumnWidth(col, 20)
Next
' Freeze the first row (index 0) so the header stays visible while scrolling
sheet.FreezeRows(1)
' Optionally set row height for the header (in points)
sheet.SetRowHeight(0, 20)
在实际生产环境中,建议根据每列的最大字符数来计算宽度,而非使用固定值。 遍历 DataTable 列的值,测量字符串长度,并乘以适合所选字体大小的字符宽度因子。
您还可以使用 C# 为 Excel 单元格设置背景色,该操作独立于行交替填充逻辑,从而实现更精细的样式控制。
如何在不使用 GridView 控件的情况下将 DataTable 导出到 Excel?
许多 .NET 应用程序通过服务调用或数据库查询填充数据,并将其保存在 DataTable 中,而从未将其绑定到 UI 控件。 您可以直接将 DataTable 导出到 Excel,而无需实例化 GridView。
对于需要在服务器端生成 Excel 文件的后台任务、定时报告和 API 端点,这是最高效的实现路径:
using IronXL;
using IronXL.Styles;
using System.Data;
public static byte[] DataTableToExcelBytes(DataTable dt, string sheetName = "Report")
{
WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.CreateWorkSheet(sheetName);
// Header
for (int col = 0; col < dt.Columns.Count; col++)
{
sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
var cell = sheet.GetCellAt(0, col);
cell.Style.Font.Bold = true;
cell.Style.SetBackgroundColor("#4472C4");
cell.Style.Font.Color = "#FFFFFF";
}
// Data
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]?.ToString() ?? string.Empty);
}
}
return workBook.ToByteArray();
}
using IronXL;
using IronXL.Styles;
using System.Data;
public static byte[] DataTableToExcelBytes(DataTable dt, string sheetName = "Report")
{
WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.CreateWorkSheet(sheetName);
// Header
for (int col = 0; col < dt.Columns.Count; col++)
{
sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
var cell = sheet.GetCellAt(0, col);
cell.Style.Font.Bold = true;
cell.Style.SetBackgroundColor("#4472C4");
cell.Style.Font.Color = "#FFFFFF";
}
// Data
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]?.ToString() ?? string.Empty);
}
}
return workBook.ToByteArray();
}
Imports IronXL
Imports IronXL.Styles
Imports System.Data
Public Shared Function DataTableToExcelBytes(dt As DataTable, Optional sheetName As String = "Report") As Byte()
Dim workBook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim sheet As WorkSheet = workBook.CreateWorkSheet(sheetName)
' Header
For col As Integer = 0 To dt.Columns.Count - 1
sheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
Dim cell = sheet.GetCellAt(0, col)
cell.Style.Font.Bold = True
cell.Style.SetBackgroundColor("#4472C4")
cell.Style.Font.Color = "#FFFFFF"
Next
' Data
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, If(dt.Rows(row)(col)?.ToString(), String.Empty))
Next
Next
Return workBook.ToByteArray()
End Function
此方法返回一个 byte[],您可以将其写入磁盘、从 API 端点流式传输、附加到电子邮件或缓存到内存中。 有关相关技术,请参阅将 DataTable 导出到 Excel 的指南以及关于将 DataTable 导出到 Excel 的最快方法的教程。
如何处理大型数据集并保证性能?
将数万行数据导出到 Excel 时,需注意内存分配问题。 对于大型网格中的每个单元格都创建一个新的单元格样式对象,是性能瓶颈最常见的成因。 尽可能复用样式定义,通过为范围对象设置样式而非单独设置单元格样式:
| 数据集规模 | 建议的翻译方法 | 关键考虑因素 |
|---|---|---|
| 最多 5,000 行 | 逐单元格样式循环 | 代码简洁,开销微乎其微 |
| 5,000 — 50,000 行 | 范围级样式应用 | 显著减少对象分配 |
| 50,000+ 行 | DataTable 直接导出,样式简化 | 尽量减少按单元格操作;若支持,请使用流式处理 |
对于分页 GridView,请始终设置 AllowPaging = false 并在导出之前重新绑定。 分页功能会限制控件中可见的行数,因此分页导出仅捕获当前页面而非整个数据集——这常常是导致导出不完整错误的常见原因。
您还可以查看有关在 C# 中将对象列表导出到 Excel 的指南,了解适用于强类型集合而不是非类型行的模式。
如何在 ASP.NET Core 或 Blazor 中导出 GridView?
ASP.NET Core 和 Blazor 应用程序没有 Web Forms 控件,但底层数据导出挑战是相同的:获取对象集合或数据,构建样式化的工作簿,并交付文件。工作簿创建代码完全相同; 仅交付机制有所变化。
在 Blazor 应用程序中,通过 JavaScript 互操作触发文件下载:
// In a Blazor component or service
using IronXL;
using System.Data;
using Microsoft.JSInterop;
public async Task ExportToExcelAsync(DataTable dt, IJSRuntime js)
{
WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.DefaultWorkSheet;
for (int col = 0; col < dt.Columns.Count; col++)
{
sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
var cell = sheet.GetCellAt(0, col);
cell.Style.Font.Bold = true;
cell.Style.SetBackgroundColor("#4472C4");
cell.Style.Font.Color = "#FFFFFF";
}
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]?.ToString() ?? string.Empty);
}
}
byte[] fileBytes = workBook.ToByteArray();
string base64 = Convert.ToBase64String(fileBytes);
await js.InvokeVoidAsync("downloadFileFromBase64", base64, "GridViewExport.xlsx",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
// In a Blazor component or service
using IronXL;
using System.Data;
using Microsoft.JSInterop;
public async Task ExportToExcelAsync(DataTable dt, IJSRuntime js)
{
WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.DefaultWorkSheet;
for (int col = 0; col < dt.Columns.Count; col++)
{
sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
var cell = sheet.GetCellAt(0, col);
cell.Style.Font.Bold = true;
cell.Style.SetBackgroundColor("#4472C4");
cell.Style.Font.Color = "#FFFFFF";
}
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]?.ToString() ?? string.Empty);
}
}
byte[] fileBytes = workBook.ToByteArray();
string base64 = Convert.ToBase64String(fileBytes);
await js.InvokeVoidAsync("downloadFileFromBase64", base64, "GridViewExport.xlsx",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
Imports IronXL
Imports System.Data
Imports Microsoft.JSInterop
Public Async Function ExportToExcelAsync(dt As DataTable, js As IJSRuntime) As Task
Dim workBook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim sheet As WorkSheet = workBook.DefaultWorkSheet
For col As Integer = 0 To dt.Columns.Count - 1
sheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
Dim cell = sheet.GetCellAt(0, col)
cell.Style.Font.Bold = True
cell.Style.SetBackgroundColor("#4472C4")
cell.Style.Font.Color = "#FFFFFF"
Next
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, If(dt.Rows(row)(col)?.ToString(), String.Empty))
Next
Next
Dim fileBytes As Byte() = workBook.ToByteArray()
Dim base64 As String = Convert.ToBase64String(fileBytes)
Await js.InvokeVoidAsync("downloadFileFromBase64", base64, "GridViewExport.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
End Function
Blazor 下载模式的完整演示详见《Blazor 导出到 Excel 教程》。 有关 ASP.NET Core 控制器实现方法,请参阅 ASP.NET Core 导出 Excel 教程。
字体样式和边框选项
IronXL 通过每个单元格上的 Style 对象公开细粒度的字体和边框控制。 C# 中 Excel 字体的完整样式包括粗体、斜体、下划线、字号和颜色。 通过 BorderType 提供的边框类型包括细边框、中等边框、粗边框、虚线边框、点线边框、双线边框和几种细线变体。
对于合并的表头行或摘要表脚,IronXL 还支持使用 C# 在 Excel 中合并单元格——当您希望在数据表上方设置一个横跨多列的标题单元格时,此功能非常有用。
若需在填入数据后自动调整列宽,请参考《使用 C# 在 Excel 中自动调整单元格宽度》指南中的推荐方法。
为什么原生 Excel 库生成的导出结果比 HtmlTextWriter 更干净?
传统的 ASP.NET 导出技术——重写 VerifyRenderingInServerForm,创建 StringWriter 和 HtmlTextWriter,并将渲染的控件写入响应——生成一个扩展名为 .xls 的 HTML 文档。 Microsoft Excel 打开此类文件时会显示兼容性警告,因为该文件实际上并非 Excel 二进制或 OOXML 格式。 样式仅限于 Excel 能部分解析的内联 CSS。 无法使用条件格式化。 非 Windows 平台用户或使用 LibreOffice 的用户将看到质量较差的输出结果。
IronXL 可直接写入 Open XML 电子表格格式 (OOXML)。 结果是一个正确的 .xlsx 文件——与 Excel 本身创建的文件完全相同——在 macOS 上的 Excel、LibreOffice、Google Sheets 和 Numbers 中打开时不会出现警告。 格式采用电子表格样式编码,而非 HTML 属性,因此能够经受往返传输和跨平台查看。
| 方法 | 文件格式 | 格式提示 | 全面支持样式规范 | 办公室要求 |
|---|---|---|---|---|
| HtmlTextWriter + StringWriter | 伪装成 XLS 的 HTML | 是 | 无 | 无 |
| Office 互操作(COM) | 原生 XLS/XLSX | 无 | 是 | 是 |
| IronXL | 原生 XLSX/XLS | 无 | 是 | 无 |
微软关于 Open XML SDK 的官方文档详细说明了 IronXL 生成的底层格式。 由 ECMA International 维护的 OOXML 规范定义了确保跨应用程序兼容性的标准。 Microsoft Docs 上的 ASP.NET GridView 控件文档描述了上述导出模式所读取的控件模型。
下一步计划是什么?
现在,您已掌握使用 IronXL 将 GridView 和 DataGridView 数据导出为格式正确的 XLSX 文件所需的模式——涵盖 Windows Forms、ASP.NET Web Forms、ASP.NET Core 和 Blazor 交付模型。
更进一步:
- 立即免费试用 IronXL,使用您的数据测试其完整的格式化和导出功能。
- 请查阅 IronXL 文档以获取完整的 API 参考,包括数据透视表、图表和数据验证。
- 探索使用 C# 创建 Excel 报表,将上述导出模式与计算得出的汇总数据和图表相结合。
- 若您的应用程序还需处理上传的电子表格,请参阅《使用 C# 读取 Excel 文件》以了解相应的导入工作流。
- 关于除 XLSX 之外的 CSV 格式导出,请参阅 C# 导出为 CSV 教程。
- 若需将 DataGridView 中的数据导出,且需将列标题作为第一行,请参阅专门的《DataGridView 导出至 Excel(含列标题)指南》。
常见问题解答
如何使用 C# 将 GridView 数据导出到 Excel?
您可以使用IronXL库在 C# 中将 GridView 数据导出到 Excel。它允许您以编程方式轻松创建 Excel 文件并导出数据,包括格式和样式。
为什么我应该使用IronXL来导出 GridView 数据?
IronXL通过其直观的 API 简化了导出 GridView 数据的过程,让您可以轻松保持格式并应用样式,而这在传统方法中可能具有挑战性。
IronXL在将GridView导出到Excel时是否支持格式设置?
是的, IronXL支持多种格式设置选项,包括字体、颜色和单元格样式,确保您导出的 Excel 文件看起来专业,并保持预期的设计。
我可以自定义从 GridView 数据生成的 Excel 文件的外观吗?
IronXL为 Excel 文件提供了一系列自定义选项,允许您在从 GridView 导出时调整单元格样式、字体、颜色等,以满足您的特定要求。
是否可以使用IronXL将大型 GridView 数据集导出到 Excel?
IronXL能够高效地处理大型数据集,确保您可以将大量的 GridView 数据导出到 Excel 而不会出现性能问题。
与使用其他方法相比,使用IronXL将 GridView 数据导出到 Excel 有哪些优势?
IronXL提供了一种更精简、更灵活的导出 GridView 数据的方法,对格式化、自定义和处理大型数据集提供了强大的支持,使其优于许多其他方法。
将 GridView 导出到 Excel 时如何保持数据完整性?
IronXL通过在从 GridView 导出到 Excel 的过程中准确转换和保留数据类型和格式来确保数据完整性。
IronXL能否从具有复杂结构的 GridView 控件中导出数据?
是的, IronXL可以有效地处理和导出具有复杂结构的 GridView 控件中的数据,并在生成的 Excel 文件中保持层次结构和格式。
IronXL可以将GridView数据导出为哪些文件格式?
IronXL主要将数据导出为 Excel 格式(如 XLSX),但也支持其他格式(如 CSV),可根据您的需要提供灵活性。
IronXL是否支持导出带有条件格式的GridView?
IronXL支持条件格式设置,允许您设置规则和样式,以便在将 GridView 数据导出到 Excel 时根据单元格值动态调整。


