我的知识记录

Python Excel 自动生成月度报表模板方法

用openpyxl一键生成月度报表模板:表头样式、标题、汇总公式、月度汇总sheet、季度对比sheet,每月换个日期直接跑脚本出报表,不用再复制模板。

场景痛点

每个月都要做同一张销售月报:标题栏写月份、表头套蓝底白字、明细区粘贴数据、底部算合计、再来个季度对比sheet。每次打开上月文件另存、改日期、清数据,稍不注意就把上个月的公式改坏了。把这套"模板"固化成Python脚本,传个月份就出新文件,格式、公式、汇总sheet全部就位,业务方直接往里填数就行。

用到的库

pip install openpyxl

完整代码

# -*- coding: utf-8 -*-
"""
一键生成月度报表模板
"""
from datetime import date
from pathlib import Path

from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter


# 通用样式
HEADER_FILL = PatternFill("solid", start_color="305496")
HEADER_FONT = Font(name="微软雅黑", size=11, bold=True, color="FFFFFF")
TITLE_FONT = Font(name="微软雅黑", size=16, bold=True, color="305496")
NORMAL_FONT = Font(name="微软雅黑", size=11)
CENTER = Alignment(horizontal="center", vertical="center")
THIN = Side(style="thin", color="BFBFBF")
BORDER = Border(left=THIN, right=THIN, top=THIN, bottom=THIN)


def build_monthly_report(year: int, month: int, out_dir: str = "."):
wb = Workbook()

# ===== Sheet1:月度明细 =====
ws = wb.active
ws.title = f"{month}月明细"

# 大标题
ws.merge_cells("A1:F1")
ws["A1"] = f"{year}年{month}月销售月报"
ws["A1"].font = TITLE_FONT
ws["A1"].alignment = CENTER
ws.row_dimensions[1].height = 30

# 生成日期
ws["A2"] = f"生成日期:{date.today().isoformat()}"

# 表头
headers = ["序号", "区域", "产品", "销售额(万)", "成本(万)", "毛利(万)"]
header_row = 4
for col_idx, name in enumerate(headers, start=1):
cell = ws.cell(row=header_row, column=col_idx, value=name)
cell.fill = HEADER_FILL
cell.font = HEADER_FONT
cell.alignment = CENTER
cell.border = BORDER

# 预留 20 行明细模板(公式自动算毛利)
data_start = header_row + 1
data_end = data_start + 19
for r in range(data_start, data_end + 1):
ws.cell(row=r, column=1, value=r - header_row)   # 序号
ws.cell(row=r, column=6).value = f"=D{r}-E{r}"  # 毛利=销售额-成本
for c in range(1, 7):
cell = ws.cell(row=r, column=c)
cell.font = NORMAL_FONT
cell.border = BORDER

# 合计行
total_row = data_end + 1
ws.cell(row=total_row, column=1, value="合计")
ws.cell(row=total_row, column=4).value = f"=SUM(D{data_start}:D{data_end})"
ws.cell(row=total_row, column=5).value = f"=SUM(E{data_start}:E{data_end})"
ws.cell(row=total_row, column=6).value = f"=SUM(F{data_start}:F{data_end})"
for c in range(1, 7):
cell = ws.cell(row=total_row, column=c)
cell.font = Font(name="微软雅黑", size=11, bold=True)
cell.border = BORDER

# 列宽
widths = [6, 12, 12, 14, 14, 14]
for i, w in enumerate(widths, start=1):
ws.column_dimensions[get_column_letter(i)].width = w

# ===== Sheet2:月度汇总 =====
ws2 = wb.create_sheet("月度汇总")
ws2.append(["指标", "数值"])
ws2.append(["本月销售额(万)", f"='{month}月明细'!D{total_row}"])
ws2.append(["本月成本(万)",   f"='{month}月明细'!E{total_row}"])
ws2.append(["本月毛利(万)",   f"='{month}月明细'!F{total_row}"])
ws2.append(["毛利率",
f"=IF(B2=0,0,B4/B2)"])
for col in "AB":
ws2.column_dimensions[col].width = 18

out_path = Path(out_dir) / f"销售月报_{year}年{month:02d}月.xlsx"
wb.save(out_path)
print("已生成:", out_path)
return str(out_path)


def main():
# 每月改这里即可,或者从命令行/日历读取
build_monthly_report(year=2026, month=9)


if __name__ == "__main__":
main()

代码讲解

  • 把所有样式抽成顶部常量:表头蓝底白字、标题深蓝大号字、灰色细边框。这样换月份时样式不会因为手滑变掉。
  • 大标题 merge_cells("A1:F1") 合并一行做标题,字号放大,视觉上一眼知道这是几月的表。
  • 明细区预留 20 行模板,每行 F 列写 =D-E 公式算毛利,业务方只要填 D、E 两列原始数据,毛利自动出来。
  • 合计行用 SUM(D5:D24) 把这 20 行求和。业务方填不满 20 行也没事,空单元格 SUM 自动忽略。
  • "月度汇总"sheet 跨表引用:='9月明细'!D25 把明细合计行拉过来,再算毛利率 =IF(B2=0,0,B4/B2) 防止除零。
  • 文件名带月份 销售月报_2026年09月.xlsxmonth:02d 保证个位数月份补零,排序时不会 10 月排在 2 月前面。
  • 想进一步自动化,把 build_monthly_report 接到定时任务(schedule/APScheduler)或从数据库读数据填入 D、E 列,连手填都省了。

运行结果

当前目录生成 销售月报_2026年09月.xlsx。打开后:A1 是蓝色大标题"2026年9月销售月报",第 4 行蓝底白字表头,第 5~24 行预留明细行且 F 列已带毛利公式,第 25 行是合计;第二个 sheet"月度汇总"自动引用明细合计。业务方从 D5、E5 开始填数即可,所有数字联动。

注意事项

  • 跨 sheet 引用时 sheet 名带中文或数字开头,必须加单引号:='9月明细'!D25。漏了引号 Excel 打开会报公式错误。
  • 预留行数(本例 20 行)要按业务峰值留足;不够就改 data_end。留太多空白行不影响 SUM,但视觉上看着空。
  • 公式跨表引用后,第一次用 Excel/WPS 打开会自动计算;如果用 openpyxl 再读,需要先按"写入公式"那篇文章讲的方式用 LibreOffice 重算。
  • 日期、月份作为函数参数传入,不要写死在代码里;后面接日历或定时任务时直接传参。
  • 模板样式里的"微软雅黑"在 Mac/Linux 上可能不存在,Excel 打开会自动替换;不影响公式和数据。
  • 每次生成都覆盖新文件,不要在同一份文件上反复改,否则公式引用容易错乱。

Python Excel 自动生成月度报表模板方法

标签:

更新时间:2026-09-15 09:05:31

上一篇:Python Excel数字格式化:金额千分位与百分比设置

下一篇:Python Excel合并单元格与取消合并:merge_cells用法详解