Python在Excel中创建数据透视表的完整指南
作者:大丸子
在销售、财务、运营等业务场景中,按"区域 × 产品"、"季度 × 品类"等维度对明细数据进行交叉汇总,是日常报表里出现频率最高的需求。手动操作 Excel 插入数据透视表,再依次拖拽行字段、值字段、筛选字段,并设置汇总方式与样式,往往要花上好几分钟;数据一旦更新或维度调整,整套流程还要重做一次。当需要按月、按季把同一份透视规则套用到不同周期的明细表上时,重复成本会被迅速放大。
如果改用 Python 脚本读取销售明细并生成 Excel 报表,过程可以被自动化、可复用化,便于批量处理多份数据,也方便嵌入到定时任务里。常见做法是用 pandas.pivot_table 生成静态汇总表,再写回 Excel。这种做法简单直接,但生成的结果是普通单元格——没有透视表对象,也就不存在 Excel 中真正可点击展开/折叠、可点击下拉刷新、可在字段列表里勾选维度的"原生透视表"。
本文将使用 Free Spire.XLS for Python 在 Excel 工作簿中创建一份真正可交互的原生 Excel 数据透视表(PivotTable)——既保留 Python 自动化的效率,又能在 Excel/WPS 中以熟悉的透视表方式查看与分析。下面会从环境准备开始,依次演示:写入销售明细 → 创建带多行字段、双数据字段与内置样式的透视表 → 修改汇总方式与百分比显示 → 控制行/列总计与空值显示 → 明细展开/折叠与刷新设置。
1. 环境准备与库安装
本文使用 Free Spire.XLS for Python 作为驱动库,安装命令如下:
pip install spire.xls.free
该库支持创建、修改、刷新 Excel 数据透视表对象,保存后的 .xlsx 用 Excel/WPS 打开后即为可交互透视表。
安装完成后,先准备销售明细数据(脚本会同时创建数据工作表与透视表工作表):
from spire.xls import *
from spire.xls.common import *
# 创建一个新的工作簿
workbook = Workbook()
sheet = workbook.Worksheets[0]
sheet.Name = "销售明细"
# 写入表头
headers = ["区域", "产品", "季度", "销售额", "订单数"]
for col, header in enumerate(headers, start=1):
sheet.Range[1, col].Value = header
# 写入示例数据(区域、产品、季度、销售额、订单数)
sales_data = [
["华东", "激光打印机", "Q1", 182000, 42],
["华东", "激光打印机", "Q2", 154000, 35],
["华东", "扫描仪", "Q1", 96000, 28],
["华东", "投影仪", "Q1", 128000, 19],
["华北", "激光打印机", "Q1", 145000, 33],
["华北", "扫描仪", "Q2", 88000, 24],
["华北", "投影仪", "Q2", 117000, 17],
["华南", "激光打印机", "Q2", 166000, 38],
["华南", "扫描仪", "Q1", 79000, 21],
["华南", "投影仪", "Q1", 138000, 20],
["西南", "激光打印机", "Q2", 102000, 26],
["西南", "扫描仪", "Q2", 61000, 15],
["西南", "投影仪", "Q1", 86000, 12],
]
for row, data in enumerate(sales_data, start=2):
for col, value in enumerate(data, start=1):
if isinstance(value, (int, float)):
sheet.Range[row, col].NumberValue = value
else:
sheet.Range[row, col].Value = value说明:
Workbook()默认包含 3 个工作表;这里将第一个工作表命名为销售明细并写入数据,作为后续透视表的数据源。- 数值字段用
NumberValue写入,文本字段用Value写入,二者均来自 Spire.XLS 的官方写入 API。 - 销售明细共 13 条,覆盖 4 个区域、3 类产品、2 个季度,足以演示多层级汇总。
2. 创建基础数据透视表
在销售明细的基础上,添加一个数据透视表工作表,把"区域"与"产品"作为行字段,把"销售额"与"订单数"分别作为求和汇总的数据字段。
# 基于 A1:E14 区域创建透视缓存
dataRange = sheet.Range["A1:E14"]
cache = workbook.PivotCaches.Add(dataRange)
# 新建工作表用于存放透视表
sheet2 = workbook.CreateEmptySheet()
sheet2.Name = "数据透视表"
# 创建透视表对象
pt = sheet2.PivotTables.Add("销售透视表", sheet2.Range["A1"], cache)
# 把字段拖入行区域(区域外层 → 产品内层)
pf_region = pt.PivotFields["区域"]
pf_region.Axis = AxisTypes.Row
pf_product = pt.PivotFields["产品"]
pf_product.Axis = AxisTypes.Row
# 把字段拖入数据区域
pt.DataFields.Add(pt.PivotFields["销售额"], "销售额汇总", SubtotalTypes.Sum)
pt.DataFields.Add(pt.PivotFields["订单数"], "订单数汇总", SubtotalTypes.Sum)
# 应用内置样式并触发计算
pt.BuiltInStyle = PivotBuiltInStyles.PivotStyleMedium12
pt.CalculateData()
workbook.SaveToFile("SalesPivot.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
print("SalesPivot.xlsx 已生成")说明:
PivotCaches.Add(dataRange)将数据源注册为透视缓存,是创建透视表的先决条件。PivotTables.Add(名称, 锚点单元格, 缓存)在指定工作表的指定位置插入透视表对象。pf.Axis = AxisTypes.Row把字段放入行区域;先后顺序决定层级(先放外层、后放内层)。DataFields.Add(字段, 显示名称, 汇总方式)把数值字段放入数据区域。这里使用SubtotalTypes.Sum按求和汇总。BuiltInStyle直接套用 Excel 自带的PivotStyleMedium12配色,节省自定义样式的工作量。CalculateData()必须显式调用,透视表才会把汇总结果物化到单元格上。
效果预览(基于示例 1 生成的 SalesPivot.xlsx 物化结果渲染):
预览为脚本对透视表已物化结果的静态展示;用 Excel/WPS 打开 SalesPivot.xlsx 后将呈现完整的可交互透视表——可点击行列字段旁的 +/- 折叠/展开明细、右键刷新数据、拖动字段列表中的字段重新组织透视。
3. 修改透视表:汇总方式与显示格式
实际报表里除了"求和",还需要"平均值"、"计数"、"最大/最小"等不同汇总方式;同时也常常需要把数字以"占列百分比"、"占总计百分比"等形式呈现。Spire.XLS 支持通过修改现有透视表对象来调整这些行为。
下面的示例加载上一步生成的 SalesPivot.xlsx,把销售额改为平均值汇总、把订单数改为最大值汇总,并把销售额显示为列百分比:
from spire.xls import *
from spire.xls.common import *
workbook = Workbook()
workbook.LoadFromFile("SalesPivot.xlsx")
sheet = workbook.Worksheets["数据透视表"]
pt = sheet.PivotTables[0]
# 修改汇总方式
pt.DataFields[0].Subtotal = SubtotalTypes.Average # 销售额 → 平均值
pt.DataFields[1].Subtotal = SubtotalTypes.Max # 订单数 → 最大值
# 数据字段显示为列百分比(适用于销售额这一列)
pt.DataFields[0].ShowDataAs = PivotFieldFormatType.PercentageOfColumn
# 重新计算并保存
pt.CalculateData()
workbook.SaveToFile("SalesPivot_Modified.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
print("SalesPivot_Modified.xlsx 已生成")说明:
Subtotal属性决定该数据字段的汇总方式,可选Sum / Average / Max / Min / Count / Product等枚举值。ShowDataAs控制数据字段的展示格式,PercentageOfColumn把每个单元格的数值转换为占其所在列总和的百分比;其它可用枚举包括PercentageOfRow、PercentageOfGrandTotal、RunningTotal等。- 修改后调用
CalculateData()让新规则生效,再保存为新文件保留原始版本以便对照。
4. 控制外观:布局、总计、空值显示与内置样式
透视表的"行小计"、"列总计"、"空值显示方式"以及"页面字段排列顺序"等外观属性,可以通过 Options、ShowRowGrand 等顶层属性统一设置。
from spire.xls import *
from spire.xls.common import *
workbook = Workbook()
workbook.LoadFromFile("SalesPivot.xlsx")
sheet = workbook.Worksheets["数据透视表"]
pt = sheet.PivotTables[0]
# 切换到 Tabular 布局(行字段并排显示,附带显式小计行)
pt.Options.RowLayout = PivotTableLayoutType.Tabular
# 显示行列总计
pt.ShowRowGrand = True
pt.ShowColumnGrand = True
# 空值单元格显示为自定义字符串
pt.DisplayNullString = True
pt.NullString = "—"
# 报表筛选字段自上而下、再自左而右
pt.PageFieldOrder = PagesOrderType.DownThenOver
# 是否显示行小计(默认 True;设为 False 时小计行会被隐藏)
pt.ShowSubtotals = True
# 重新应用内置样式
pt.BuiltInStyle = PivotBuiltInStyles.PivotStyleLight10
pt.CalculateData()
workbook.SaveToFile("SalesPivot_Styled.xlsx", ExcelVersion.Version2016)
workbook.Dispose()说明:
Options.RowLayout控制行字段布局:Compact(默认,分级缩进)、Outline(带分级线)、Tabular(表格化,每个行字段占一列)。ShowRowGrand/ShowColumnGrand分别控制是否在透视表底部/右侧显示行总计与列总计。DisplayNullString = True配合NullString让没有数据的单元格显示自定义占位符(默认为"null",这里改为—)。PageFieldOrder决定报表筛选字段(页面字段)的摆放顺序:DownThenOver(先下后右)/OverThenDown(先右后下)。
5. 展开/折叠明细与自动刷新
完成布局调整后,下一步是控制透视表里"区域"或"产品"明细行的展开状态,以及让透视表在打开文件时自动随源数据更新。
from spire.xls import *
from spire.xls.common import *
workbook = Workbook()
workbook.LoadFromFile("SalesPivot.xlsx")
sheet = workbook.Worksheets["数据透视表"]
pt = sheet.PivotTables[0]
# 1. 计算数据(展开/折叠前需先调用)
pt.CalculateData()
# 2. 折叠"华东"区域的产品明细行(仅显示华东合计)
pt.PivotFields["区域"].HideItemDetail("华东", True)
# 3. 展开"华北"区域的产品明细行
pt.PivotFields["区域"].HideItemDetail("华北", False)
# 4. 启用"打开文件时自动刷新"
pt.Cache.IsRefreshOnLoad = True
workbook.SaveToFile("SalesPivot_Refresh.xlsx", ExcelVersion.Version2016)
workbook.Dispose()说明:
HideItemDetail(item, True)将该行字段下的某个条目折叠(只显示合计,隐藏明细);False则展开。Cache.IsRefreshOnLoad = True会在用户用 Excel/WPS 打开文件时,自动根据当前源数据重新计算透视表结果,避免"数据更新了透视表还是老的"的情况。
实测提醒:以上示例在 Free Spire.XLS 当前版本中保存后,明细展开/折叠的初始状态在部分环境下不会立即物化到 xlsx 文件中。用 Excel/WPS 打开文件并触发一次"刷新"后,折叠/展开状态会按脚本设定生效。
6. 关键类与方法解析
下表汇总了本文示例涉及到的核心 API,便于查阅与复用:
| 类 / 成员 | 作用 |
|---|---|
Workbook.Worksheets[i] | 按索引访问工作表 |
Workbook.CreateEmptySheet() | 新建空白工作表 |
Workbook.PivotCaches.Add(range) | 将指定数据区域注册为透视缓存 |
Worksheet.PivotTables.Add(name, anchor, cache) | 在工作表上创建透视表对象 |
PivotTable.PivotFields[name] | 获取字段引用,可设置其 Axis(行/列区域) |
PivotField.Axis | 设置字段所属区域,AxisTypes.Row 表示行区域 |
PivotField.SortType | 设置字段排序方式,如 PivotFieldSortType.Descending |
PivotField.HideItemDetail(item, bool) | 折叠或展开指定条目的明细 |
PivotTable.DataFields.Add(field, displayName, subtotal) | 向数据区域添加一个汇总字段 |
PivotTable.DataFields[i].Subtotal | 修改已有数据字段的汇总方式(Sum/Average/Max/...) |
PivotTable.DataFields[i].ShowDataAs | 修改数据字段显示格式(百分比、占比等) |
PivotTable.BuiltInStyle | 应用 Excel 内置透视表样式枚举 |
PivotTable.CalculateData() | 触发透视表汇总计算,物化到单元格 |
PivotTable.Options.RowLayout | 设置行字段布局(Compact/Outline/Tabular) |
PivotTable.ShowRowGrand / ShowColumnGrand | 控制行列总计的显示 |
PivotTable.ShowSubtotals | 是否显示行小计 |
PivotTable.DisplayNullString / NullString | 自定义空值单元格的占位符 |
PivotTable.PageFieldOrder | 报表筛选字段排列顺序 |
PivotTable.Cache.IsRefreshOnLoad | 是否在打开文件时自动刷新 |
总结
通过本文示例,你已经掌握了如何使用 Python + Free Spire.XLS 在 Excel 中创建原生可交互的数据透视表。从把销售明细写入工作簿、到通过 PivotCaches 与 PivotTables.Add 生成透视对象、再到把多个字段分别拖入行/数据区域,整个过程都通过脚本完成,避免了在 Excel 里反复手动拖拽的重复劳动。相比 pandas.pivot_table 生成的静态汇总结果,本方案生成的 .xlsx 在 Excel/WPS 打开后可以直接点击展开/折叠、修改字段列表、设置筛选条件,使用体验与手动建立的透视表完全一致。
在示例基础上,你可以继续扩展更多能力:
- 批量生成月度透视表:对每个月度销售明细文件重复同一段透视代码,结合遍历文件夹实现"一键出 N 张月报";
- 结合邮件自动发送:把生成的
SalesPivot.xlsx作为附件,通过smtplib或yagmail自动发到指定邮箱; - 搭配 Spire.PDF 生成报告:把透视表用 Spire.PDF for Python 转为 PDF 报告,配合图表与封面页,输出标准化月报;
- 按权限只读分享:利用 Spire.XLS 的
Workbook.Protect/Sheet.Protect设置工作簿或工作表的口令保护,避免他人误改透视表结构。
如果你正在做销售/财务/运营方向的报表自动化,这种"Excel 原生透视 + Python 脚本"的组合将显著缩短从明细数据到可视化报表的距离。
以上就是Python在Excel中创建数据透视表的完整指南的详细内容,更多关于Python Excel创建数据透视表的资料请关注脚本之家其它相关文章!
