查看: 66|回复: 3

Python+pandas+matplotlib+xlwings自动生成

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在日常办公中,从Excel提取数据并生成图表是常见需求。手工重复操作效率低,容易出错。本文提供一套完整的Python自动化流程:读取Excel数据,使用pandas清洗,matplotlib绘制图表保存为PNG,最后通过xlwings将图表插回Excel指定位置。整个过程可复用,只需修改文件名和列名即可适应不同报表。

适用场景与前提
该方法适合Excel表结构固定、数据定期更新的场景,如工单趋势、销售统计、巡检汇总等。注意:xlwings依赖本机Microsoft Excel应用,因此推荐在Windows办公电脑上运行。如果仅需生成PNG,可只用pandas+matplotlib;需要交付带图表的Excel文件则必须安装xlwings。

环境准备
需要安装四个核心库:pandas(读取清洗Excel数据)、matplotlib(绘图并保存PNG)、openpyxl(pandas读取.xlsx的底层引擎)、xlwings(通过Excel应用程序操控工作簿)。
  1. pip install pandas matplotlib openpyxl xlwings
复制代码
安装后可用以下代码自检:
  1. import pandas as pd
  2. import matplotlib.pyplot as plt
  3. import xlwings as xw
  4. print("环境检测通过")
复制代码

核心:读取Excel生成图表PNG
假设Excel文件report.xlsx,工作表名为“数据”,包含“月份”和“工单数量”两列。关键点:列名应干净、无合并单元格,数值列可能混入空格或文本。使用pd.to_numeric(..., errors='coerce')将非数值转为NaN,再dropna()清理。
  1. import pandas as pd
  2. import matplotlib.pyplot as plt
  3. from pathlib import Path
  4. def excel_to_chart_png(xlsx_path, sheet_name, x_col, y_col, out_png):
  5.     df = pd.read_excel(xlsx_path, sheet_name=sheet_name)
  6.     x = df[x_col].astype(str)
  7.     y = pd.to_numeric(df[y_col], errors="coerce")
  8.     data = pd.DataFrame({x_col: x, y_col: y}).dropna()
  9.     plt.figure(figsize=(8, 4))
  10.     plt.plot(data[x_col], data[y_col], marker="o")
  11.     plt.title(f"{y_col}趋势图")
  12.     plt.xlabel(x_col)
  13.     plt.ylabel(y_col)
  14.     plt.xticks(rotation=30)
  15.     plt.grid(axis="y", linestyle="dashed", alpha=0.4)
  16.     plt.tight_layout()
  17.     out_png = Path(out_png)
  18.     out_png.parent.mkdir(parents=True, exist_ok=True)
  19.     plt.savefig(out_png, dpi=200)
  20.     plt.close()
  21.     return str(out_png)
  22. if __name__ == "__main__":
  23.     png = excel_to_chart_png("report.xlsx", "数据", "月份", "工单数量", "out/chart.png")
  24.     print("图表已输出:", png)
复制代码

插图到Excel:xlwings控制位置
生成PNG后,需要将图片插回Excel报表。核心操作:定位锚点单元格(如H2),删除同名旧图避免叠图,插入新图并调整尺寸,另存为新文件以保护原数据。
  1. import xlwings as xw
  2. from pathlib import Path
  3. def insert_png_to_excel(xlsx_path, sheet_name, png_path, anchor_cell="H2", out_xlsx=None):
  4.     xlsx_path = str(Path(xlsx_path).resolve())
  5.     png_path = str(Path(png_path).resolve())
  6.     if out_xlsx is None:
  7.         p = Path(xlsx_path)
  8.         out_xlsx = str(p.with_name(p.stem + "_已插图" + p.suffix))
  9.     app = xw.App(visible=False, add_book=False)
  10.     try:
  11.         wb = app.books.open(xlsx_path)
  12.         sht = wb.sheets[sheet_name]
  13.         cell = sht.range(anchor_cell)
  14.         # 删除同名旧图,避免重复叠图
  15.         for pic in list(sht.pictures):
  16.             if pic.name == "chart_png":
  17.                 pic.delete()
  18.         sht.pictures.add(png_path, name="chart_png", left=cell.left, top=cell.top)
  19.         pic = sht.pictures["chart_png"]
  20.         pic.width = 520
  21.         pic.height = 320
  22.         wb.save(out_xlsx)
  23.         wb.close()
  24.     finally:
  25.         app.quit()
  26.     return out_xlsx
  27. if __name__ == "__main__":
  28.     out = insert_png_to_excel("report.xlsx", "数据", "out/chart.png", "H2")
  29.     print("已写回Excel:", out)
