当前位置:首页>python>30天Python办公自动化全回顾!一张表总结所有代码+避坑指南,直接拿去用

30天Python办公自动化全回顾!一张表总结所有代码+避坑指南,直接拿去用

  • 2026-10-05 07:07:45
30天Python办公自动化全回顾!一张表总结所有代码+避坑指南,直接拿去用
“

一个月前,我还在手动复制粘贴Excel,每天加班半夜。现在,我坐在工位上泡杯茶,看着脚本自动处理全校成绩、生成报告、发邮件。这30天,我把踩过的坑、流过的泪、修过的bug都写成了文章。但我知道,很多人学完就忘,遇到问题还得翻之前的教程。今天我把这30天最常用、最实用的代码整理成一张表,每行代码都附上“自己踩过的坑”和“逐行解释”。以后再遇到类似任务,直接复制这段,改改文件名就能用。


🗂️一、文件操作:批量整理、重命名

import os, shutil# 列出文件夹里所有文件(排除文件夹)files = [f for f in os.listdir('目标文件夹') if os.path.isfile(os.path.join('目标文件夹', f))]# 移动文件shutil.move('旧路径', '新路径')# 批量重命名(加序号)for i, f in enumerate(files):    new_name = f'文件_{i+1}.txt'if not os.path.exists(new_name):        os.rename(f, new_name)# 创建文件夹(如果不存在)os.makedirs('新文件夹', exist_ok=True)

逐行解释:

  • os.listdir('目标文件夹'):拿到文件夹里所有东西的名字。
  • os.path.isfile():判断是不是文件(不是文件夹)。
  • shutil.move():移动文件到新位置。
  • os.rename():重命名文件。
  • os.makedirs(..., exist_ok=True):创建文件夹,如果已经存在也不会报错。

踩过的坑:

  • 一开始没用 os.path.isfile 过滤,结果把文件夹也移动了,整个目录结构乱掉。
  • 重命名时没检查新名字是否存在,结果把已有文件覆盖了。后来加了 if not os.path.exists 判断。
  • 路径里有空格?用原始字符串r'路径'或者双反斜杠 \\。

📊 二、Excel数据处理(Pandas核心)

import pandas as pd# 读取Exceldf = pd.read_excel('成绩表.xlsx', sheet_name='Sheet1')# 快速查看df.head()          # 前5行df.info()          # 列信息、缺失值df.describe()      # 数值列统计# 处理缺失值df.dropna()                             # 删掉有缺失的行df.fillna(0)                            # 缺失填0df['语文'].fillna(df['语文'].mean())     # 用平均值填# 筛选数据df[df['班级'] == '三(1)班']              # 单条件df[(df['语文'] > 90) & (df['数学'] > 90)] # 多条件且# 新增列df['总分'] = df['语文'] + df['数学'] + df['英语']df['等级'] = df['总分'].apply(lambda x: '优'if x >= 270 else'良')# 分组统计df.groupby('班级')['语文'].mean()                      # 各班语文平均df.groupby('班级').agg({'语文':'mean', '数学':'max'})   # 不同列不同统计# 合并多个Excelall_files = [f for f in os.listdir('各班成绩') if f.endswith('.xlsx')]df_list = [pd.read_excel(os.path.join('各班成绩', f)) for f in all_files]df_all = pd.concat(df_list, ignore_index=True)# 保存df.to_excel('结果.xlsx', index=False)df.to_csv('结果.csv', index=False, encoding='utf-8-sig')

逐行解释:

  • pd.read_excel():读Excel,sheet_name 指定工作表。
  • head()、info()、describe():快速了解数据。
  • dropna()、fillna():处理缺失值。
  • df[条件]:筛选行。
  • groupby:分组聚合。
  • pd.concat():纵向合并多个DataFrame。
  • to_excel/to_csv:保存,index=False 去掉行号。

踩过的坑:

  • 用 pd.concat 时,如果列名不一致,会全列保留,出现很多NaN。可以用 join='inner' 只保留共有列。
  • 保存CSV中文乱码?encoding='utf-8-sig' 解决。
  • 分组后想转成普通表格,用 .reset_index()。
  • apply 里用 lambda,如果逻辑复杂,最好先定义函数,否则容易写成一长串看不懂。

📄 三、Word批量生成(docxtpl)

from docxtpl import DocxTemplate# 加载模板doc = DocxTemplate('奖状模板.docx')  # 模板里要有 {{姓名}}、{{奖项}} 占位符# 填充数据doc.render({'姓名': '张三','奖项': '三好学生','日期': '2025年7月'})# 保存doc.save('奖状_张三.docx')# 批量生成(配合pandas)import pandas as pddf = pd.read_excel('学生名单.xlsx')for _, row in df.iterrows():    doc = DocxTemplate('奖状模板.docx')    doc.render({'姓名': row['姓名'],'奖项': row['奖项'],'日期': '2025年7月'    })    doc.save(f"奖状_{row['姓名']}.docx")

