Python在Excel中创建数据透视表的完整指南

 更新时间:2026年09月05日 09:28:47   作者:大丸子  
本文将使用 Free Spire.XLS for Python 在 Excel 工作簿中创建一份真正可交互的原生 Excel 数据透视表(PivotTable),既保留 Python 自动化的效率,又能在 Excel/WPS 中以熟悉的透视表方式查看与分析,感兴趣的小伙伴可以了解下

在销售、财务、运营等业务场景中,按"区域 × 产品"、"季度 × 品类"等维度对明细数据进行交叉汇总,是日常报表里出现频率最高的需求。手动操作 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 把每个单元格的数值转换为占其所在列总和的百分比;其它可用枚举包括 PercentageOfRowPercentageOfGrandTotalRunningTotal 等。
  • 修改后调用 CalculateData() 让新规则生效,再保存为新文件保留原始版本以便对照。

4. 控制外观:布局、总计、空值显示与内置样式

透视表的"行小计"、"列总计"、"空值显示方式"以及"页面字段排列顺序"等外观属性,可以通过 OptionsShowRowGrand 等顶层属性统一设置。

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创建数据透视表的资料请关注脚本之家其它相关文章!

相关文章

  • python中itertools模块zip_longest函数详解

    python中itertools模块zip_longest函数详解

    itertools模块包含创建高效迭代器的函数,这些函数的返回值不是list,而是iterator(可迭代对象),可以用各种方式对数据执行循环操作,今天我们来详细探讨下zip_longest函数
    2018-06-06
  • Python实现图片与视频互转代码实战(亲测有效)

    Python实现图片与视频互转代码实战(亲测有效)

    图片转视频,视频转图片手机一操作,立马转换过来,那么基于代码是如何操作的呢?下面小编给大家带来了Python实现图片与视频互转代码实战,感兴趣的朋友跟随小编一起看看吧
    2021-12-12
  • Python对列表进行排序的五种方法示例代码

    Python对列表进行排序的五种方法示例代码

    这篇文章主要给大家介绍了关于Python对列表进行排序的五种方法,分别是sort()、sorted()、lambda表达式、reverse()和自定义排序算法,这些方法各有特点,文中给出了详细的代码示例,需要的朋友可以参考下
    2025-05-05
  • Python实现将通信达.day文件读取为DataFrame

    Python实现将通信达.day文件读取为DataFrame

    今天小编就为大家分享一篇Python实现将通信达.day文件读取为DataFrame,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • Python Pygame制作雪夜烟花景

    Python Pygame制作雪夜烟花景

    这篇文章主要为大家详细介绍了如何利用Python中的Pygame模块制作一个雪夜烟花景,文中的示例代码讲解详细,对我们学习Python有一定帮助,需要的可以参考一下
    2022-01-01
  • 基于Django websocket实现视频画面的实时传输功能(最新推荐)

    基于Django websocket实现视频画面的实时传输功能(最新推荐)

    Django Channels 是一个用于在 Django框架中实现实时、异步通信的扩展库,本文给大家介绍基于Django websocket实现视频画面的实时传输案例,本案例是基于B/S架构的视频监控画面的实时传输,使用django作为服务端的开发框架,需要的朋友可以参考下
    2023-06-06
  • python实现在多维数组中挑选符合条件的全部元素

    python实现在多维数组中挑选符合条件的全部元素

    今天小编就为大家分享一篇python实现在多维数组中挑选符合条件的全部元素,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • 使用PyTorch实现去噪扩散模型的完整代码

    使用PyTorch实现去噪扩散模型的完整代码

    在本文中,我们将深入研究DDPM的复杂性,涵盖其训练过程,包括正向和逆向过程,并探索如何执行采样,在整个探索过程中,我们将使用PyTorch从头开始构建DDPM,并完成其完整的训练,需要的朋友可以参考下
    2024-01-01
  • 分享13个非常有用的Python代码片段

    分享13个非常有用的Python代码片段

    大家好,这篇文章主要和大家分享13个Python中非常有用的代码片段,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-06-06
  • python 实现一个反向单位矩阵示例

    python 实现一个反向单位矩阵示例

    今天小编就为大家分享一篇python 实现一个反向单位矩阵示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11

最新评论