复制代码

合体脚本:一键自动化
将两个函数组合,只需修改四个变量(xlsx、sheet、x_col、y_col)即可快速迁移到其他报表。
  1. if __name__ == "__main__":
  2.     xlsx = "report.xlsx"
  3.     sheet = "数据"
  4.     x_col = "月份"
  5.     y_col = "工单数量"
  6.     png = excel_to_chart_png(xlsx, sheet, x_col, y_col, "out/chart.png")
  7.     out = insert_png_to_excel(xlsx, sheet, png, "H2")
  8.     print("完成交付文件:", out)
复制代码

效果验证要点
1. 检查PNG是否存在、标题正确、x/y轴数据合理、中文无乱码。
2. 打开带图Excel,确认图片位于指定锚点,未压住数据,尺寸合适。
3. 抽查原始数据与图表趋势是否一致。

常见踩坑与解决
ModuleNotFoundError:使用“python -m pip install”确保安装到当前Python环境。
中文标题显示为方块:matplotlib默认字体不含中文,添加以下配置:
  1. plt.rcParams["font.sans-serif"] = ["SimHei"]
  2. plt.rcParams["axes.unicode_minus"] = False
复制代码
xlwings无法打开Excel:检查本机是否安装Microsoft Excel(非WPS或其他Office)。若在无Office的服务器上运行,建议只使用pandas+matplotlib。
图片重复插入:脚本中已通过删除同名图片“chart_png”避免叠图。若仍出现,检查图片名称是否一致。
图片压住数据:调整锚点单元格(如改用J3或L2),或在模板中预留固定图表区域。

总结
本文并非单纯展示绘图语法,而是构建一条“Excel数据源→pandas读取→matplotlib出图→xlwings插回Excel→交付文件”的自动化链路。实际落地时重点关注数据清洗、图片定位、避免覆盖原文件。掌握这套流程后,面对同类型报表只需调整列名和路径,即可快速实现办公自动化。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python+pandas+matplotlib+xlwings自动生成

感谢分享这个完整的自动化流程!代码从数据读取、清洗到图表生成和回插Excel都覆盖了,很实用。特别是用 `pd.to_numeric` 加 `errors='coerce'` 处理脏数据,以及插入图片时先删除同名旧图避免叠图,这些细节非常贴心。有个小问题想请教:如果Excel文件不是 `.xlsx` 而是 `.xls` 格式,xlwings 和 pandas 需要额外处理吗?另外,图表配色和字体方面,有没有什么建议能支持中文显示?再次感谢!
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python+pandas+matplotlib+xlwings自动生成

感谢分享!这套流程很实用,把 pandas 清洗、matplotlib 绘图和 xlwings 插入整合成一个可复用的脚本,对于固定模板的报表自动化工作来说非常高效。尤其对数据列做 `to_numeric` 和 `dropna` 处理以及删除同名旧图避免叠图这两个细节,考虑得很周到,减少了手动干预的出错可能。 一点小建议:如果在没有安装 Excel 的环境中运行(比如服务器),可以考虑用 `openpyxl` 直接插入图片(`Worksheet.add_image()`),这样不依赖本地 Excel 应用,部署更灵活。另外实际使用中注意 `xlwings` 操作后记得关闭 Excel 进程,避免残留,楼主代码里用了 `try...finally...app.quit()`,这个习惯很好。 整体代码结构清晰,注释到位,新手也能快速上手改参数。感谢分享这种“即拿即用”的方案!
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python+pandas+matplotlib+xlwings自动生成

感谢分享,这个流程整理得很清晰,尤其是 `pd.to_numeric` 处理脏数据和删除旧图避免叠图这两点,确实能省掉不少手工排查的麻烦。我平时也常用类似的组合,不过偶尔会遇到 Excel 中有合并单元格导致读表报错的情况,不知道你有没有遇到过?另外想请教一下,xlwings 在 `visible=False` 模式下,碰到较大的 Excel 文件或者系统安全软件会不会有兼容性问题?期待继续交流。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-7 11:36 , Processed in 0.035808 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部