首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >用Python给运营同事做了个Excel自动化工具,从此她再也不加班了

用Python给运营同事做了个Excel自动化工具,从此她再也不加班了

原创
作者头像
七条猫
发布2026-08-08 16:33:52
发布2026-08-08 16:33:52
1260
举报

上周三下午运营部的小夏抱着一杯珍珠奶茶来找我的时候,我正对着满屏的bug发愁。她把奶茶往我桌上一放,苦着脸说:“哥,能不能帮我个忙?每周五的销售报表我实在做吐了,三个平台的数据导出来七八个Excel,复制粘贴加算环比,每次要花三个多小时,上周还因为算错一个数被领导骂了。”

我当时拍胸脯说这还不简单,半天给你搞定。结果真动手做的时候才发现,现实里的需求根本不像LeetCode题那样规整,前前后后踩了四五个坑,折腾了快两天才做出来。不过现在小夏每周五打开软件点一下按钮,10秒钟就能出完整报表,昨天还说这个月不用加班省下来的钱准备请我吃火锅。

特意把整个开发过程和踩过的坑整理出来,给同样经常要处理Excel的朋友们做个参考,完整源码我放在文末了,需要的可以自取。


需求梳理

先跟小夏坐下来捋了整整半小时,才把她平时做报表的完整流程搞清楚,以前我总觉得自动化就是写代码读文件算数据就行,真对接业务才发现,80%的时间都在处理那些“不规范”的问题。

我把手动处理和自动化的效果做了个简单对比:

对比项

手动处理

自动化工具

单次耗时

2.5-3小时/周

10秒以内

错误率

5%-10%(经常看错行、公式拉错)

0(逻辑固定)

学习成本

新人要教1周才能独立做

双击运行,选文件就行,1分钟学会

可维护性

新增统计维度要改所有表格

改几行代码即可

附加功能

做图表还要手动拉选数据

自动生成趋势图和汇总表

具体要实现的功能其实不复杂:

  1. 自动读取淘宝、京东、拼多多三个平台导出的销售明细Excel
  2. 清洗掉无效数据(测试单、退款单)
  3. 按周汇总各品类的销量、销售额、客单价
  4. 和上周数据对比计算环比增长
  5. 自动生成带格式的Excel报表,插入销量趋势图
  6. 不用装Python环境,同事双击就能用

技术选型

一开始也考虑过几个方案,毕竟给非技术人员用,稳定好用比技术炫酷重要多了:

  1. VBA:本来想过直接写Excel宏,但是VBA语法太老,处理数据不方便,而且不同版本Excel经常有兼容问题,小夏的电脑还是Office 2016,跑不了最新的函数,Pass。
  2. 低代码工具:比如飞书多维表格、简道云这些,但是数据要上传到第三方平台,公司销售数据不太方便外传,而且自定义计算逻辑不够灵活,Pass。
  3. Python:最终选了Python,Pandas处理表格数据是真的香,配合openpyxl操作Excel格式,matplotlib画图表,最后用pyinstaller打包成exe,完美解决环境问题。

用到的库都是非常成熟的,没有用什么冷门依赖:

代码语言:python
复制
pandas==1.5.3  # 数据处理
openpyxl==3.1.2  # Excel读写和格式设置
matplotlib==3.7.1  # 生成图表
pyinstaller==5.13.0  # 打包成exe
tkinter  # 做个简单的选文件界面,Python自带不用装

开发过程踩坑实录

本来以为几十行代码就能搞定,结果真写的时候坑一个接一个,说多了都是泪,给大家看看我踩过的那些坑:

坑1:永远对不上的表头

一开始我直接写pd.concat([pd.read_excel(f) for f in file_list]),结果跑出来列全乱了。后来才发现三个平台导出的Excel表头根本不一样:淘宝叫“订单金额”,京东叫“实付金额”,拼多多更绝,叫“买家实付(元)”,甚至同一个平台不同月份导出的文件,列顺序还会变,偶尔还有隐藏的空列。

解决方案:不要按列位置取数,统一做列名映射,不管原始列叫什么,先转成统一的字段名:

