把 XML 数据批量整理成 Excel,是很多 .NET 项目里很常见的一步:上游系统吐出半结构化数据,下游又希望拿到能直接筛选、统计、发给业务同事的表格。如果还在靠手工复制,不仅慢,而且一旦数据量变大或需要反复生成报表,出错概率会明显上升。下面就按“先看映射关系、再选库、最后落代码”的顺序,拆解一遍 C# 中 XML 转 Excel 的实现过程,方便你判断这套方案是否适合自己的项目。
先理清 XML 和 Excel 的映射关系
在动手写代码之前,先要确认 XML 里的层级结构,准备怎样落到 Excel 的行和列。一般来说:

- 一个记录节点,对应 Excel 的一行
- 节点属性或子元素,对应 Excel 的一列
- 文本内容,就是最终写入单元格的值
以一个简单的产品库存 XML 为例:
<Products>
<Product id="P001">
<Name>Laptop</Name>
<Category>Electronics</Category>
<Price>1200.00</Price>
<Stock>50</Stock>
</Product>
<Product id="P002">
<Name>Mouse</Name>
<Category>Electronics</Category>
<Price>25.00</Price>
<Stock>200</Stock>
</Product>
</Products>
这份数据映射到 Excel 后,可以整理成下面这种结构:
| 产品ID | 产品名称 | 类别 | 价格 | 库存 |
|---|---|---|---|---|
| P001 | Laptop | Electronics | 1200.00 | 50 |
| P002 | Mouse | Electronics | 25.00 | 200 |
这里的核心判断很直接:<Product> 对应一行,id、<Name>、<Category>、<Price>、<Stock> 对应列。这个映射关系一旦确定,后面的解析和写表就会顺很多。
为什么这里选 Spire.XLS for .NET
如果直接操作 Office COM 对象,部署和环境依赖会比较重;如果自己基于 Open XML SDK 逐层拼装,做简单导出还行,一旦要补格式、列宽、样式,代码复杂度会迅速上来。本文示例选择的是 Spire.XLS for .NET。
按原文给出的信息,这个库是独立的 Excel .NET 库,不要求机器安装 Microsoft Excel 或 Microsoft Office,可用于 .NET 2.0、.NET 3.5、.NET 4.0、.NET 4.0 ClientProfile、.NET 4.5 以及 .NET Core 环境,并支持用 C# 和 Visual Basic 创建、写入、编辑和保存 Excel 文件。
除了基础写表,它还能处理格式转换,以及常见的导入导出场景。对于“把 XML 解析后快速落到 `.xlsx` 文件”这种需求,API 也比较直接。
安装 Spire.XLS
在 Visual Studio 里可以直接通过 NuGet 安装,命令如下:
Install-Package Spire.XLS
安装完成后,就可以在项目中引用 Spire.Xls 命名空间。
C# 实现 XML 转 Excel 的完整步骤
下面按三个关键步骤来走:先加载 XML,再写入工作簿,最后保存为 XLSX。

