← 返回课程体系
🧰 办公实战 痛点驱动

办公实战 痛点解决方案库

从真实工作场景出发,解决你每天遇到的重复性工作。
每个项目都来自保康本地政府/企业/乡镇的一线需求,即学即用。

📋 调研:保康本地办公常见痛点(15项)

通过对乡镇统计员、中小企业行政、县级单位办公室、茶企/香菇合作社等岗位的调研,汇总以下高频痛点:

📊 统计
各乡镇报表格式不统一 — 每月汇总15个乡镇的季度报表,每个镇的表格格式、列名都不一样,手工复制粘贴耗时2小时+。
📊 统计
手工核对数据累眼睛 — 几百行数据一条条看有没有重复、有没有填错格,眼睛酸效率低,还容易漏。
📄 文书
大量通知/证明/通报需逐个修改 — 年底发100份先进个人通知,每份改姓名、日期、单位名,Word复制粘贴改到崩溃。
📄 文书
PDF文件无法直接提取数据 — 上级发的PDF公文/红头文件,要提取里面的表格数据或关键字段,只能手打出来。
📧 内勤
群发通知逐个发邮件 — 给各村/各企业发会议通知,几十个邮箱地址来回粘贴,附件一个一个加,发到手软。
📊 财务
报销单数据重复录入 — 纸质报销单上的数字,手打到Excel,再录入财务系统,同一个数录三遍。
🗂️ 档案
文件归档靠人工分类拖拽 — 电脑桌面几百个文件按日期/类型分文件夹,一个一个拖,一不小心就搞乱。
📧 内勤
图片太大无法上传系统 — 拍的产品照片/活动照片每张5-10MB,上传系统有限制,要一张一张压缩、改名。
🌐 信息
政府网站公开数据采集难 — 需要关注某个补贴公示/招标公告,每天手动刷新网页看有没有更新,忘记就错过。
👥 人事
考勤统计全靠数指纹记录 — 每月导出的打卡记录几百条,每个人上班下班时间对着数,算加班工时算到头疼。
📄 档案
纸质档案电子化靠手动录入 — 历史档案、合同扫描件几百页,想转成Excel/Word只能一张张打字录入。
🍵 特产
茶叶/香菇库存手工记账 — 小微茶企用本子记进销存,月底盘点全靠翻账本,库存对不上是常事。
📊 统计
多来源数据拼表费时 — 一个数据表来自财政所,一个来自农技站,要拼在一起做汇总分析,格式对不上白费劲。
📊 财务
季度报表公式忘记检错 — Excel里嵌套了七八层公式,某次不小心改了一个单元格,整张表全错了还不知道。
🌐 信息
不会用编程工具 — 知道Python能自动化,但没人教、没时间学,觉得编程很难,望而却步。
🛠️

痛点解决方案 实战项目

以下10个实战项目,每个聚焦一个真实办公痛点,提供完整解决步骤和可直接复用的代码模板。

💡 痛点场景:乡镇报表汇总

📊 项目一:多表数据合并 — 15个乡镇报表一键汇总

小王是乡镇统计员,每月要收齐15个村的季度报表。每个村提交的Excel格式不一样——有的列名叫"产量"、有的叫"产粮",有的数据在Sheet1、有的在Sheet2。手工复制粘贴要花2个多小时,还经常粘错行。

Pythonpandasopenpyxlglob
展开查看解决方案 →
  1. 安装依赖:打开命令提示符(Win+R → 输入cmd → 回车),执行 pip install pandas openpyxl
  2. 把所有待汇总的Excel文件放到同一个文件夹(如 C:\报表汇总\),确保文件都是.xlsx格式
  3. 新建Python脚本:在桌面上新建一个文本文件,改名为 合并报表.py,右键"编辑",粘贴下方代码
  4. 修改文件夹路径:将代码中的 folder_path 改成你自己的文件夹路径
  5. 运行脚本:双击 合并报表.py(或在命令提示符中执行 python 合并报表.py),等待几秒钟
  6. 查看结果:在同目录下会生成 汇总结果.xlsx,所有数据已合并到一个文件中,每个Sheet标注了来源
import pandas as pd import glob import os # 设置存放Excel文件的文件夹路径 folder_path = r"C:\报表汇总" output_file = "汇总结果.xlsx" # 获取所有.xlsx文件 excel_files = glob.glob(os.path.join(folder_path, "*.xlsx")) if not excel_files: print("❌ 未找到Excel文件,请检查路径") exit() all_data = [] sheet_names = [] for file in excel_files: file_name = os.path.basename(file).replace(".xlsx", "") # 读取Excel文件中的所有Sheet xl = pd.ExcelFile(file) for sheet in xl.sheet_names: df = pd.read_excel(file, sheet_name=sheet) # 添加来源信息列 df['来源文件'] = file_name df['来源Sheet'] = sheet all_data.append(df) sheet_names.append(f"{file_name}_{sheet}") print(f"✅ 已读取: {file_name} - {sheet} ({len(df)}行)") # 合并所有数据 merged_df = pd.concat(all_data, ignore_index=True) # 写出到Excel,每个来源一个Sheet with pd.ExcelWriter(output_file, engine='openpyxl') as writer: # 总表 merged_df.to_excel(writer, sheet_name='汇总总表', index=False) # 分表 for df, name in zip(all_data, sheet_names): # Sheet名不能超过31字符 short_name = name[:31] df.to_excel(writer, sheet_name=short_name, index=False) print(f"\n🎉 合并完成!共合并 {len(excel_files)} 个文件,{len(all_data)} 个Sheet") print(f"📁 输出文件: {output_file}") print(f"📊 总数据行数: {len(merged_df)}")
💡 扩展技巧:如果各村表格列名不一致,可以在 pd.read_excel() 后加 df = df.rename(columns={"产粮": "产量", "金额(元)": "金额"}) 统一列名。
💡 痛点场景:公文数据处理