代码语言:python
复制
# 列名映射字典,不管原始列叫啥,统一重命名
column_mapping = {
    '订单编号': 'order_id',
    '订单金额': 'amount',
    '实付金额': 'amount',
    '买家实付(元)': 'amount',
    '支付时间': 'pay_time',
    '下单时间': 'pay_time',
    '商品品类': 'category',
    '品类名称': 'category'
}

def read_and_clean(file_path):
    df = pd.read_excel(file_path)
    # 只保留我们需要的列,顺便重命名
    df = df.rename(columns=column_mapping)
    df = df[['order_id', 'amount', 'pay_time', 'category']]
    return df

坑2:读出来的日期变成了数字

合并完数据算周度汇总的时候,发现pay_time列全是45123、45130这种数字,一开始以为是数据类型错了,转了半天字符串都不对,折腾了快一个小时才想起来,Excel里的日期本质是从1900年开始算的序列号,openpyxl读取的时候如果没做处理,就会直接读成数字。

解决方案:用pandas自带的转换函数,注意origin要设成1899-12-30,别问为什么,Excel自己有个千年虫bug,少算两天:

代码语言:python
复制
# 转换Excel日期序列号
df['pay_time'] = pd.to_datetime(df['pay_time'], unit='D', origin='1899-12-30')
# 过滤掉退款单和测试单
df = df[df['amount'] > 0]
df = df[~df['order_id'].str.contains('测试|退款', na=False)]

坑3:图表里的中文全是方块

用matplotlib生成趋势图的时候,插进去一看所有中文标签都变成了□□□,这个是老问题了,matplotlib默认字体不支持中文。

解决方案:直接指定系统里的中文字体,不用手动下载字体文件,Windows系统自带微软雅黑:

代码语言:python
复制
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']  # 解决中文显示
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 画周度销量趋势图
weekly_sales = df.groupby('week')['amount'].sum()
plt.figure(figsize=(10, 4))
plt.plot(weekly_sales.index, weekly_sales.values, marker='o', color='#2E86C1')
plt.title('近8周销售额趋势', fontsize=12)
plt.xlabel('周次', fontsize=10)
plt.ylabel('销售额(元)', fontsize=10)
plt.grid(alpha=0.3)
plt.savefig('trend.png', dpi=100, bbox_inches='tight')

我把遇到的所有坑整理成了表格,大家做类似项目的时候可以直接避坑:

坑点描述

根本原因

解决方案

合并Excel时数据错位

不同文件列顺序不一致、有隐藏列

统一做列名映射,按列名取数而非位置

日期读成45xxx数字

Excel日期为序列号存储

pd.to_datetime(unit='D', origin='1899-12-30')

图表中文显示方块

matplotlib默认无中文字体

指定sans-serif为系统自带中文字体

打包exe后运行闪退

相对路径问题,打包后工作目录变了

sys._MEIPASS处理资源路径

写入Excel时原有格式全丢

pandas默认会覆盖整个sheet

用openpyxl加载原有工作簿,只写入数据区域


核心功能实现

踩完所有坑之后,核心逻辑其实就几十行代码,我加了详细的注释,大家可以直接改改用:

代码语言:python
复制
import pandas as pd
from openpyxl import load_workbook
from openpyxl.styles import Font, Alignment, Border, Side, PatternFill
from openpyxl.drawing.image import Image
import datetime