步骤一:加载并解析 XML 数据
示例使用的是 XDocument。它属于 LINQ to XML,适合处理中小型 XML 数据,写法也比传统 XML API 更清晰。
using System;
using System.Xml.Linq;
using Spire.Xls; // 引入Spire.Xls命名空间
public class XmlToExcelConverter
{
public static void ConvertXmlToExcel(string xmlFilePath, string excelFilePath)
{
// 假设XML文件内容如上所示
string xmlContent = @"
<Products>
<Product id='P001'>
<Name>Laptop</Name>
<Category>Electronics</Category>
<Price>1200.00</Price>
<Stock>50</Stock>
</Product>
<Product id='P002'>
<Name>Mouse</Name>
<Category>Electronics</Category>
<Price>25.00</Price>
<Stock>200</Stock>
</Product>
</Products>";
XDocument doc;
try
{
// 从字符串加载XML,也可以使用 XDocument.Load(xmlFilePath) 从文件加载
doc = XDocument.Parse(xmlContent);
Console.WriteLine("XML数据加载成功。");
}
catch (Exception ex)
{
Console.WriteLine($"加载XML数据时发生错误: {ex.Message}");
return;
}
// ... 后续写入Excel的代码
}
}
这一步的重点不是“能不能读到 XML”,而是要先把异常处理放进去。因为一旦上游 XML 格式有问题,后面整条导出链路都会失败。
步骤二:创建工作簿并按列写入数据
解析出 XDocument 后,就可以创建工作簿、设置表头,然后遍历每个 Product 节点,逐行写入 Excel。
// ... 承接上一步的 ConvertXmlToExcel 方法
// 创建一个新的工作簿
Workbook workbook = new Workbook();
Worksheet sheet = workbook.Worksheets[0]; // 获取第一个工作表
// 设置列标题
sheet.Range["A1"].Text = "产品ID";
sheet.Range["B1"].Text = "产品名称";
sheet.Range["C1"].Text = "类别";
sheet.Range["D1"].Text = "价格";
sheet.Range["E1"].Text = "库存";
// 遍历XML数据并写入Excel
int row = 2; // 从第二行开始写入数据,第一行是标题
foreach (XElement product in doc.Descendants("Product"))
{
// 从XML节点提取数据
string productId = product.Attribute("id")?.Value;
string productName = product.Element("Name")?.Value;
string category = product.Element("Category")?.Value;
string price = product.Element("Price")?.Value;
string stock = product.Element("Stock")?.Value;
// 将数据写入Excel单元格
sheet.Range[$"A{row}"].Text = productId;
sheet.Range[$"B{row}"].Text = productName;
sheet.Range[$"C{row}"].Text = category;
// 尝试将价格和库存转换为数字类型,以便Excel正确处理
if (decimal.TryParse(price, out decimal dPrice))
{
sheet.Range[$"D{row}"].NumberValue = (double)dPrice;
}
else
{
sheet.Range[$"D{row}"].Text = price;
}
if (int.TryParse(stock, out int iStock))
{
sheet.Range[$"E{row}"].NumberValue = iStock;
}
else
{
sheet.Range[$"E{row}"].Text = stock;
}
row++;
}
// 自动调整列宽,使内容可见
sheet.AllocatedRange.AutoFitColumns();
// ... 后续保存Excel的代码
这里有两个细节值得注意:
product.Attribute("id")?.Value和product.Element("Name")?.Value这种写法,能在节点缺失时避免直接抛空引用异常。- 价格和库存没有直接统一当字符串写入,而是先尝试做
decimal.TryParse和int.TryParse。这样 Excel 打开后,数值列仍然是数值类型,后续排序、求和、筛选都更方便。
步骤三:保存为 XLSX 文件
数据填充完成后,最后一步就是保存文件,并释放资源。
// ... 承接上一步的代码
try
{
workbook.SaveToFile(excelFilePath, ExcelVersion.Version2016); // 保存为Excel 2016格式
Console.WriteLine($"Excel文件已成功保存到: {excelFilePath}");
}
catch (Exception ex)
{
Console.WriteLine($"保存Excel文件时发生错误: {ex.Message}");
}
finally
{
workbook.Dispose(); // 释放资源
}
}
public static void Main(string[] args)
{
string xmlFile = "products.xml"; // 实际应用中可以是文件路径
string excelFile = "ProductsReport.xlsx";
ConvertXmlToExcel(xmlFile, excelFile);
}
}
原文示例里这里的 SaveToFile 方法名出现了空格断裂,实际应为 workbook.SaveToFile(excelFilePath, ExcelVersion.Version2016);。保存格式指定为 ExcelVersion.Version2016,输出文件名示例为 ProductsReport.xlsx。
让生成的报表更易读:加一点基础样式
如果导出的 Excel 还要给业务或管理层直接查看,建议至少把表头做一下样式处理。哪怕只是加粗、底色和居中,也能让可读性明显提升。

// ... 在设置列标题之后,写入数据之前
// 设置标题行的样式
sheet.Range["A1:E1"].Style.Font.IsBold = true; // 加粗
sheet.Range["A1:E1"].Style.KnownColor = ExcelKnownColor.LightGreen; // 设置背景色
sheet.Range["A1:E1"].Style.HorizontalAlignment = HorizontalAlignType.Center; // 居中对齐
// ...
这部分虽然不影响导出逻辑,但很适合放在首版实现里一并完成,成本不高,效果却很直观。
这套做法适合什么场景,还能怎么扩展
按照上面的流程,你已经可以把结构相对规则的 XML 数据导出为可用的 Excel 报表。它比较适合下面几类场景:
- 上游接口或系统以 XML 作为交换格式
- 需要周期性导出库存、订单、日志或主数据报表
- 希望保留 Excel 的数值类型,便于后续统计分析
如果业务再复杂一些,还可以继续往下扩展,例如:
- 处理更深层的嵌套 XML 结构
- 按业务规则拆分多个工作表
- 增加单元格格式、边框、条件样式或图表
- 把 XML 来源从字符串切换成真实文件或接口返回内容
对多数 .NET 项目来说,这类需求难点不在“能不能生成 Excel”,而在于是否把映射关系、类型处理和异常路径都考虑完整。把这三部分先搭稳,后续扩展就会容易很多。