逐行解释:

  • DocxTemplate('模板.docx'):加载Word模板文件。
  • .render({...}):用字典里的值替换模板里的 {{变量}}。
  • .save():保存为新文件。
  • 批量生成时,每次循环重新加载模板,避免第一次渲染后模板被修改。

踩过的坑:

  • 模板里占位符写错大小写,渲染后还是原样。
  • 如果模板里有表格,需要用 {% for row in 汇总表 %} 语法,但 docxtpl 的表格渲染比较绕,建议先在模板里画好一行,然后用{% for %}包裹。
  • 插入图片要用InlineImage,否则图片不显示。

🧾 四、PDF处理(PyPDF2)

import PyPDF2# 合并多个PDFmerger = PyPDF2.PdfMerger()for pdf in ['1.pdf', '2.pdf']:    merger.append(pdf)merger.write('合并.pdf')# 拆分PDF(取前3页)with open('源.pdf', 'rb') as f:    reader = PyPDF2.PdfReader(f)    writer = PyPDF2.PdfWriter()for i in range(3):        writer.add_page(reader.pages[i])    with open('前3页.pdf', 'wb') as out:        writer.write(out)# 加水印(需要提前准备水印PDF)with open('源.pdf', 'rb') as src, open('水印.pdf', 'rb') as wm:    reader = PyPDF2.PdfReader(src)    watermark = PyPDF2.PdfReader(wm).pages[0]    writer = PyPDF2.PdfWriter()for page in reader.pages:        page.merge_page(watermark)        writer.add_page(page)    with open('带水印.pdf', 'wb') as out:        writer.write(out)

逐行解释:

  • PdfMerger().append():把PDF文件加入合并列表。
  • PdfReader:读取PDF,.pages 是所有页的列表。
  • PdfWriter:创建新PDF,用 .add_page() 添加页。
  • page.merge_page(watermark):把水印页叠加到当前页。

踩过的坑:

  • 合并时如果文件太多,内存会爆?PdfMerger的append不会一次性读入所有文件,可以放心。
  • 水印PDF最好只有一页,文字半透明,否则会盖住正文。
  • 用with open(... as f)确保文件正确关闭。

📧 五、邮件自动发送(smtplib)

import smtplibfrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextfrom email.mime.base import MIMEBasefrom email import encoders# 设置邮箱信息发件人 = '你的邮箱@qq.com'密码 = '授权码'# 不是登录密码收件人 = '领导@公司.com'# 构造邮件msg = MIMEMultipart()msg['From'] = 发件人msg['To'] = 收件人msg['Subject'] = '成绩报告'正文 = MIMEText('领导好,请查收附件。', 'plain', 'utf-8')msg.attach(正文)# 添加附件with open('报告.pdf', 'rb') as f:    part = MIMEBase('application', 'octet-stream')    part.set_payload(f.read())    encoders.encode_base64(part)    part.add_header('Content-Disposition', 'attachment; filename=报告.pdf')    msg.attach(part)# 发送server = smtplib.SMTP_SSL('smtp.qq.com', 465)server.login(发件人, 密码)server.send_message(msg)server.quit()

逐行解释:

  • MIMEMultipart():创建一个可包含正文和附件的邮件对象。
  • MIMEText():创建纯文本正文。
  • MIMEBase + encoders.encode_base64:将文件转成附件格式。
  • add_header:设置附件的文件名。
  • SMTP_SSL:连接QQ邮箱的SSL服务器,登录,发送。

踩过的坑:

  • 密码不是QQ登录密码,是邮箱设置里的“授权码”。要先开启SMTP服务,生成授权码。
  • 附件名含中文会乱码?最好用英文名,或者用email.utils.encode_header处理。
  • 发太多会被封?可以加time.sleep(1)间隔。
  • 公司邮箱可能用不同的服务器地址和端口,要问IT。

🖼️ 六、图片批量处理(PIL)

from PIL import Image, ImageDraw, ImageFontimport os# 批量缩放for f in os.listdir('照片'):if not f.endswith('.jpg'): continue    img = Image.open(os.path.join('照片', f))    img.thumbnail((800, 600))   # 等比例缩放到不超过800x600    img.save(os.path.join('处理后', f))# 添加文字水印img = Image.open('照片.jpg').convert('RGBA')txt = Image.new('RGBA', img.size, (255,255,255,0))draw = ImageDraw.Draw(txt)font = ImageFont.truetype('simhei.ttf', 40)draw.text((100,100), '保密', fill=(255,255,255,128), font=font)out = Image.alpha_composite(img, txt)out.convert('RGB').save('带水印.jpg')

逐行解释:

  • Image.open():打开图片。
  • .thumbnail((宽,高)):等比例缩放,不会变形。
  • convert('RGBA'):转成带透明通道的模式,方便叠加水印。
  • Image.new('RGBA', size, 颜色):创建一张透明图片。
  • ImageDraw.Draw():在图片上画画。
  • ImageFont.truetype():加载中文字体。
  • draw.text():写字,fill 最后一个参数是透明度(0-255)。
  • Image.alpha_composite():叠加两张透明图。
  • 最后转回RGB保存。