def generate_report(input_files, output_path):
    # 1. 读取并合并所有文件
    all_dfs = []
    for f in input_files:
        all_dfs.append(read_and_clean(f))
    df = pd.concat(all_dfs, ignore_index=True)
    
    # 2. 数据计算
    df['pay_time'] = pd.to_datetime(df['pay_time'], unit='D', origin='1899-12-30')
    df['week'] = df['pay_time'].dt.isocalendar().week
    # 本周和上周数据
    current_week = datetime.date.today().isocalendar().week
    last_week = current_week - 1
    
    current_data = df[df['week'] == current_week].groupby('category').agg(
        销量=('order_id', 'count'),
        销售额=('amount', 'sum'),
        客单价=('amount', 'mean')
    ).reset_index()
    last_data = df[df['week'] == last_week].groupby('category')['销售额'].sum().reset_index()
    last_data.columns = ['category', '上周销售额']
    
    # 合并计算环比
    result = pd.merge(current_data, last_data, on='category', how='left')
    result['环比增长'] = (result['销售额'] - result['上周销售额']) / result['上周销售额']
    result['客单价'] = result['客单价'].round(2)
    result['环比增长'] = result['环比增长'].apply(lambda x: f"{x*100:.1f}%")
    
    # 3. 写入Excel并设置格式
    with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
        result.to_excel(writer, sheet_name='周度汇总', index=False)
        # 插入趋势图
        wb = writer.book
        ws = wb['周度汇总']
        img = Image('trend.png')
        ws.add_image(img, 'A10')
        
        # 设置表头格式(灰色背景、加粗、居中)
        header_fill = PatternFill(start_color='D9D9D9', end_color='D9D9D9', fill_type='solid')
        thin_border = Border(left=Side(style='thin'), right=Side(style='thin'),
                           top=Side(style='thin'), bottom=Side(style='thin'))
        for cell in ws[1]:
            cell.font = Font(bold=True)
            cell.fill = header_fill
            cell.alignment = Alignment(horizontal='center')
        # 给所有单元格加边框
        for row in ws.iter_rows(min_row=1, max_row=len(result)+1, max_col=5):
            for cell in row:
                cell.border = thin_border
                cell.alignment = Alignment(horizontal='center')

为了让同事用着方便,我用tkinter做了个极其简单的界面,丑是丑了点但是够用:就两个按钮,一个选文件,一个点生成,连路径都不用手动输。毕竟给非技术人员用,按钮越少越好,选项多了他们反而不会用。

(图1 工具运行界面,真的只有两个按钮,选完三个平台的Excel点生成就行)


效果展示与打包

最后用pyinstaller打包成单个exe文件,命令也给大家贴出来:

代码语言:bash
复制
pyinstaller -F -w -i icon.ico main.py
  • -F是打包成单个exe文件,不用带一堆依赖
  • -w是运行的时候不弹黑色的命令行窗口
  • -i是给exe加个图标,看起来正规一点

打包完生成的exe大概30M左右,直接发给小夏,她桌面上双击就能打开,不用装任何环境。现在她每周五早上到公司,选三个平台导出的文件,点一下生成按钮,喝口水的功夫报表就做好了,格式都是调好的,打印出来直接就能给领导交差。

(图2 最终生成的报表效果,前半部分是分品类汇总数据,环比增长超过10%的自动标成绿色,低于-10%的标成红色,下面是自动生成的近8周趋势图)

上周小夏跟我说,她们部门现在三个人都在用这个工具,以前每周五一整个下午都在做报表,现在10分钟搞定,剩下的时间都能摸鱼了。


后记

其实这个工具真的没什么高深的技术,用的都是Pandas最基础的功能,写代码的过程也没什么技术难点,大部分时间都在处理那些业务上的“小问题”:比如平台导出的文件偶尔会有合并单元格、同事下载文件的时候喜欢改名字、不同电脑上字体显示不一样这些细碎的问题,这些都是看书和看教程学不到的东西。

以前我总觉得要做分布式、高并发、大模型这种“高大上”的技术才叫厉害,这次做完这个小工具才发现,能实实在在解决身边人的麻烦,让他们不用做重复枯燥的劳动,写代码的价值其实一点都不小。

对了,还有几个小功能还在迭代:比如自动从邮箱拉取附件不用手动下载、生成完报表自动发给领导,等做完了再给大家更新。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 需求梳理
  • 技术选型
  • 开发过程踩坑实录
    • 坑1:永远对不上的表头
    • 坑2:读出来的日期变成了数字
    • 坑3:图表里的中文全是方块
  • 核心功能实现
  • 效果展示与打包
  • 后记
相关产品与服务
腾讯云 BI
腾讯云BI(Business Intelligence)提供从数据源接入、数据建模到数据可视化分析全流程的BI能力,仅需简单拖拽即可完成复杂的报表开发,并支持报表分享、推送等企业协作场景。其中的智能助手ChatBI作为基于大模型的智能分析Agent,支持通过简单对话实现数据分析,并提供数据解读、波动归因、业务优化建议等能力。腾讯云BI 简报模块具备强大的可视化能力,支持搭建大屏、领导驾驶舱、数据报告等,满足企业对外展示宣传、高层汇报、专题报告等业务场景。
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档