📄 项目二:PDF批量提取 — 从50份公文中提取关键数据

李姐在办公室工作,上级部门发来50份PDF格式的项目申报材料,需要在每份PDF里找到"项目名称""申报金额""负责人"三个字段,汇总成一个Excel表格。她只能打开每份PDF,复制粘贴到Excel,一份一份做,50份做了一整天。

PythonPyMuPDF(fitz)pdfplumberpandas
展开查看解决方案 →
  1. 安装依赖:执行 pip install pymupdf pdfplumber pandas openpyxl
  2. 准备一个包含所有PDF的文件夹(如 C:\PDF材料\
  3. 新建脚本 提取PDF数据.py,粘贴下方代码
  4. 修改关键词列表:将代码中 keywords 字典里的关键词替换成你需要提取的字段名
  5. 运行脚本:执行 python 提取PDF数据.py
  6. 检查输出:生成的 PDF提取结果.xlsx 中每行是一份PDF,每列是一个提取的字段
  7. 手动校正:对于提取不准的,打开对应PDF对照修正(通常首次需要微调关键词)
import fitz # PyMuPDF import pdfplumber import pandas as pd import glob import os import re # 配置 pdf_folder = r"C:\PDF材料" keywords = { "项目名称": ["项目名称", "项目名", "课题名称"], "申报金额(万元)": ["申报金额", "申请金额", "经费", "总金额"], "负责人": ["负责人", "项目负责人", "申请人", "申报人"], "单位": ["申报单位", "单位名称", "所在单位"] } results = [] pdf_files = glob.glob(os.path.join(pdf_folder, "*.pdf")) if not pdf_files: print("❌ 未找到PDF文件") exit() for file in pdf_files: file_name = os.path.basename(file) print(f"正在处理: {file_name}") row = {"文件名": file_name} # 方法1: 用PyMuPDF提取全部文本 doc = fitz.open(file) full_text = "" for page in doc: full_text += page.get_text() doc.close() # 方法2: 用pdfplumber(表格提取更准) table_text = "" try: with pdfplumber.open(file) as pdf: for page in pdf.pages: tables = page.extract_tables() for table in tables: for row_data in table: table_text += " ".join([str(c) for c in row_data if c]) + "\n" except: pass combined_text = full_text + "\n" + table_text # 提取每个关键词后面的值 for field_name, patterns in keywords.items(): value = "未找到" for pattern in patterns: # 匹配"关键词:XXX"或"关键词 XXX"格式 match = re.search( rf"{re.escape(pattern)}[::]\s*(.+?)[\n\r]", combined_text ) if match: value = match.group(1).strip() break row[field_name] = value results.append(row) # 输出Excel df = pd.DataFrame(results) df.to_excel("PDF提取结果.xlsx", index=False, engine='openpyxl') print(f"\n🎉 完成!共处理 {len(results)} 份PDF") print(f"📁 输出: PDF提取结果.xlsx")
💡 小技巧:如果PDF是扫描件(图片格式),需要用OCR技术提取文字——请参考项目十(文字识别OCR)。
💡 痛点场景:通知/证明/报表批量生成

📑 项目三:Word模板批量生成 — 一键生成100份先进个人通知

年底了,老张要给100个先进个人发通知文件。每份通知除了姓名、单位、奖项不同,其他一模一样。他先做好一个模板,然后复制粘贴100次改名字,手酸眼花搞了一下午,还漏发了3个人。

Pythonpython-docxpandas
展开查看解决方案 →
  1. 安装依赖:执行 pip install python-docx pandas openpyxl
  2. 准备Word模板文件:新建一个 模板.docx,把需要替换的地方用{{姓名}}{{单位}}{{奖项}}这样的占位符标出来
  3. 准备数据Excel:新建 名单.xlsx,第一行表头是"姓名""单位""奖项",下面每一行是一条记录
  4. 新建脚本 批量生成通知.py,粘贴下方代码
  5. 修改路径:template_pathdata_path 改成你的文件路径
  6. 运行脚本:执行 python 批量生成通知.py
  7. 查看结果:输出通知 文件夹中会生成100份带名字的Word文件
from docx import Document import pandas as pd import os # 配置 template_path = r"模板.docx" # Word模板文件 data_path = r"名单.xlsx" # Excel数据文件 output_dir = "输出通知" # 输出文件夹 # 创建输出文件夹 os.makedirs(output_dir, exist_ok=True) # 读取数据 df = pd.read_excel(data_path) print(f"📋 共加载 {len(df)} 条记录") for idx, row in df.iterrows(): # 打开模板 doc = Document(template_path) # 替换段落中的占位符 for paragraph in doc.paragraphs: for key, value in row.items(): placeholder = "{{" + str(key) + "}}" if placeholder in paragraph.text: # 保留原格式替换 for run in paragraph.runs: if placeholder in run.text: run.text = run.text.replace(placeholder, str(value)) # 替换表格中的占位符(如果有表格) for table in doc.tables: for table_row in table.rows: for cell in table_row.cells: for key, value in row.items(): placeholder = "{{" + str(key) + "}}" if placeholder in cell.text: cell.text = cell.text.replace(placeholder, str(value)) # 保存文件 name = str(row.get("姓名", f"第{idx+1}份")) output_path = os.path.join(output_dir, f"通知_{name}.docx") doc.save(output_path) print(f"✅ 已生成: 通知_{name}.docx") print(f"\n🎉 全部完成!共生成 {len(df)} 份通知文件") print(f"📁 文件位置: {os.path.abspath(output_dir)}")
💡 模板制作提示:在Word中用 Ctrl+H 把要替换的文字改成 {{字段名}} 格式即可。注意占位符前后不要有多余空格。
💡 痛点场景:会议通知群发

📧 项目四:邮件自动发送 — 批量发送带附件的会议通知

小陈在县政府办公室,月底要给全县15个乡镇、30多家企业发会议通知。每封邮件内容基本相同,但附件要根据收件人不同而替换。她一封一封发,每封都要:打开邮箱→点击"写邮件"→粘贴内容→添加附件→输入地址→发送。60封邮件发了一上午。

Pythonsmtplibemailpandas
展开查看解决方案 →
  1. 安装依赖:执行 pip install pandas openpyxl(smtplib和email是Python自带模块,无需安装)
  2. 准备数据:新建 收件人名单.xlsx,列名包括"邮箱""姓名""单位""附件路径"(附件路径指对应每个人的附件文件位置)
  3. 获取邮箱授权码:登录QQ邮箱 → 设置 → 账户 → 开启"POP3/SMTP服务" → 生成授权码(不是登录密码!)
  4. 新建脚本 批量发邮件.py,粘贴下方代码
  5. 修改邮箱配置:填入你的邮箱地址和授权码
  6. 运行脚本:执行 python 批量发邮件.py
  7. 查看发送结果:每发送成功一封会打印"✅ 已发送",失败的会显示原因
import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email import encoders import pandas as pd import os # ===== 邮箱配置 ===== SMTP_SERVER = "smtp.qq.com" # QQ邮箱;163邮箱用 smtp.163.com SMTP_PORT = 587 # TLS端口 SENDER_EMAIL = "你的QQ号@qq.com" # 发件邮箱 SENDER_PASS = "你的授权码" # 不是登录密码,是SMTP授权码! # ===== 读取收件人名单 ===== df = pd.read_excel("收件人名单.xlsx") print(f"📋 共 {len(df)} 封待发送邮件") # 邮件内容(HTML格式,支持富文本) subject_template = "关于召开{月份}月度工作会议的通知" body_template = """

尊敬的{姓名}:

您好!

根据工作安排,定于{日期}召开{月份}月度工作会议,现将有关事项通知如下:

  1. 会议时间:{日期} 上午9:00
  2. 会议地点:保康县人民政府三楼会议室
  3. 参会人员:{单位}负责同志
  4. 会议要求:请提前10分钟入场,携带相关材料。

特此通知。

保康县人民政府办公室
{日期}

""" # 连接SMTP服务器 server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT) server.starttls() server.login(SENDER_EMAIL, SENDER_PASS) print("✅ 已登录邮箱服务器") success = 0 fail = 0 for idx, row in df.iterrows(): try: # 创建邮件对象 msg = MIMEMultipart() msg["From"] = SENDER_EMAIL msg["To"] = row["邮箱"] msg["Subject"] = subject_template.format( 月份=row.get("月份", "本月"), 姓名=row["姓名"] ) # 正文 body = body_template.format( 姓名=row["姓名"], 单位=row["单位"], 日期=row.get("日期", "2025年1月15日"), 月份=row.get("月份", "本月") ) msg.attach(MIMEText(body, "html", "utf-8")) # 添加附件(如果有) if "附件路径" in row and pd.notna(row["附件路径"]): attach_path = row["附件路径"] if os.path.exists(attach_path): with open(attach_path, "rb") as f: part = MIMEBase("application", "octet-stream") part.set_payload(f.read()) encoders.encode_base64(part) part.add_header( "Content-Disposition", f"attachment; filename={os.path.basename(attach_path)}" ) msg.attach(part) # 发送 server.sendmail(SENDER_EMAIL, [row["邮箱"]], msg.as_string()) success += 1 print(f"✅ [{success}] 已发送至: {row['邮箱']} ({row['姓名']})") except Exception as e: fail += 1 print(f"❌ 发送失败 {row['邮箱']}: {str(e)}") server.quit() print(f"\n🎉 发送完毕!成功: {success} 封,失败: {fail} 封")
⚠️ 安全提醒:先给自己的邮箱发一封测试,确认格式正确后再正式发送!QQ邮箱授权码在"设置 → 账户 → POP3/SMTP服务"中生成。
💡 痛点场景:统计数据处理

🧹 项目五:数据去重清洗 — 从混乱的原始数据中提取干净信息

统计局的刘姐每月要处理来自多个渠道的统计数据:有的姓名带空格、有的手机号格式不对、有的重复提交了好几次、有的金额带"元"字。她用Excel的筛选功能一条条改,2000条数据要搞两天。

Pythonpandasre(正则)
展开查看解决方案 →
  1. 安装依赖:执行 pip install pandas openpyxl
  2. 准备原始数据:把需要清洗的Excel/CSV文件放到工作目录
  3. 新建脚本 数据清洗.py,粘贴下方代码
  4. 修改文件名和列名:input_file 和清洗规则中的列名改成你自己的
  5. 运行脚本:执行 python 数据清洗.py
  6. 检查结果:生成的文件包括:清洗结果.xlsx(干净数据)、重复数据.xlsx(被删掉的重复项)
import pandas as pd import re # 配置 input_file = "原始数据.xlsx" # 原始数据文件 output_file = "清洗结果.xlsx" # 清洗后输出 # 读取数据 df = pd.read_excel(input_file, dtype=str) print(f"📋 原始数据: {len(df)} 行, {len(df.columns)} 列") print(f"📋 列名: {list(df.columns)}") # ====== 清洗步骤 ====== # 1. 去除所有单元格前后空格 df = df.map(lambda x: x.strip() if isinstance(x, str) else x) print("✅ 已去除所有单元格前后空格") # 2. 统一手机号格式(去除横线、空格,补齐11位) if "手机号" in df.columns: def clean_phone(p): if pd.isna(p): return p p = re.sub(r'[\s\-\(\)]', '', str(p)) if len(p) == 11 and p.startswith('1'): return p return p df["手机号"] = df["手机号"].apply(clean_phone) print("✅ 手机号格式已统一") # 3. 提取金额数字(去掉"元""¥"等) if "金额" in df.columns: def extract_amount(val): if pd.isna(val): return val nums = re.findall(r'[\d.]+', str(val)) return nums[0] if nums else val df["金额"] = df["金额"].apply(extract_amount) print("✅ 金额字段已清洗(去除了单位文字)") # 4. 姓名去空格、统一大小写 if "姓名" in df.columns: df["姓名"] = df["姓名"].str.replace(r'\s+', '', regex=True) print("✅ 姓名已去空格") # 5. 去除重复行(基于指定列判断) if "身份证号" in df.columns: dup_before = len(df) df_dups = df[df.duplicated(subset=["身份证号"], keep=False)] df = df.drop_duplicates(subset=["身份证号"], keep="first") dedup_count = dup_before - len(df) print(f"✅ 基于身份证号去重: 删除了 {dedup_count} 条重复数据") elif "手机号" in df.columns: dup_before = len(df) df_dups = df[df.duplicated(subset=["手机号"], keep=False)] df = df.drop_duplicates(subset=["手机号"], keep="first") dedup_count = dup_before - len(df) print(f"✅ 基于手机号去重: 删除了 {dedup_count} 条重复数据") else: dedup_count = 0 # 6. 处理缺失值 null_counts = df.isnull().sum() null_cols = null_counts[null_counts > 0] if len(null_cols) > 0: print(f"⚠️ 以下列存在缺失值:") for col, cnt in null_cols.items(): print(f" - {col}: {cnt} 个空值") # 输出清洗后数据 df.to_excel(output_file, index=False, engine='openpyxl') print(f"\n🎉 清洗完成!") print(f"📁 干净数据: {output_file} ({len(df)} 行)") # 如果有重复数据,单独输出 if dedup_count > 0: df_dups.to_excel("重复数据.xlsx", index=False, engine='openpyxl') print(f"📁 重复数据: 重复数据.xlsx ({len(df_dups)} 行)")
💡 快速检查重复:如果不确定用哪列去重,可以在Excel中选中该列 → 条件格式 → 突出显示重复值,快速预览。
💡 痛点场景:文档归档管理

🗂️ 项目六:文件夹批量整理 — 按日期/类型自动归档文件

办公室的电脑桌面上堆满了文件——通知、报表、照片、会议材料混在一起。每次要找某个文件都要翻很久。小赵每次整理一次要花半小时把文件一个个拖到对应文件夹,过一周又乱了。

Pythonos/shutildatetimepathlib
展开查看解决方案 →
  1. 无需安装任何包:Python自带 os、shutil、pathlib 模块
  2. 新建脚本 文件整理.py,粘贴下方代码
  3. 修改要整理的文件夹路径:将 target_dir 改为你的桌面路径或其他需要整理的文件夹
  4. 运行脚本:执行 python 文件整理.py
  5. 查看效果:文件会自动按扩展名分类到"文档""图片""表格""PDF""其他"等文件夹中
  6. 进阶:如需按日期整理,取消注释代码中按日期整理的模块
import os import shutil from pathlib import Path from datetime import datetime # ===== 配置 ===== target_dir = Path.home() / "Desktop" # 要整理的文件夹(桌面) # target_dir = Path(r"C:\下载") # 或改成其他路径 # 文件分类规则(扩展名 → 文件夹名) categories = { "文档": [".doc", ".docx", ".txt", ".md", ".wps"], "表格": [".xls", ".xlsx", ".csv"], "PDF": [".pdf"], "图片": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".webp"], "压缩包": [".zip", ".rar", ".7z", ".tar", ".gz"], "演示": [".ppt", ".pptx"], "视频": [".mp4", ".avi", ".mov", ".wmv", ".flv"], "代码": [".py", ".js", ".html", ".css", ".json", ".xml", ".sql"], "其他": [] } # 收集所有没有被分类的文件扩展名 all_exts = set() for file in target_dir.iterdir(): if file.is_file(): all_exts.add(file.suffix.lower()) known_exts = set() for ext_list in categories.values(): known_exts.update(ext_list) unknown_exts = all_exts - known_exts if unknown_exts: categories["其他"].extend(list(unknown_exts)) # 创建分类文件夹 for folder_name in categories: (target_dir / folder_name).mkdir(exist_ok=True) # 移动文件 moved_count = 0 for file in target_dir.iterdir(): if file.is_file() and not file.name.startswith("文件整理"): moved = False for folder_name, exts in categories.items(): if file.suffix.lower() in exts: shutil.move(str(file), str(target_dir / folder_name / file.name)) moved_count += 1 moved = True break if not moved: shutil.move(str(file), str(target_dir / "其他" / file.name)) moved_count += 1 # ===== 按日期整理(可选) ===== # 取消下方注释启用:按文件修改日期存入 年/月 子文件夹 """ for folder_name in categories: folder_path = target_dir / folder_name for file in folder_path.iterdir(): if file.is_file(): mtime = os.path.getmtime(file) date = datetime.fromtimestamp(mtime) date_dir = folder_path / str(date.year) / f"{date.month:02d}月" date_dir.mkdir(parents=True, exist_ok=True) shutil.move(str(file), str(date_dir / file.name)) """ print(f"🎉 整理完成!共移动了 {moved_count} 个文件") print(f"📁 请查看 {target_dir}") # 统计每个分类的文件数 for folder_name in categories: folder_path = target_dir / folder_name if folder_path.exists(): count = len(list(folder_path.iterdir())) print(f" 📂 {folder_name}: {count} 个文件")
💡 安全提醒:建议先复制少量文件测试,确认分类规则符合预期后再整理整个文件夹。脚本不会删除任何文件,只是移动位置。
💡 痛点场景:材料图片上传

🖼️ 项目七:图片批量压缩/重命名 — 百张产品图一键处理

小周在茶叶合作社工作,要把200张产品照片上传到电商平台。每张照片5-10MB,平台限制单张不超过1MB,而且要统一命名格式为"保康绿茶_001.jpg"。她一张张用画图软件压缩、改名,2个小时还没做完。

PythonPillow(PIL)os
展开查看解决方案 →
  1. 安装依赖:执行 pip install Pillow
  2. 把要处理的图片放到一个文件夹(如 C:\原始图片\
  3. 新建脚本 图片批量处理.py,粘贴下方代码
  4. 修改配置:设置 input_folderoutput_foldername_prefix(文件名前缀)
  5. 运行脚本:执行 python 图片批量处理.py
  6. 检查输出:处理后的图片在 已处理图片 文件夹中,大小控制在1MB以内
from PIL import Image import os from pathlib import Path # ===== 配置 ===== input_folder = r"C:\原始图片" # 原始图片所在文件夹 output_folder = "已处理图片" # 输出文件夹 name_prefix = "保康绿茶_" # 文件名前缀 max_size_mb = 1 # 最大大小(MB) max_width = 1920 # 最大宽度(px) quality = 85 # JPEG压缩质量(1-100) # 支持的图片格式 supported = (".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".webp") # 创建输出文件夹 os.makedirs(output_folder, exist_ok=True) # 获取所有图片文件 image_files = [f for f in Path(input_folder).iterdir() if f.suffix.lower() in supported] if not image_files: print("❌ 未找到图片文件") exit() print(f"📋 找到 {len(image_files)} 张图片") total_before = sum(os.path.getsize(f) for f in image_files) print(f"📊 处理前总大小: {total_before / 1024 / 1024:.1f} MB") processed = 0 max_bytes = max_size_mb * 1024 * 1024 for idx, img_path in enumerate(image_files, 1): try: img = Image.open(img_path) # 转换RGBA为RGB(处理PNG透明背景) if img.mode in ("RGBA", "P"): img = img.convert("RGB") # 限制最大宽度(等比例缩放) if img.width > max_width: ratio = max_width / img.width new_h = int(img.height * ratio) img = img.resize((max_width, new_h), Image.LANCZOS) # 生成输出文件名 ext = ".jpg" # 统一输出为JPEG output_name = f"{name_prefix}{idx:03d}{ext}" output_path = os.path.join(output_folder, output_name) # 保存并控制大小 img.save(output_path, "JPEG", quality=quality, optimize=True) # 如果文件仍然大于限制,逐步降低质量 file_size = os.path.getsize(output_path) q = quality while file_size > max_bytes and q > 10: q -= 5 img.save(output_path, "JPEG", quality=q, optimize=True) file_size = os.path.getsize(output_path) processed += 1 before_size = os.path.getsize(img_path) after_size = os.path.getsize(output_path) ratio_pct = (1 - after_size / before_size) * 100 print(f"✅ [{processed}] {img_path.name} → {output_name} " f"({before_size/1024:.0f}KB→{after_size/1024:.0f}KB, 压缩{ratio_pct:.0f}%)") except Exception as e: print(f"❌ 处理失败 {img_path.name}: {str(e)}") total_after = sum(os.path.getsize(os.path.join(output_folder, f)) for f in os.listdir(output_folder)) print(f"\n🎉 处理完成!共处理 {processed}/{len(image_files)} 张图片") print(f"📊 处理前: {total_before/1024/1024:.1f} MB → 处理后: {total_after/1024/1024:.1f} MB") print(f"📁 文件位置: {os.path.abspath(output_folder)}")
💡 批量操作提醒:建议先复制一份原始图片到其他文件夹备份,再运行脚本。压缩后的图片质量在85%左右肉眼几乎看不出差异。
💡 痛点场景:政府网站信息采集

🌐 项目八:网页数据自动抓取 — 定时监控政府网站更新内容

小吴每天上班第一件事是打开县政府网站,看有没有新的补贴公示、招标公告、政策文件。如果今天没更新就白看了,如果有更新就得手动复制粘贴到Excel里做台账。一个月下来,每天花15分钟,还容易漏掉重要通知。

PythonrequestsBeautifulSouppandas
展开查看解决方案 →
  1. 安装依赖:执行 pip install requests beautifulsoup4 pandas lxml
  2. 新建脚本 网页监控.py,粘贴下方代码
  3. 修改目标网址:target_url 改为你要监控的网站地址
  4. 修改筛选规则:调整 item_selector(文章列表的CSS选择器)
  5. 运行脚本:执行 python 网页监控.py
  6. 每日运行:设置Windows任务计划程序,每天早上8点自动运行(见下方说明)
import requests from bs4 import BeautifulSoup import pandas as pd from datetime import datetime import os # ===== 配置 ===== target_url = "http://example.gov.cn/notice" # 替换为目标网站URL output_file = "网页监控台账.xlsx" # CSS选择器规则(根据目标网站的HTML结构调整) # 示例:如果公告列表是
  • 标题日期
  • item_selector = "ul.news-list li" # 列表项选择器 title_selector = "a" # 标题所在标签 link_selector = "a" # 链接所在标签 date_selector = "span" # 日期所在标签 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/120.0.0.0 Safari/537.36" } print(f"🌐 正在访问: {target_url}") try: resp = requests.get(target_url, headers=headers, timeout=15) resp.encoding = resp.apparent_encoding soup = BeautifulSoup(resp.text, "lxml") except Exception as e: print(f"❌ 访问失败: {str(e)}") exit() # 提取文章列表 items = soup.select(item_selector) print(f"📋 找到 {len(items)} 条记录") data = [] for item in items: title_el = item.select_one(title_selector) if title_selector else item title = title_el.get_text(strip=True) if title_el else "无标题" link_el = item.select_one(link_selector) if link_selector else item link = "" if link_el and link_el.name == "a" and link_el.get("href"): href = link_el["href"] if href.startswith("/"): from urllib.parse import urljoin link = urljoin(target_url, href) elif href.startswith("http"): link = href else: link = href date_el = item.select_one(date_selector) if date_selector else None date_text = date_el.get_text(strip=True) if date_el else "" data.append({ "标题": title, "链接": link, "日期": date_text, "抓取时间": datetime.now().strftime("%Y-%m-%d %H:%M") }) # 读取已有的台账,合并去重 if os.path.exists(output_file): existing = pd.read_excel(output_file) new_df = pd.DataFrame(data) combined = pd.concat([existing, new_df], ignore_index=True) combined = combined.drop_duplicates(subset=["标题", "链接"], keep="last") else: combined = pd.DataFrame(data) combined.to_excel(output_file, index=False, engine='openpyxl') # 输出新增内容 new_count = len(combined) - (len(pd.read_excel(output_file)) if os.path.exists(output_file) else 0) print(f"\n🎉 抓取完成!") print(f"📁 台账文件: {output_file} (共 {len(combined)} 条)") print(f"🆕 新增内容: {len(data)} 条(本批次)") # 显示最新5条 print("\n📰 最新内容预览:") for i, row in enumerate(data[:5]): print(f" {i+1}. {row['标题'][:40]}...")
💡 设置定时任务(Windows):
1. 搜索"任务计划程序" → 创建基本任务
2. 触发器设为"每天",时间设为"8:00"
3. 操作设为"启动程序" → 程序填 python,参数填脚本的完整路径
4. 每天早上自动运行,打开台账Excel就能看到最新内容
💡 痛点场景:人事考勤管理

⏰ 项目九:考勤/排班统计 — 打卡记录自动计算工时

人事科的小杨每个月导出考勤机里的打卡记录,几百条数据:张三 2025-01-15 08:12:23,张三 2025-01-15 17:45:38……她要在Excel里算每个人每天上班几小时、有没有迟到早退、加班多少分钟。40个人的数据,每次对几个小时眼睛都花了。

Pythonpandasdatetime
展开查看解决方案 →
  1. 安装依赖:执行 pip install pandas openpyxl
  2. 导出考勤记录:从考勤系统中导出打卡记录为Excel(通常包含"姓名""日期""打卡时间"三列)
  3. 新建脚本 考勤统计.py,粘贴下方代码
  4. 修改配置:设置上班时间、下班时间、迟到标准等参数
  5. 运行脚本:执行 python 考勤统计.py
  6. 查看结果:生成 考勤统计结果.xlsx,包含每个人每天的出勤情况汇总
import pandas as pd from datetime import datetime, timedelta # ===== 配置 ===== input_file = "考勤原始数据.xlsx" # 从考勤机导出的原始数据 output_file = "考勤统计结果.xlsx" # 上下班时间设置 MORNING_START = "08:00" # 上午上班时间 MORNING_END = "12:00" # 上午下班时间 AFTERNOON_START = "13:00" # 下午上班时间 AFTERNOON_END = "17:30" # 下午下班时间 # 迟到/早退标准(分钟) LATE_THRESHOLD = 15 # 超过X分钟算迟到 EARLY_THRESHOLD = 15 # 提前X分钟走算早退 # 读取原始数据 df = pd.read_excel(input_file) print(f"📋 原始记录: {len(df)} 条") print(f"📋 列名: {list(df.columns)}") # 标准化列名(通常考勤机导出的列名可能是"姓名/日期/时间"或"员工/打卡时间") df.columns = [str(c).strip() for c in df.columns] # 假设列名包含"姓名""日期""时间"关键词,自动匹配 name_col = [c for c in df.columns if "姓名" in c or "员工" in c or "名称" in c] date_col = [c for c in df.columns if "日期" in c or "日" in c] time_col = [c for c in df.columns if "时间" in c or "打卡" in c or "考勤" in c] if not name_col or not date_col or not time_col: print("❌ 无法自动识别列名,请检查数据格式") print(f" 找到的列: {list(df.columns)}") print(" 请确保列名包含:姓名、日期、时间") exit() name_col, date_col, time_col = name_col[0], date_col[0], time_col[0] # 转换日期和时间列为标准格式 df[date_col] = pd.to_datetime(df[date_col]).dt.date df[time_col] = pd.to_datetime(df[time_col], format='%H:%M:%S', errors='coerce') df[time_col] = df[time_col].dt.time # 按人和日期分组,每人每天取第一次打卡(上班)和最后一次打卡(下班) records = [] for (name, date), group in df.groupby([name_col, date_col]): times = sorted(group[time_col].dropna()) if len(times) < 2: # 只有一次打卡记录,无法计算 records.append({ "姓名": name, "日期": date, "上班打卡": str(times[0]) if times else "无", "下班打卡": "无", "出勤时长(小时)": 0, "状态": "打卡异常" }) continue first_punch = times[0] last_punch = times[-1] # 计算总在岗时间 def time_diff_minutes(t1, t2): dt1 = datetime.combine(datetime.today(), t1) dt2 = datetime.combine(datetime.today(), t2) return (dt2 - dt1).total_seconds() / 60 total_minutes = time_diff_minutes(first_punch, last_punch) # 判断迟到 morning_start = datetime.strptime(MORNING_START, "%H:%M").time() late_minutes = time_diff_minutes(morning_start, first_punch) if late_minutes > LATE_THRESHOLD: late_status = f"迟到{int(late_minutes)}分钟" else: late_status = "正常" # 判断早退 afternoon_end = datetime.strptime(AFTERNOON_END, "%H:%M").time() early_minutes = time_diff_minutes(last_punch, afternoon_end) if early_minutes > EARLY_THRESHOLD: early_status = f"早退{int(early_minutes)}分钟" else: early_status = "正常" records.append({ "姓名": name, "日期": str(date), "上班打卡": str(first_punch), "下班打卡": str(last_punch), "出勤时长(小时)": round(total_minutes / 60, 1), "出勤状态": late_status, "离开状态": early_status }) result = pd.DataFrame(records) # 每个人汇总统计 summary = result.groupby("姓名").agg( 出勤天数=("日期", "count"), 总时长_小时=("出勤时长(小时)", "sum"), 平均时长_小时=("出勤时长(小时)", "mean"), 迟到次数=("出勤状态", lambda x: sum("迟到" in str(s) for s in x)), 早退次数=("离开状态", lambda x: sum("早退" in str(s) for s in x)) ).reset_index() summary["总时长_小时"] = summary["总时长_小时"].round(1) summary["平均时长_小时"] = summary["平均时长_小时"].round(1) # 输出到Excel(两个Sheet) with pd.ExcelWriter(output_file, engine='openpyxl') as writer: result.to_excel(writer, sheet_name="每日明细", index=False) summary.to_excel(writer, sheet_name="汇总统计", index=False) print(f"\n🎉 考勤统计完成!") print(f"📁 输出文件: {output_file}") print(f"📊 每日明细: {len(result)} 条记录") print(f"📊 汇总统计: {len(summary)} 人") # 显示汇总 print("\n📋 考勤汇总:") for _, row in summary.iterrows(): print(f" {row['姓名']}: 出勤{row['出勤天数']}天, " f"共{row['总时长_小时']}小时, " f"迟到{row['迟到次数']}次, " f"早退{row['早退次数']}次")
💡 不同考勤机导出格式:如果导出的格式不一样(如所有打卡时间在一列用逗号分隔),请先截取示例数据发到答疑群,帮你调整脚本适配。
💡 痛点场景:纸质材料电子化

🔍 项目十:文字识别(OCR) — 扫描件/图片转Excel可编辑数据

档案室的老周要整理历史档案:500多页上世纪90年代的纸质统计表、手写报表、旧式合同。这些资料只有纸质版或扫描件,领导要电子版方便查询。如果手工打字录入,500页一年都做不完。他听说有OCR技术,但不知道怎么用。

PythonpytesseractPillowpandas百度OCR(免费)
展开查看解决方案 →
  1. 安装Tesseract OCR引擎:
    a. 下载Windows安装包:github.com/UB-Mannheim/tesseract/wiki
    b. 安装时勾选"简体中文语言包"
    c. 记下安装路径(如 C:\Program Files\Tesseract-OCR\tesseract.exe
  2. 安装Python依赖:执行 pip install pytesseract pillow pandas openpyxl
  3. 新建脚本 OCR识别.py,粘贴下方代码
  4. 修改tesseract路径:将代码中的 pytesseract.pytesseract.tesseract_cmd 改成你的安装路径
  5. 把扫描件图片放到文件夹中(支持jpg/png/tiff格式)
  6. 运行脚本:执行 python OCR识别.py
  7. 检查识别结果:生成 OCR识别结果.xlsx,每张图片识别的文字分段保存
import pytesseract from PIL import Image import pandas as pd import os from pathlib import Path # ===== 配置 ===== # Tesseract安装路径(根据实际安装位置修改) pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe" input_folder = r"C:\扫描件图片" # 扫描件图片文件夹 output_file = "OCR识别结果.xlsx" # 支持的语言:chi_sim=简体中文, eng=英文, chi_sim+eng=中英混合 OCR_LANG = "chi_sim+eng" supported = (".jpg", ".jpeg", ".png", ".tiff", ".tif", ".bmp") # 获取图片文件 image_files = [f for f in Path(input_folder).iterdir() if f.suffix.lower() in supported] if not image_files: print("❌ 未找到图片文件") exit() print(f"📋 找到 {len(image_files)} 张图片") results = [] for idx, img_path in enumerate(image_files, 1): try: print(f"⏳ [{idx}/{len(image_files)}] 正在识别: {img_path.name}") # 打开图片 img = Image.open(img_path) # 图片预处理:转为灰度图,提高识别率 img = img.convert("L") # 调整对比度(可选) # from PIL import ImageEnhance # enhancer = ImageEnhance.Contrast(img) # img = enhancer.enhance(2.0) # 执行OCR识别 text = pytesseract.image_to_string(img, lang=OCR_LANG) # 清洗结果 lines = [line.strip() for line in text.split("\n") if line.strip()] results.append({ "文件名": img_path.name, "识别文字": "\n".join(lines), "行数": len(lines), "状态": "成功" }) print(f"✅ 识别完成: {len(lines)} 行文字") except Exception as e: results.append({ "文件名": img_path.name, "识别文字": "", "行数": 0, "状态": f"失败: {str(e)}" }) print(f"❌ 识别失败 {img_path.name}: {str(e)}") # 输出Excel df = pd.DataFrame(results) df.to_excel(output_file, index=False, engine='openpyxl') success_count = sum(1 for r in results if r["状态"] == "成功") print(f"\n🎉 OCR识别完成!") print(f"📁 输出: {output_file}") print(f"📊 成功: {success_count}/{len(results)} 张") # 显示前3张的识别内容预览 print("\n📝 识别预览:") for r in results[:3]: if r["状态"] == "成功": preview = r["识别文字"][:100].replace("\n", " | ") print(f" 📄 {r['文件名']}: {preview}...")
💡 免费在线OCR方案(不需编程):
如果不想安装软件,也可以直接用在线工具:
1. 百度OCR免费版: ai.baidu.com/tech/ocr — 每天500次免费识别
2. QQ截图OCR: Ctrl+Alt+A 截图 → 点击"文"字图标即可识别文字
3. WPS内置OCR:WPS Office自带图片转文字功能
🔗

痛点 ⇄ 课程 双向映射表

遇到问题不知道学哪个课程?学完课程不知道能解决什么问题?这个映射表帮你快速定位。
🔍 痛点📘 对应课程📖 阶段⭐ 难度
批量改文件名/整理文件第一个Python脚本 + 文件夹整理工具阶段1 工具容易
合并多个Excel报表自动化Excel报表生成器 + 多表数据合并工具阶段2 工具容易
数据去重/清洗/格式化数据去重清洗工具 + 数据格式统一工具工具 阶段2容易
批量压缩/裁剪图片AI辅助图片批量处理 + 图片批量处理工具阶段1 工具容易
PDF文本提取PDF数据提取工具工具容易
文字识别OCROCR文字识别工具 + 纸质档案数字化工具 阶段3容易
Word模板批量生成Word模板批量生成工具 + 模块A2 Word/PDF自动化工具 阶段3容易
薪酬个税计算薪税计算器工具工具容易
VLOOKUP模糊匹配智能VLOOKUP合并工具工具中等
工资条/通知单拆分模块A1 Excel自动化阶段3中等
PDF表格提取模块A2 Word/PDF自动化阶段3中等
自动发邮件/通知模块A3 邮件/通知自动化阶段3中等
网页数据采集模块A4 数据采集与清洗 + 网页数据抓取工具阶段3 工具中等
农产品价格分析农产品价格趋势图 + 数据可视化阶段2中等
财务数据透视分析财务数据透视分析表阶段2较难
搭建自动化报表系统模块A5 定时任务与报表系统 + 智能报表系统阶段3较难
AI客服/知识库问答保康文旅问答Bot + 方向B AI客服Bot阶段2 阶段3较难
公文格式自动排版公文格式排版助手工具 + 编辑助手工具较难
进销存/库存管理方向C 低代码企业管理系统阶段3较难
企业综合数据看板方向B 数据看板 + Flask阶段3困难
全流程办公自动化模块A6 综合项目·办公提效工具箱阶段3困难