C# WPF如何导出非DataTable、非DataGrid的原生Table到CSV?
WPF原生Table控件导出CSV实现方案
WPF 中System.Windows.Documents.Table是流式文档体系下的原生表格控件,本身没有内置导出接口,可通过逐层遍历结构提取内容实现导出,具体方案如下:
实现思路
- 逐层遍历Table结构:优先遍历所有TableRowGroup,再遍历每个行组下的TableRow,最后遍历每行的TableCell
- 提取单元格文本:将TableCell内的所有块内容拼接为纯文本,自动处理多余空格、换行等无效格式
- 遵循CSV转义规则:内容包含逗号、双引号、换行符时,用双引号包裹整体内容,内容本身的双引号替换为两个连续双引号
- 按行拼接内容后写入本地文件,默认使用带BOM的UTF-8编码,适配Excel直接打开不出现乱码
依赖命名空间
using System.IO; using System.Text; using System.Windows.Documents; using System.Linq;
导出方法代码
/// <summary> /// 导出WPF原生Table为CSV文件 /// </summary> /// <param name="targetTable">待导出的Table控件实例</param> /// <param name="saveFullPath">导出文件的完整保存路径</param> public void ExportTableToCsv(Table targetTable, string saveFullPath) { StringBuilder csvBuilder = new StringBuilder(); // 遍历所有行组 foreach (TableRowGroup rowGroup in targetTable.RowGroups) { // 遍历行组内所有行 foreach (TableRow row in rowGroup.Rows) { List<string> currentRowContent = new List<string>(); // 遍历行内所有单元格 foreach (TableCell cell in row.Cells) { // 提取单元格内所有Paragraph的文本,可自行扩展支持List、Section等其他Block类型 string cellText = string.Join(" ", cell.Blocks.OfType<Paragraph>() .Select(p => p.Inlines.Text) .Where(t => !string.IsNullOrWhiteSpace(t))) .Trim(); // 处理CSV转义规则 if (cellText.Contains(',') || cellText.Contains('"') || cellText.Contains('\n') || cellText.Contains('\r')) { cellText = $"\"{cellText.Replace("\"", "\"\"")}\""; } currentRowContent.Add(cellText); } // 拼接当前行到CSV内容 csvBuilder.AppendLine(string.Join(",", currentRowContent)); } } // 写入本地文件 File.WriteAllText(saveFullPath, csvBuilder.ToString(), Encoding.UTF8); }
调用示例
假设XAML中定义的Table控件Name属性为customDocumentTable,导出到桌面的调用代码如下:
string savePath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Table导出结果.csv"); ExportTableToCsv(customDocumentTable, savePath);
特殊场景适配提示
- 单元格包含非文本内容(图片、按钮、自定义控件等):可根据业务需求自行扩展逻辑,选择忽略对应内容、或者替换为指定占位文本
- 存在跨行/跨列合并单元格:可遍历时记录单元格的ColumnSpan、RowSpan属性,在对应位置补空值或者标注合并属性
- 需要兼容老旧版Excel中文显示:可将写入编码替换为
Encoding.GetEncoding("GB2312"),注意需先安装NuGet包System.Text.Encoding.CodePages,并在程序启动时注册编码提供程序:Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - 单元格包含List、Section等非Paragraph块:可扩展文本提取逻辑,遍历所有Block类型匹配对应规则提取内容
内容的提问来源于stack exchange,提问作者Gautham_Samy
相关产品推荐
相关产品推荐