踩过的坑:

  • JPG没有透明通道,要先 convert('RGBA'),合并后再转回RGB保存。
  • 中文字体路径要正确,Windows一般有 simhei.ttf,Mac用 'PingFang.ttc'。
  • 如果字体文件不存在,会报错,可以用默认字体,但不支持中文。

📈 七、数据可视化(matplotlib)

import matplotlib.pyplot as plt# 解决中文乱码plt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = False# 折线图plt.plot(['1月','2月','3月'], [85,90,88], marker='o')plt.title('成绩趋势')plt.grid(True)plt.show()# 柱状图plt.bar(['三(1)','三(2)'], [92,88])plt.title('班级对比')for i, v in enumerate([92,88]):    plt.text(i, v+1, str(v), ha='center')plt.show()# 饼图plt.pie([45,30,25], labels=['教学','科研','行政'], autopct='%1.1f%%')plt.axis('equal')plt.show()# 保存图片plt.savefig('图表.png', dpi=300, bbox_inches='tight')

逐行解释:

  • plt.rcParams:设置全局字体,解决中文乱码。
  • plt.plot():画折线图,marker 是点的样式。
  • plt.bar():画柱状图。
  • plt.text():在指定坐标加文字,用于显示柱子上的数值。
  • plt.pie():画饼图,autopct 显示百分比格式。
  • plt.axis('equal'):让饼图是正圆。
  • plt.savefig():保存图片,dpi分辨率,bbox_inches='tight'去除白边。

踩过的坑:

  • 不设置中文字体,标题和标签全是方框。
  • plt.show()之后不能保存,因为画布被清空。要先savefig再show。
  • 饼图不加 axis('equal') 会变成椭圆,很难看。

⚠️ 八、基础语法—这些坑天天踩

# 字符串拼接name = '张三'age = 25print('我叫' + name + ',今年' + str(age) + '岁')   # 数字要转字符串print(f'我叫{name},今年{age}岁')                   # 推荐 f-string# 列表操作fruits = ['苹果','香蕉']fruits.append('橘子')          # 末尾加fruits.insert(1, '草莓')       # 指定位置加if'香蕉'in fruits:           # 先判断再删除    fruits.remove('香蕉')# 字典操作student = {'姓名':'张三', '年龄':12}print(student['姓名'])          # 键不存在会报错print(student.get('性别', '未知'))  # 安全访问# 文件读写with open('笔记.txt', 'w', encoding='utf-8') as f:    f.write('hello')with open('笔记.txt', 'r', encoding='utf-8') as f:    content = f.read()

踩过的坑:

  • 用 open 不指定 encoding,中文可能乱码,特别是Windows。
  • 列表索引从0开始,经常忘。
  • 字典用[]访问不存在的键直接报错,用 get 更安全。
  • 删除列表元素前最好用 in 判断一下,否则会报 ValueError。

📋 九、一张表总结(收藏使用)

功能
核心代码
遍历文件
[f for f in os.listdir('.') if os.path.isfile(f)]
移动文件
shutil.move('旧','新')
读Excel
pd.read_excel('文件.xlsx')
读CSV
pd.read_csv('文件.csv', encoding='utf-8-sig')
快速查看
df.head()
、df.info()、df.describe()
删除缺失
df.dropna()
填充缺失
df.fillna(0)
筛选行
df[df['列'] > 90]
多条件筛选
df[(条件1) & (条件2)]
新增列
df['新列'] = 计算
分组统计
df.groupby('列')['值'].mean()
合并多个DF
pd.concat([df1,df2])
保存Excel
df.to_excel('文件.xlsx', index=False)
Word模板填充
doc = DocxTemplate('模板.docx')
; doc.render({...})
合并PDF
PyPDF2.PdfMerger().append('1.pdf').write('合并.pdf')
发送邮件
smtplib.SMTP_SSL().login().send_message()
图片缩放
Image.open().thumbnail((800,600)).save()
画折线图
plt.plot(x,y)
画柱状图
plt.bar(x,y)
保存图片
plt.savefig('图.png')

🎯 今日挑战:做一个综合小工具

把你家里或者办公室里最乱的一个文件夹,用今天复习的代码整理一下:

  • 按文件类型分类(图片放一起,文档放一起)
  • 或者按修改日期归档(年/月文件夹)
  • 生成一个简单的Excel清单,列出所有文件信息

做完你会发现:原来Python真的能省好多时间。


🔮 下期预告

Excel处理几十万行数据卡成狗怎么办?下期我们正式进入数据库,用SQLite存储所有成绩数据,查询分析快到飞起。记得来哈。

回复「Py-Day」获取相关学习资料及源码

Day29:Matplotlib数据可视化速查手册—从画图到出报告,这些坑我都替你踩过了

Day28:Pandas数据处理速查手册(二)从Excel到数据分析,这些坑我都替你踩过了

Day27:Python基础语法速查手册(一)从变量到函数,这些坑我都替你踩过了

Day20:批量文件终结者!用Python一键处理100个Excel,自动生成汇总报表


最新文章

随机文章