在当今数据驱动的商业环境中,数据透视表是Excel中最强大的数据分析工具之一。它能够快速将大量复杂的数据转换为清晰、易于理解的汇总报表,帮助分析师和决策者从不同维度洞察数据趋势和规律。通过数据透视表,用户可以轻松地进行数据的汇总、筛选、排序和比较,而无需编写复杂的公式。
传统的手工创建数据透视表过程繁琐,尤其是当需要定期生成相同格式的报表时,重复劳动会大大降低工作效率。这时,.NET操作Excel COM组件的优势就凸显出来了。通过编程方式自动化创建数据透视表,不仅能够节省大量时间,还能确保报表格式的一致性和数据的准确性。
本文将基于MudTools.OfficeInterop.Excel组件,手把手教你如何使用C#实现Excel数据透视表的自动化创建。从环境准备到实战案例,我们将全面覆盖数据透视表开发的所有关键知识点,帮助你快速掌握这一实用技能。
环境准备与基础概念
技术栈介绍
.NET与Excel互操作基础
.NET与Excel的互操作主要基于Microsoft提供的COM组件接口。通过这些接口,.NET应用程序可以控制Excel应用程序、访问工作簿、工作表、单元格等对象,并执行各种操作。这种方式的优点是功能完整,可以实现Excel的所有功能;缺点是需要安装Excel应用程序,并且需要注意COM对象的资源释放问题。
MudTools.OfficeInterop.Excel组件
MudTools.OfficeInterop.Excel是一个专门用于操作Microsoft Excel应用程序的.NET封装库,它对底层COM接口进行了二次封装,提供了更简洁、更安全的API接口。该组件的主要特点包括:
- 完整的对象模型封装:涵盖Excel应用程序、工作簿、工作表、单元格、图表、数据透视表等所有核心对象
- 自动资源管理:通过IDisposable接口和using语句,自动管理COM对象生命周期
- 类型安全:提供强类型接口,减少运行时错误
- 易于使用:简化了常见的操作流程,提高开发效率
支持框架:
- .NET Framework 4.6.2+
- .NET Standard 2.1
- .NET 6.0-windows 及更高版本
安装方式:- [/code][size=4]开发环境配置[/size]
- [size=3]系统要求[/size]
- [list]
- [*]操作系统:Windows 7 及以上版本
- [*]Microsoft Office Excel 2016 或更高版本(推荐使用Office 365)
- [*].NET Framework 或 .NET SDK 根据项目需求选择
- [/list][size=3]Visual Studio 项目配置[/size]
- [list=1]
- [*][b]创建项目[/b]
- [/list]创建一个控制台应用程序或类库项目(.NET Framework或.NET 6+)。
- [list=1]
- [*][b]添加NuGet包引用[/b]
- [/list]通过NuGet包管理器控制台或图形界面安装MudTools.OfficeInterop.Excel:
- [code]Install-Package MudTools.OfficeInterop.Excel
复制代码 或者通过Visual Studio的NuGet包管理器搜索并安装。
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>net8.0-windows</TargetFramework>
- <UseWindowsForms>true</UseWindowsForms>
- </PropertyGroup>
- <ItemGroup>
- <PackageReference Include="MudTools.OfficeInterop.Excel" Version="1.1.8" />
- </ItemGroup>
- </Project>
复制代码 注意事项:Excel版本兼容性
在进行Excel COM互操作时,需要特别注意版本兼容性问题:
Excel版本PIA库版本推荐使用场景Excel 2016Microsoft.Office.Interop.Excel 15.0较老系统,兼容性好Excel 2019Microsoft.Office.Interop.Excel 16.0当前主流版本Office 365Microsoft.Office.Interop.Excel 16.0+最新功能支持最佳实践建议:
- 开发和部署环境使用相同版本的Excel
- 在代码中添加版本检测逻辑,适配不同Excel版本
- 使用MudTools.OfficeInterop.Excel组件时,无需直接操作PIA库,版本兼容性问题由组件内部处理
Excel COM组件基础操作
应用程序对象模型概览
MudTools.OfficeInterop.Excel组件将Excel的对象模型封装成清晰的层次结构,理解这个层次对于高效操作Excel至关重要。
graph TD A[IExcelApplication] --> B[IExcelWorkbooks] B --> C[IExcelWorkbook] C --> D[IExcelWorksheets] D --> E[IExcelWorksheet] E --> F[IExcelRange] E --> G[IExcelPivotTables] G --> H[IExcelPivotTable] E --> I[IExcelCharts] I --> J[IExcelChart]核心对象说明
接口说明常用方法/属性IExcelApplicationExcel应用程序实例Visible, Quit, Workbooks, WorksheetsIExcelWorkbook工作簿对象SaveAs, Close, Worksheets, NameIExcelWorksheet工作表对象Range, Name, Cells, PivotTablesIExcelRange单元格或单元格区域Value, Formula, NumberFormat, AutoFitIExcelPivotTable数据透视表对象PivotFields, AddDataField, RefreshTable基本文件操作
创建/打开工作簿
创建新的空白工作簿:- using MudTools.OfficeInterop.Excel;
- // 创建Excel应用程序实例
- using var app = ExcelFactory.BlankWorkbook();
- // 获取活动工作簿和工作表
- var workbook = app.ActiveWorkbook;
- var worksheet = workbook.ActiveSheetWrap;
- worksheet.Name = "数据源";
- // 设置Excel可见性(可选)
- app.Visible = true;
复制代码 从模板创建工作簿:- // 基于模板创建工作簿
- using var app = ExcelFactory.CreateFrom(@"C:\Templates\ReportTemplate.xltx");
- var worksheet = app.ActiveSheetWrap;
复制代码 打开现有工作簿:- // 打开现有的Excel文件
- using var app = ExcelFactory.Open(@"C:\Data\SalesData.xlsx");
- var worksheet = app.Worksheets[1]; // 获取第一个工作表
复制代码 数据写入与格式设置
- // 写入数据到单元格
- worksheet.Range("A1").Value = "产品类别";
- worksheet.Range("B1").Value = "产品名称";
- worksheet.Range("C1").Value = "销售地区";
- worksheet.Range("D1").Value = "销售数量";
- worksheet.Range("E1").Value = "销售金额";
- // 批量写入数据(二维数组)
- object[,] salesData = {
- {"电子产品", "笔记本电脑", "北京", 10, 50000},
- {"电子产品", "台式电脑", "上海", 8, 32000},
- {"家居用品", "沙发", "广州", 5, 15000},
- {"服装", "T恤", "深圳", 50, 2500}
- };
- var dataRange = worksheet.Range("A2:E5");
- dataRange.Value = salesData;
- // 设置单元格格式
- dataRange.NumberFormat = "#,##0"; // 数字格式
- worksheet.Range("A1:E1").Font.Bold = true; // 标题加粗
- // 自动调整列宽
- worksheet.Columns.AutoFit();
复制代码 保存与退出时的资源清理
保存工作簿:- // 保存为指定文件名
- workbook.SaveAs(@"C:\Output\SalesReport.xlsx");
- // 或者保存当前工作簿
- workbook.Save();
复制代码 退出Excel应用程序:- // 使用using语句自动释放资源
- using var app = ExcelFactory.BlankWorkbook();
- // ... 执行操作 ...
- // app.Dispose() 会在using块结束时自动调用
复制代码 手动资源释放:- try
- {
- var app = ExcelFactory.CreateApplication();
- // ... 执行操作 ...
- app.Quit();
- app.Dispose();
- }
- catch (Exception ex)
- {
- Console.WriteLine($"操作失败: {ex.Message}");
- }
复制代码 数据透视表核心实现
数据准备阶段
构建源数据表的最佳实践
数据透视表的质量很大程度上取决于源数据的质量。良好的数据结构应该遵循以下原则:
数据结构要求:
要求说明示例标题行每列必须有唯一的列标题作为字段名称日期、产品类别、销售地区连续数据数据区域应该是连续的,中间不能有空行或空列从A1开始连续填充数据类型一致同一列的数据类型应该保持一致数值列全部为数字无合并单元格避免在数据区域使用合并单元格单元格独立示例源数据结构:- // 创建规范的销售数据源
- worksheet.Range("A1").Value = "日期";
- worksheet.Range("B1").Value = "产品类别";
- worksheet.Range("C1").Value = "产品名称";
- worksheet.Range("D1").Value = "销售地区";
- worksheet.Range("E1").Value = "销售人员";
- worksheet.Range("F1").Value = "销售数量";
- worksheet.Range("G1").Value = "单价";
- worksheet.Range("H1").Value = "销售金额";
- object[,] salesData = {
- {"2023-01-01", "电子产品", "笔记本电脑", "北京", "张三", 2, 5000, 10000},
- {"2023-01-02", "电子产品", "台式电脑", "上海", "李四", 1, 4000, 4000},
- {"2023-01-03", "家居用品", "沙发", "广州", "王五", 1, 3000, 3000},
- {"2023-01-04", "服装", "T恤", "深圳", "赵六", 10, 50, 500},
- // ... 更多数据 ...
- };
- var dataRange = worksheet.Range("A2:H16");
- dataRange.Value = salesData;
复制代码 命名区域的定义与使用
命名区域可以提高代码的可读性和可维护性:- // 为数据源区域创建命名区域
- workbook.Names.Add("SalesDataSource", worksheet.Range("A1:H16"));
- // 在创建数据透视表时使用命名区域
- var sourceRange = worksheet.Range("SalesDataSource");
复制代码 数据验证与清洗
- // 删除空行
- var usedRange = worksheet.UsedRange;
- for (int i = usedRange.Rows.Count; i >= 2; i--)
- {
- var row = usedRange.Rows[i];
- bool isEmpty = true;
- foreach (var cell in row.Cells)
- {
- if (cell.Value != null && !string.IsNullOrEmpty(cell.Value.ToString()))
- {
- isEmpty = false;
- break;
- }
- }
- if (isEmpty)
- {
- row.Delete();
- }
- }
- // 检查数据完整性
- var dataRange = worksheet.Range("A2:H16");
- foreach (var row in dataRange.Rows)
- {
- // 验证关键字段是否为空
- if (row.Cells[1].Value == null) // 检查日期列
- {
- Console.WriteLine($"警告: 第{row.Row}行日期为空");
- }
- }
复制代码 创建透视表步骤详解
MudTools.OfficeInterop.Excel提供了两种创建数据透视表的方式:
方式一:使用PivotCache创建(推荐)
- // 步骤1:创建数据透视表缓存
- var pivotCache = workbook.PivotCaches().Create(
- XlPivotTableSourceType.xlConsolidation,
- sourceWorksheet.Range("A1:H33").GetAddress(external: true)
- );
- // 步骤2:在工作表中添加数据透视表
- var pivotWorksheet = workbook.Worksheets.Add() as IExcelWorksheet;
- pivotWorksheet.Name = "销售透视表";
- var pivotTable = pivotWorksheet.PivotTables().Add(
- pivotCache,
- pivotWorksheet.Range("A1"),
- "销售分析透视表"
- );
复制代码 方式二:使用PivotTableWizard创建
- var pivotTable = pivotWorksheet.PivotTableWizard(
- sourceType: XlPivotTableSourceType.xlConsolidation,
- sourceData: sourceWorksheet.Range("A1:H16"),
- tableDestination: pivotWorksheet.Range("A1"),
- tableName: "销售分析透视表",
- rowGrand: true,
- columnGrand: true
- );
复制代码 两种方式对比:
创建方式优点缺点适用场景PivotCache灵活性高,可复用缓存创建多个透视表需要更多代码步骤需要创建多个透视表或复杂配置PivotTableWizard代码简洁,一次性完成配置参数较多,灵活性稍弱快速创建单个透视表字段配置与布局
行字段、列字段的添加与排序
- // 添加行字段 - 产品类别
- var categoryField = pivotTable.PivotFields("产品类别");
- categoryField.Orientation = XlPivotFieldOrientation.xlRowField;
- categoryField.Position = 1; // 设置为第一个行字段
- // 添加行字段 - 产品名称
- var productField = pivotTable.PivotFields("产品名称");
- productField.Orientation = XlPivotFieldOrientation.xlRowField;
- productField.Position = 2; // 设置为第二个行字段
- // 添加列字段 - 销售地区
- var regionField = pivotTable.PivotFields("销售地区");
- regionField.Orientation = XlPivotFieldOrientation.xlColumnField;
- regionField.Position = 1;
复制代码 值字段的汇总方式
- // 添加值字段 - 销售金额(求和)
- var sumField = pivotTable.PivotFields("销售金额");
- sumField.Orientation = XlPivotFieldOrientation.xlDataField;
- sumField.Function = XlConsolidationFunction.xlSum;
- sumField.Name = "销售金额合计";
- // 添加值字段 - 销售数量(计数)
- var countField = pivotTable.PivotFields("销售数量");
- countField.Orientation = XlPivotFieldOrientation.xlDataField;
- countField.Function = XlConsolidationFunction.xlCount;
- countField.Name = "销售次数";
- // 添加值字段 - 单价(平均值)
- var avgField = pivotTable.PivotFields("单价");
- avgField.Orientation = XlPivotFieldOrientation.xlDataField;
- avgField.Function = XlConsolidationFunction.xlAverage;
- avgField.Name = "平均单价";
复制代码 支持的汇总函数:
函数枚举值说明求和xlSum数值字段的默认汇总方式计数xlCount统计记录数量平均值xlAverage计算算术平均值最大值xlMax找出最大值最小值xlMin找出最小值乘积xlProduct计算乘积标准差xlStDev计算样本标准差总体标准差xlStDevP计算总体标准差方差xlVar计算样本方差总体方差xlVarP计算总体方差筛选字段的应用
- // 添加页字段(筛选器)- 日期
- var dateField = pivotTable.PivotFields("日期");
- dateField.Orientation = XlPivotFieldOrientation.xlPageField;
- // 添加页字段 - 年份
- var yearField = pivotTable.PivotFields("年份");
- yearField.Orientation = XlPivotFieldOrientation.xlPageField;
复制代码 字段分组设置(日期、数字分组)
- // 对日期字段进行分组
- var dateField = pivotTable.PivotFields("日期");
- dateField.Orientation = XlPivotFieldOrientation.xlRowField;
- // 创建年月日分组
- var pivotItems = dateField.PivotItems;
- // 按年分组
- dateField.DataRange.Group(
- By: 7, // 按年分组
- Periods: new object[] { true, true, true, false, false, false, false }
- // 年、月、日、季度、小时、分钟、秒
- );
- // 对数值字段进行分组
- var priceField = pivotTable.PivotFields("单价");
- priceField.Orientation = XlPivotFieldOrientation.xlRowField;
- // 按价格区间分组:0-1000, 1000-3000, 3000-5000, 5000+
- priceField.DataRange.Group(
- From: 0,
- To: 5000,
- By: 1000
- );
复制代码 高级功能与定制化
样式与格式优化
应用内置透视表样式
- // 应用内置透视表样式
- pivotTable.TableStyle = "PivotStyleMedium9"; // 中等样式9
- // 显示行条纹和列条纹
- pivotTable.ShowTableStyleRowStripes = true;
- pivotTable.ShowTableStyleColumnStripes = true;
- // 显示首列和末列的特殊样式
- pivotTable.ShowTableStyleColumnHeaders = true;
- pivotTable.ShowTableStyleRowHeaders = true;
复制代码 常用透视表样式:
样式名称样式风格适用场景PivotStyleLight1 - PivotStyleLight28浅色系,简洁简洁报表,黑白打印PivotStyleMedium1 - PivotStyleMedium28中等色彩,平衡日常业务报表PivotStyleDark1 - PivotStyleDark28深色系,醒目演示文稿,强调重点自定义数字格式
- // 设置值字段的数字格式
- var sumField = pivotTable.PivotFields("销售金额合计");
- sumField.NumberFormat = "#,##0.00"; // 千分位,保留两位小数
- // 设置百分比格式
- var percentField = pivotTable.PivotFields("占比");
- percentField.NumberFormat = "0.00%";
- // 设置货币格式
- var currencyField = pivotTable.PivotFields("收入");
- currencyField.NumberFormat = "¥#,##0.00";
复制代码 条件格式在透视表中的使用
- // 获取数据透视表的数据区域
- var dataRange = pivotTable.DataBodyRange;
- // 应用条件格式 - 高亮显示大于10000的销售额
- var formatRule = dataRange.FormatConditions.Add(
- Type: XlFormatConditionType.xlCellValue,
- Operator: XlFormatConditionOperator.xlGreater,
- Formula1: "10000"
- );
- formatRule.Interior.Color = ColorTranslator.ToOle(Color.LightGreen);
- // 应用数据条格式
- var dataBarRule = dataRange.FormatConditions.AddDatabarRule(
- MinType: XlConditionValueTypes.xlConditionValueNumber,
- MaxType: XlConditionValueTypes.xlConditionValueNumber,
- MinValue: 0,
- MaxValue: 50000
- );
- dataBarRule.BarColor.Color = ColorTranslator.ToOle(Color.Blue);
复制代码 数据透视表选项配置
更新刷新策略
- // 设置为手动更新(提高大数据量处理性能)
- pivotTable.ManualUpdate = true;
- // 执行多项操作
- // ... 配置字段 ...
- // 最后刷新数据透视表
- pivotTable.RefreshTable();
- // 恢复自动更新
- pivotTable.ManualUpdate = false;
复制代码 空值处理
- // 设置空值显示的文本
- pivotTable.NullString = "-";
- // 设置错误值显示的文本
- pivotTable.ErrorString = "N/A";
- // 显示/隐藏空字符串
- pivotTable.DisplayNullString = true;
- pivotTable.DisplayErrorString = true;
复制代码 总计与小计控制
- // 显示行总计和列总计
- pivotTable.RowGrand = true; // 显示行总计
- pivotTable.ColumnGrand = true; // 显示列总计
- // 自定义总计名称
- pivotTable.GrandTotalName = "总计";
- // 设置小计位置
- pivotTable.SubtotalLocation(XlSubtototalLocationType.xlAtTop); // 小计在顶部
- // 为特定字段设置小计
- var categoryField = pivotTable.PivotFields("产品类别");
- categoryField.Subtotals = new object[] { true, false, false, false, false, false, false, false, false, false, false, false };
- // 第一个true表示显示默认小计,其他参数对应不同的汇总函数
复制代码 动态数据范围处理
使用表格对象(ListObject)作为动态源
- // 将数据区域转换为Excel表格(ListObject)
- var listObject = worksheet.ListObjects.Add(
- SourceType: XlListObjectSourceType.xlSrcRange,
- Source: worksheet.Range("A1:H16"),
- XlListObjectHasHeaders: XlYesNoGuess.xlYes
- );
- listObject.Name = "销售数据表";
- // 使用表格作为数据透视表的数据源
- var pivotCache = workbook.PivotCaches().Create(
- XlPivotTableSourceType.xlDatabase,
- "销售数据表"
- );
- // 当表格数据增加时,数据透视表数据源会自动更新
复制代码 处理数据增删时的范围调整
- // 动态确定数据源范围
- var lastRow = worksheet.Cells[worksheet.Rows.Count, 1].End(XlDirection.xlUp).Row;
- var lastColumn = worksheet.Cells[1, worksheet.Columns.Count].End(XlDirection.xlToLeft).Column;
- var sourceRange = worksheet.Range(worksheet.Cells[1, 1], worksheet.Cells[lastRow, lastColumn]);
- // 更新数据透视表的数据源
- var pivotCache = pivotTable.PivotCache();
- pivotCache.SourceData = sourceRange.Address;
- pivotTable.RefreshTable();
复制代码- // 另一种方式:使用命名区域的动态引用
- workbook.Names.Add("DynamicDataSource",
- "=OFFSET(源数据!$A$1,0,0,COUNTA(源数据!$A:$A),COUNTA(源数据!$1:$1))"
- );
- // 使用动态命名区域创建数据透视表
- var pivotCache = workbook.PivotCaches().Create(
- XlPivotTableSourceType.xlDatabase,
- "DynamicDataSource"
- );
复制代码 实战案例:销售数据分析报表
场景描述
假设我们需要创建一个销售数据分析报表,用于分析公司2023年的销售情况。数据包含以下字段:
- 日期:销售日期
- 产品类别:如电子产品、家居用品、服装等
- 产品名称:具体的产品名称
- 销售地区:北京、上海、广州、深圳
- 销售人员:销售人员姓名
- 销售数量:销售的数量
- 单价:产品单价
- 销售金额:销售总额
分析需求:
- 按产品类别和产品名称统计销售情况
- 按销售地区分析销售额分布
- 按时间段(月度)分析销售趋势
- 计算各类产品的销售占比
- 展示销售人员的业绩排名
完整代码实现
[code]using MudTools.OfficeInterop.Excel;using System;namespace SalesReportGenerator{ class Program { static void Main(string[] args) { Console.WriteLine("开始生成销售数据分析报表..."); try { // ========== 1. 初始化Excel应用 ========== using var excelApp = ExcelFactory.BlankWorkbook(); var workbook = excelApp.ActiveWorkbook; excelApp.Visible = true; // ========== 2. 导入/生成源数据 ========== var sourceWorksheet = workbook.ActiveSheetWrap; sourceWorksheet.Name = "源数据"; // 创建表头 sourceWorksheet.Range("A1").Value = "日期"; sourceWorksheet.Range("B1").Value = "产品类别"; sourceWorksheet.Range("C1").Value = "产品名称"; sourceWorksheet.Range("D1").Value = "销售地区"; sourceWorksheet.Range("E1").Value = "销售人员"; sourceWorksheet.Range("F1").Value = "销售数量"; sourceWorksheet.Range("G1").Value = "单价"; sourceWorksheet.Range("H1").Value = "销售金额"; // 格式化表头 var headerRange = sourceWorksheet.Range("A1:H1"); headerRange.Font.Bold = true; headerRange.Interior.Color = 0x4472C4; // 蓝色背景 headerRange.Font.Color = 0xFFFFFF; // 白色文字 // 准备销售数据 object[,] salesData = { {"2023-01-05", "电子产品", "笔记本电脑", "北京", "张三", 2, 5000, 10000}, {"2023-01-08", "电子产品", "手机", "北京", "张三", 3, 2000, 6000}, {"2023-01-10", "电子产品", "平板电脑", "北京", "张三", 2, 1500, 3000}, {"2023-01-12", "家居用品", "沙发", "北京", "张三", 1, 3000, 3000}, {"2023-01-15", "服装", "T恤", "北京", "张三", 10, 50, 500}, {"2023-02-05", "电子产品", "笔记本电脑", "上海", "李四", 1, 5000, 5000}, {"2023-02-08", "电子产品", "手机", "上海", "李四", 2, 2000, 4000}, {"2023-02-10", "家居用品", "床", "上海", "李四", 1, 2000, 2000}, {"2023-02-15", "服装", "牛仔裤", "上海", "李四", 5, 100, 500}, {"2023-03-05", "电子产品", "笔记本电脑", "广州", "王五", 2, 5000, 10000}, {"2023-03-08", "电子产品", "台式电脑", "广州", "王五", 2, 4000, 8000}, {"2023-03-12", "家居用品", "餐桌", "广州", "王五", 1, 1000, 1000}, {"2023-03-15", "服装", "外套", "广州", "王五", 3, 300, 900}, {"2023-04-05", "电子产品", "手机", "深圳", "赵六", 3, 2000, 6000}, {"2023-04-10", "电子产品", "平板电脑", "深圳", "赵六", 2, 1500, 3000}, {"2023-04-15", "家居用品", "衣柜", "深圳", "赵六", 1, 3000, 3000}, {"2023-04-20", "服装", "连衣裙", "深圳", "赵六", 4, 200, 800}, {"2023-05-08", "电子产品", "笔记本电脑", "北京", "张三", 1, 5000, 5000}, {"2023-05-12", "家居用品", "沙发", "北京", "张三", 2, 3000, 6000}, {"2023-06-05", "电子产品", "手机", "上海", "李四", 4, 2000, 8000}, {"2023-06-10", "服装", "T恤", "上海", "李四", 15, 50, 750}, {"2023-07-08", "电子产品", "台式电脑", "广州", "王五", 1, 4000, 4000}, {"2023-07-15", "家居用品", "床", "广州", "王五", 2, 2000, 4000}, {"2023-08-05", "电子产品", "笔记本电脑", "深圳", "赵六", 2, 5000, 10000}, {"2023-08-10", "服装", "外套", "深圳", "赵六", 5, 300, 1500}, {"2023-09-08", "电子产品", "平板电脑", "北京", "张三", 3, 1500, 4500}, {"2023-09-15", "家居用品", "餐桌", "北京", "张三", 2, 1000, 2000}, {"2023-10-05", "电子产品", "手机", "上海", "李四", 2, 2000, 4000}, {"2023-10-12", "服装", "牛仔裤", "上海", "李四", 8, 100, 800}, {"2023-11-08", "电子产品", "笔记本电脑", "广州", "王五", 3, 5000, 15000}, {"2023-11-15", "家居用品", "沙发", "广州", "王五", 1, 3000, 3000}, {"2023-12-05", "电子产品", "台式电脑", "深圳", "赵六", 2, 4000, 8000}, {"2023-12-10", "服装", "连衣裙", "深圳", "赵六", 6, 200, 1200} }; // 写入数据 var dataRange = sourceWorksheet.Range("A2:H33"); dataRange.Value = salesData; // 设置数字格式 sourceWorksheet.Range("F2:F33").NumberFormat = "#,##0"; sourceWorksheet.Range("G2:G33").NumberFormat = "#,##0.00"; sourceWorksheet.Range("H2:H33").NumberFormat = "#,##0.00"; // 自动调整列宽 sourceWorksheet.Columns.AutoFit(); // ========== 3. 创建产品销售透视表 ========== var productPivotSheet = workbook.Worksheets.Add() as IExcelWorksheet; productPivotSheet.Name = "产品销售分析"; var pivotCache = workbook.PivotCaches().Create( XlPivotTableSourceType.xlConsolidation, sourceWorksheet.Range("A1:H33").GetAddress(external: true) ); var productPivot = productPivotSheet.PivotTables().Add( pivotCache, productPivotSheet.Range("A1"), "产品销售透视表" ); // 配置字段 productPivot.PivotFields("产品类别").Orientation = XlPivotFieldOrientation.xlRowField; productPivot.PivotFields("产品类别").Position = 1; productPivot.PivotFields("产品名称").Orientation = XlPivotFieldOrientation.xlRowField; productPivot.PivotFields("产品名称").Position = 2; productPivot.PivotFields("销售地区").Orientation = XlPivotFieldOrientation.xlColumnField; // 添加销售金额汇总 var amountField = productPivot.PivotFields("销售金额"); amountField.Orientation = XlPivotFieldOrientation.xlDataField; amountField.Function = XlConsolidationFunction.xlSum; amountField.Name = "销售金额"; amountField.NumberFormat = "#,##0.00"; // 添加销售数量统计 var qtyField = productPivot.PivotFields("销售数量"); qtyField.Orientation = XlPivotFieldOrientation.xlDataField; qtyField.Function = XlConsolidationFunction.xlSum; qtyField.Name = "销售数量"; qtyField.NumberFormat = "#,##0"; // 添加平均单价 var avgPriceField = productPivot.PivotFields("单价"); avgPriceField.Orientation = XlPivotFieldOrientation.xlDataField; avgPriceField.Function = XlConsolidationFunction.xlAverage; avgPriceField.Name = "平均单价"; avgPriceField.NumberFormat = "#,##0.00"; // 设置透视表选项 productPivot.RowGrand = true; productPivot.ColumnGrand = true; productPivot.HasAutoFormat = true; // 应用样式 productPivot.TableStyle = " ivotStyleMedium9"; productPivot.ShowTableStyleRowStripes = true; productPivot.ShowTableStyleColumnStripes = true; productPivotSheet.Columns.AutoFit(); // ========== 4. 创建地区销售透视表 ========== var regionPivotSheet = workbook.Worksheets.Add() as IExcelWorksheet; regionPivotSheet.Name = "地区销售分析"; var regionPivot = regionPivotSheet.PivotTables().Add( pivotCache, regionPivotSheet.Range("A1"), "地区销售透视表" ); // 配置字段 regionPivot.PivotFields("销售地区").Orientation = XlPivotFieldOrientation.xlRowField; regionPivot.PivotFields("产品类别").Orientation = XlPivotFieldOrientation.xlColumnField; // 添加销售金额和数量 var regionAmountField = regionPivot.PivotFields("销售金额"); regionAmountField.Orientation = XlPivotFieldOrientation.xlDataField; regionAmountField.Function = XlConsolidationFunction.xlSum; regionAmountField.Name = "销售金额"; regionAmountField.NumberFormat = "#,##0.00"; var regionQtyField = regionPivot.PivotFields("销售数量"); regionQtyField.Orientation = XlPivotFieldOrientation.xlDataField; regionQtyField.Function = XlConsolidationFunction.xlSum; regionQtyField.Name = "销售数量"; // 按销售金额降序排列 regionPivot.PivotFields("销售地区").AutoSort( XlSortOrder.xlDescending, "销售金额" ); regionPivot.RowGrand = true; regionPivot.ColumnGrand = true; regionPivot.TableStyle = " ivotStyleMedium14"; regionPivot.ShowTableStyleRowStripes = true; regionPivotSheet.Columns.AutoFit(); // ========== 5. 创建销售人员业绩透视表 ========== var salespersonPivotSheet = workbook.Worksheets.Add() as IExcelWorksheet; salespersonPivotSheet.Name = "销售人员业绩"; var salespersonPivot = salespersonPivotSheet.PivotTables().Add( pivotCache, salespersonPivotSheet.Range("A1"), "销售人员业绩透视表" ); // 配置字段 salespersonPivot.PivotFields("销售人员").Orientation = XlPivotFieldOrientation.xlRowField; salespersonPivot.PivotFields("产品类别").Orientation = XlPivotFieldOrientation.xlColumnField; var spAmountField = salespersonPivot.PivotFields("销售金额"); spAmountField.Orientation = XlPivotFieldOrientation.xlDataField; spAmountField.Function = XlConsolidationFunction.xlSum; spAmountField.Name = "销售金额"; spAmountField.NumberFormat = "#,##0.00"; var spOrderCountField = salespersonPivot.PivotFields("销售数量"); spOrderCountField.Orientation = XlPivotFieldOrientation.xlDataField; spOrderCountField.Function = XlConsolidationFunction.xlSum; spOrderCountField.Name = "订单数量"; // 按销售金额降序排列 salespersonPivot.PivotFields("销售人员").AutoSort( XlSortOrder.xlDescending, "销售金额" ); salespersonPivot.RowGrand = true; salespersonPivot.ColumnGrand = true; salespersonPivot.TableStyle = " ivotStyleMedium19"; salespersonPivotSheet.Columns.AutoFit(); // ========== 6. 创建月度销售趋势透视表 ========== var monthlyPivotSheet = workbook.Worksheets.Add() as IExcelWorksheet; monthlyPivotSheet.Name = "月度销售趋势"; // 添加月度列到源数据 sourceWorksheet.Range("I1").Value = "月份"; for (int row = 2; row |