ARTICLE · 1063592
Python自动化办公:Excel图表自动生成全攻略,从此告别手工画图
每月做报表,复制粘贴、插入图表、调格式……一套流程下来半小时没了。今天教你用 Python 把这套动作变成一行命令,图表自动生成、自动排版,喝杯咖啡的功夫,报表已经躺在文件夹里了。
一、为什么选 xlsxwriter?
Python 操作 Excel 的库不少,但要做"原生图表"(就是 Excel 里那种可以点选、可以改数据源的图表),首选 xlsxwriter:
支持柱状图、折线图、饼图、散点图、组合图等几乎所有 Excel 图表类型
生成的图表是"真图表",不是图片,同事还能继续编辑
配合 pandas,数据处理 + 写出一气呵成
配合 pandas 处理数据,xlsxwriter 负责输出,就是黄金搭档。
二、环境准备
pip install pandas xlsxwriter openpyxl一行装好,开干。
三、5 分钟上手:第一个自动图表
假设我们有上半年销售和成本数据,想生成一张对比柱状图:
import pandas as pd# 1. 准备数据data = {"月份": ["1月", "2月", "3月", "4月", "5月", "6月"],"销售额": [120, 135, 148, 160, 175, 190],"成本": [80, 88, 95, 102, 110, 118],}df = pd.DataFrame(data)# 2. 写入 Excel 并插入图表with pd.ExcelWriter("销售报表.xlsx", engine="xlsxwriter") as writer:df.to_excel(writer, sheet_name="数据", index=False)workbook = writer.bookworksheet = writer.sheets["数据"]# 3. 创建柱状图chart = workbook.add_chart({"type": "column"})# 注意:行、列索引都从 0 开始;第 0 行是表头,数据从第 1 行开始chart.add_series({"name": "销售额","categories": ["数据", 1, 0, 6, 0], # 月份列"values": ["数据", 1, 1, 6, 1], # 销售额列})chart.add_series({"name": "成本","categories": ["数据", 1, 0, 6, 0],"values": ["数据", 1, 2, 6, 2],})# 4. 美化chart.set_title({"name": "上半年销售与成本对比"})chart.set_x_axis({"name": "月份"})chart.set_y_axis({"name": "金额(万元)"})chart.set_style(11) # 内置配色方案chart.set_size({"width": 640, "height": 400})# 5. 插入到 E2 单元格位置worksheet.insert_chart("E2", chart)print("搞定!")
运行后打开 销售报表.xlsx,数据在左边,图表在右边,还是可编辑的原生图表。
add_series 里那串数字 ["数据", 1, 0, 6, 0] 的含义是:[工作表名, 起始行, 起始列, 结束行, 结束列],全部从 0 开始计数。记住这个,后面所有图表都靠它。
四、四种常用图表,一次搞定
把上面的 chart 换一换,就能生成不同图表:
折线图:{"type": "line"},适合看趋势。
饼图:{"type": "pie"},适合看占比。
pie = workbook.add_chart({"type": "pie"})pie.add_series({"name": "渠道占比","categories": ["数据", 1, 0, 5, 0],"values": ["数据", 1, 1, 5, 1],"data_labels": {"percentage": True}, # 显示百分比})pie.set_title({"name": "各渠道销售占比"})worksheet.insert_chart("E20", pie)
column = workbook.add_chart({"type": "column"})column.add_series({"name": "销售额","categories": ["数据", 1, 0, 6, 0],"values": ["数据", 1, 1, 6, 1],})line = workbook.add_chart({"type": "line"})line.add_series({"name": "增长率","categories": ["数据", 1, 0, 6, 0],"values": ["数据", 1, 3, 6, 3],"y2_axis": True, # 使用次坐标轴})column.combine(line)column.set_title({"name": "销售额与增长率"})worksheet.insert_chart("E38", column)
五、实战:批量生成多部门报表
真正省时间的场景是:一次生成几十个部门的图表。用循环轻松搞定:
import pandas as pddepartments = {"销售部": [120, 135, 148, 160, 175, 190],"市场部": [90, 100, 115, 130, 145, 160],"技术部": [60, 70, 85, 95, 110, 125],"客服部": [40, 45, 52, 60, 68, 75],}months = ["1月", "2月", "3月", "4月", "5月", "6月"]with pd.ExcelWriter("部门报表.xlsx", engine="xlsxwriter") as writer:workbook = writer.bookfor dept, values in departments.items():df = pd.DataFrame({"月份": months, "业绩": values})df.to_excel(writer, sheet_name=dept, index=False)ws = writer.sheets[dept]chart = workbook.add_chart({"type": "line"})chart.add_series({"name": f"{dept}业绩","categories": [dept, 1, 0, 6, 0],"values": [dept, 1, 1, 6, 1],"marker": {"type": "circle", "size": 6},})chart.set_title({"name": f"{dept} 上半年业绩趋势"})chart.set_x_axis({"name": "月份"})chart.set_y_axis({"name": "业绩(万元)"})chart.set_size({"width": 600, "height": 380})ws.insert_chart("E2", chart)print("全部部门报表生成完毕!")
4 个部门、4 张图,不到 1 秒全部生成。如果公司有 50 个门店,代码一行都不用改。
六、进阶:给已有 Excel 加图表
如果数据已经在 Excel 里了,用 openpyxl 直接读取并加图表:
from openpyxl import load_workbookfrom openpyxl.chart import BarChart, Referencewb = load_workbook("原始数据.xlsx")ws = wb.activechart = BarChart()chart.type = "col"chart.title = "销售对比"chart.y_axis.title = "金额"chart.x_axis.title = "月份"data = Reference(ws, min_col=2, min_row=1, max_row=7) # 含表头cats = Reference(ws, min_col=1, min_row=2, max_row=7)chart.add_data(data, titles_from_data=True)chart.set_categories(cats)ws.add_chart(chart, "E2")wb.save("带图表报表.xlsx")
openpyxl 更适合"在模板上动刀"的场景,比如公司有固定格式的月报模板,你只需要把数据填进去、图表自动更新。
七、几个避坑小技巧
索引从 0 开始:
add_series里的行列号千万别按 Excel 的 1 开始数,会错位。中文工作表名可以直接用,但建议和
sheet_name完全一致。图表位置用
insert_chart("E2", chart),E2 是左上角锚点,图表会浮在单元格上方。数据标签:
"data_labels": {"value": True}可以显示数值,饼图用{"percentage": True}。想批量设置格式,可以把
chart的配置封装成函数,传不同参数复用。
八、总结
用 Python 做 Excel 图表自动化,核心就三步:
pandas 整理数据 → 写入工作表
xlsxwriter 创建 chart 对象 →
add_series绑定数据区域insert_chart 插入 → 保存
一旦跑通,以后每月报表就是"改数据源 → 运行脚本 → 收工"。省下的时间,摸摸鱼也好,学点新东西也好,都比重复劳动强。