在日常工作中,我们经常要做重复的办公任务:批量处理几十份Excel表格、批量生成合同、从PDF中提取数据……这些工作耗时且容易出错。而Python能帮我们实现“自动化办公”——用代码批量处理Excel、Word和PDF,把1小时的工作缩短到1分钟。这篇我们就聚焦三个核心场景:批量处理Excel数据自动生成Word文档提取PDF内容并汇总,每个场景都提供可直接复用的代码,让你快速上手提升工作效率。

一、准备工作:安装办公自动化库

需要安装3类处理不同文件的库(打开终端/命令提示符执行):

# 处理Excel(pandas/openpyxl:读写.xlsx文件)
# 处理Word(python-docx:读写.docx文件)
# 处理PDF(PyPDF2:合并/分割PDF;pdfplumber:提取PDF文本和表格)
pip install pandas openpyxl python-docx PyPDF2 pdfplumber

二、场景1:批量处理Excel数据(最常用!)

Excel是办公高频工具,我们以“批量计算销售业绩+标记达标人员”为例,学习用pandas(数据处理)和openpyxl(写入Excel)处理表格。

需求说明

假设有“销售数据.xlsx”,包含3列:姓名、销售额、目标额,需要:

  1. 计算每个人的完成率(销售额/目标额);
  2. 标记完成率≥100%的人员为“达标”,否则为“未达标”;
  3. 按完成率从高到低排序;
  4. 保存到新文件“销售业绩分析.xlsx”。

示例数据(销售数据.xlsx)

姓名 销售额(元) 目标额(元)
张三 12000 10000
李四 8000 10000
王五 15000 12000
赵六 9500 9000

代码实现

import pandas as pd
import logging
from openpyxl.styles import Font, Alignment  # 用于设置Excel单元格样式

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

def process_sales_data(input_file, output_file):
    """
    批量处理销售数据Excel,计算完成率并标记达标情况
    参数:
        input_file:输入Excel文件路径(如"销售数据.xlsx")
        output_file:输出Excel文件路径(如"销售业绩分析.xlsx")
    返回:处理成功返回True,失败返回False
    """
    try:
        logging.info(f"开始处理Excel文件:{input_file}")
        
        # 1. 读取Excel数据(pandas的read_excel支持.xlsx格式)
        # sheet_name:指定工作表名称(默认第一个);header=0:第一行为表头
        df = pd.read_excel(input_file, sheet_name="Sheet1", header=0)
        
        # 检查必要的列是否存在
        required_columns = ["姓名", "销售额(元)", "目标额(元)"]
        if not all(col in df.columns for col in required_columns):
            logging.error(f"Excel文件缺少必要的列,需要:{required_columns}")
            print(f"❌ 错误:Excel文件必须包含列:{required_columns}")
            return False
        
        # 2. 批量计算完成率(销售额/目标额,保留2位小数)
        # 避免除以0错误:若目标额为0,完成率设为0
        df["完成率(%)"] = df.apply(
            lambda row: round(row["销售额(元)"] / row["目标额(元)"] * 100, 2) 
            if row["目标额(元)"] != 0 else 0,
            axis=1  # axis=1表示按行处理
        )
        
        # 3. 标记达标情况(完成率≥100%为达标)
        df["达标情况"] = df["完成率(%)"].apply(lambda x: "达标" if x >= 100 else "未达标")
        
        # 4. 按完成率从高到低排序(降序)
        df = df.sort_values(by="完成率(%)", ascending=False).reset_index(drop=True)
        
        # 5. 保存到新Excel(用openpyxl引擎支持后续样式设置)
        with pd.ExcelWriter(output_file, engine="openpyxl") as writer:
            df.to_excel(writer, sheet_name="业绩分析", index=False)  # index=False:不保存行索引
            
            # 6. 美化表格(设置表头样式:加粗、居中)
            worksheet = writer.sheets["业绩分析"]  # 获取工作表对象
            header_font = Font(bold=True, color="000000")  # 表头字体:加粗、黑色
            header_alignment = Alignment(horizontal="center", vertical="center")  # 居中对齐
            
            # 遍历表头单元格(第一行),应用样式
            for cell in worksheet[1]:  # worksheet[1]表示第一行(Excel行号从1开始)
                cell.font = header_font
                cell.alignment = header_alignment
            
            # 调整列宽(根据内容自动调整)
            for column in worksheet.columns:
                max_length = 0
                column_letter = column[0].column_letter  # 获取列字母(如A、B)
                for cell in column:
                    try:
                        if len(str(cell.value)) > max_length:
                            max_length = len(cell.value)
                    except:
                        pass
                adjusted_width = (max_length + 2) * 1.2  # 适当加宽
                worksheet.column_dimensions[column_letter].width = adjusted_width
        
        logging.info(f"Excel处理完成,已保存到:{output_file}")
        print(f"\n✅ 处理成功!生成文件:{output_file}")
        print(f"  共处理{len(df)}条数据,达标{len(df[df['达标情况']=='达标'])}人,未达标{len(df[df['达标情况']=='未达标'])}人")
        return True
    
    except FileNotFoundError:
        logging.error(f"输入文件不存在:{input_file}")
        print(f"❌ 错误:文件{input_file}不存在,请检查路径!")
        return False
    
    except Exception as e:
        logging.error(f"Excel处理错误:{e}", exc_info=True)
        print(f"❌ 处理失败:{e},请查看日志获取详情")
        return False

# 执行处理(替换为你的文件路径)
if __name__ == "__main__":
    process_sales_data(
        input_file="销售数据.xlsx",
        output_file="销售业绩分析.xlsx"
    )

运行效果

生成的“销售业绩分析.xlsx”会新增“完成率(%)”和“达标情况”列,表头加粗居中,列宽自动适配内容,无需手动调整格式。

三、场景2:自动生成Word文档(批量出合同/报告)

很多工作需要生成大量格式相同、内容略有差异的Word文档(如合同、通知书)。我们以“批量生成员工工资条”为例,用python-docx实现:先制作模板,再替换模板中的占位符,生成个性化文档。

步骤1:制作Word模板(工资条模板.docx)

新建一个Word文档,用{{占位符}}标记需要替换的内容,例如:

工资条

姓名:{{姓名}}
部门:{{部门}}
职位:{{职位}}
基本工资:{{基本工资}}元
绩效工资:{{绩效工资}}元
应发合计:{{应发合计}}元
发放日期:{{发放日期}}

—— 人力资源部 ——

保存为“工资条模板.docx”,放在项目文件夹中。

步骤2:准备数据(员工信息.xlsx)

用Excel存储需要替换的内容,格式如下:

姓名 部门 职位 基本工资 绩效工资
张三 技术部 开发工程师 8000 2000
李四 市场部 专员 6000 1500
王五 财务部 会计 7000 1000

步骤3:代码实现(批量生成工资条)

import docx
from docx.shared import Pt, RGBColor  # 用于设置字体样式
from docx.enum.text import WD_ALIGN_PARAGRAPH  # 用于设置段落对齐
import pandas as pd
import os
from datetime import datetime

def generate_word_from_template(template_path, data, output_dir="工资条"):
    """
    根据Word模板和数据,批量生成个性化Word文档
    参数:
        template_path:模板文件路径(如"工资条模板.docx")
        data:包含替换数据的列表(每个元素为字典,键是占位符,值是替换内容)
        output_dir:生成文件的保存目录(默认"工资条")
    """
    try:
        # 创建输出目录(若不存在)
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)
            logging.info(f"创建输出目录:{output_dir}")
        
        # 获取当前日期(作为发放日期)
        pay_date = datetime.now().strftime("%Y年%m月%d日")
        
        # 循环处理每条数据,生成对应的Word文档
        for idx, item in enumerate(data, 1):
            # 1. 打开模板文件
            doc = docx.Document(template_path)
            
            # 2. 替换所有占位符(遍历文档中的所有段落和表格)
            # 2.1 处理段落中的占位符
            for para in doc.paragraphs:
                for run in para.runs:  # run是段落中的文本片段
                    # 遍历所有需要替换的占位符
                    for key, value in item.items():
                        placeholder = f"{{{{{key}}}}}"  # 构建占位符(如{{姓名}})
                        if placeholder in run.text:
                            # 替换文本
                            run.text = run.text.replace(placeholder, str(value))
                            # 设置字体样式(可选:统一字体为微软雅黑,大小10.5pt)
                            run.font.name = "微软雅黑"
                            run.font.size = Pt(10.5)
            
            # 2.2 处理表格中的占位符(如果模板有表格)
            for table in doc.tables:
                for row in table.rows:
                    for cell in row.cells:
                        for para in cell.paragraphs:
                            for run in para.runs:
                                for key, value in item.items():
                                    placeholder = f"{{{{{key}}}}}"
                                    if placeholder in run.text:
                                        run.text = run.text.replace(placeholder, str(value))
                                        run.font.name = "微软雅黑"
                                        run.font.size = Pt(10.5)
            
            # 3. 替换发放日期(单独处理,所有文档日期相同)
            for para in doc.paragraphs:
                for run in para.runs:
                    if "{{发放日期}}" in run.text:
                        run.text = run.text.replace("{{发放日期}}", pay_date)
                        run.font.name = "微软雅黑"
            
            # 4. 计算应发合计(基本工资+绩效工资)
            for para in doc.paragraphs:
                for run in para.runs:
                    if "{{应发合计}}" in run.text:
                        total = item["基本工资"] + item["绩效工资"]
                        run.text = run.text.replace("{{应发合计}}", str(total))
                        run.font.name = "微软雅黑"
                        run.font.bold = True  # 应发合计加粗
                        run.font.color.rgb = RGBColor(192, 0, 0)  # 红色
            
            # 5. 设置标题居中(第一个段落是标题“工资条”)
            doc.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
            doc.paragraphs[0].runs[0].font.size = Pt(14)  # 标题字号加大
            doc.paragraphs[0].runs[0].font.bold = True  # 标题加粗
            
            # 6. 保存生成的文档(文件名:姓名_工资条.docx)
            output_filename = f"{item['姓名']}_工资条.docx"
            output_path = os.path.join(output_dir, output_filename)
            doc.save(output_path)
            logging.info(f"生成第{idx}个文档:{output_path}")
        
        print(f"\n✅ 批量生成完成!共生成{len(data)}个Word文档")
        print(f"  保存路径:{os.path.abspath(output_dir)}")
        return True
    
    except FileNotFoundError:
        logging.error(f"模板文件不存在:{template_path}")
        print(f"❌ 错误:模板文件{template_path}不存在!")
        return False
    
    except Exception as e:
        logging.error(f"生成Word文档错误:{e}", exc_info=True)
        print(f"❌ 生成失败:{e}")
        return False

# 完整流程:读取Excel数据→生成工资条
if __name__ == "__main__":
    # 1. 读取员工数据Excel
    excel_path = "员工信息.xlsx"
    try:
        df = pd.read_excel(excel_path)
        # 转换为字典列表(每个字典对应一条员工信息)
        employee_data = df.to_dict("records")
        logging.info(f"成功读取{len(employee_data)}条员工数据")
    except Exception as e:
        logging.error(f"读取员工数据失败:{e}")
        print(f"❌ 读取员工数据失败:{e}")
        exit(1)
    
    # 2. 批量生成工资条
    generate_word_from_template(
        template_path="工资条模板.docx",
        data=employee_data,
        output_dir="2024年6月工资条"
    )

运行效果

在“2024年6月工资条”文件夹中,会生成每个人的工资条文档,格式统一,姓名、部门等信息自动替换,应发合计自动计算并标红加粗,无需手动修改。

四、场景3:提取PDF内容(文字+表格)并汇总到Excel

PDF是办公中常用的格式,但直接编辑困难。我们以“提取多份PDF简历中的姓名、电话、工作经历”为例,用pdfplumber提取内容,再用pandas汇总到Excel。

代码实现(PDF内容提取)

import pdfplumber
import pandas as pd
import os
import re  # 用于正则表达式匹配(提取电话等)

def extract_pdf_info(pdf_path):
    """
    从单份PDF简历中提取关键信息
    参数:pdf_path - PDF文件路径
    返回:包含关键信息的字典
    """
    info = {
        "文件名": os.path.basename(pdf_path),
        "姓名": "未找到",
        "电话": "未找到",
        "工作经历": "未找到"
    }
    
    try:
        with pdfplumber.open(pdf_path) as pdf:
            # 1. 提取所有页的文本(合并为一个字符串)
            full_text = ""
            for page in pdf.pages:
                page_text = page.extract_text()  # 提取单页文本
                if page_text:
                    full_text += page_text + "\n"  # 页间加换行
            
            # 2. 提取姓名(假设姓名在"个人简历"或"简历"附近,且是2-4个汉字)
            name_pattern = re.compile(r"[简历|个人简历]\s*([\u4e00-\u9fa5]{2,4})")
            name_match = name_pattern.search(full_text)
            if name_match:
                info["姓名"] = name_match.group(1).strip()
            
            # 3. 提取电话(11位手机号)
            phone_pattern = re.compile(r"1[3-9]\d{9}")
            phone_match = phone_pattern.search(full_text)
            if phone_match:
                info["电话"] = phone_match.group()
            
            # 4. 提取工作经历(包含"工作经历"或"工作经验"后的内容,取前500字)
            experience_pattern = re.compile(r"(工作经历|工作经验)\s*(.*?)(教育背景|项目经验|技能证书)", re.DOTALL)
            experience_match = experience_pattern.search(full_text)
            if experience_match:
                experience = experience_match.group(2).strip()
                info["工作经历"] = experience[:500]  # 限制长度,避免内容过长
            
            logging.info(f"成功提取PDF信息:{info['文件名']}(姓名:{info['姓名']})")
            return info
    
    except Exception as e:
        logging.error(f"提取PDF {pdf_path} 失败:{e}")
        print(f"⚠️  提取{os.path.basename(pdf_path)}失败:{e}")
        return info

def batch_extract_pdfs(pdf_dir, output_excel="简历信息汇总.xlsx"):
    """
    批量提取指定目录下所有PDF的信息,汇总到Excel
    参数:
        pdf_dir:存放PDF的目录
        output_excel:汇总结果的Excel路径
    """
    # 1. 获取目录下所有PDF文件
    pdf_files = []
    for filename in os.listdir(pdf_dir):
        if filename.lower().endswith(".pdf"):
            pdf_path = os.path.join(pdf_dir, filename)
            pdf_files.append(pdf_path)
    
    if not pdf_files:
        logging.warning(f"目录{pdf_dir}下未找到PDF文件")
        print(f"⚠️  未在{pdf_dir}找到任何PDF文件!")
        return False
    
    logging.info(f"发现{len(pdf_files)}个PDF文件,开始批量提取")
    
    # 2. 批量提取每个PDF的信息
    all_info = []
    for pdf_path in pdf_files:
        info = extract_pdf_info(pdf_path)
        all_info.append(info)
    
    # 3. 保存到Excel
    df = pd.DataFrame(all_info)
    df.to_excel(output_excel, index=False, engine="openpyxl")
    logging.info(f"PDF信息汇总完成,保存到:{output_excel}")
    print(f"\n✅ 批量提取完成!共处理{len(pdf_files)}个PDF")
    print(f"  汇总结果:{output_excel}")
    return True

# 执行批量提取(替换为你的PDF目录)
if __name__ == "__main__":
    batch_extract_pdfs(
        pdf_dir="简历文件夹",  # 存放PDF简历的文件夹
        output_excel="简历信息汇总.xlsx"
    )

运行效果

程序会扫描“简历文件夹”中的所有PDF,提取姓名、电话、工作经历,汇总到“简历信息汇总.xlsx”,无需逐个打开PDF复制粘贴,尤其适合处理几十上百份简历的场景。

五、自动化办公实用技巧

  1. 文件路径处理:用os.path模块处理路径(如os.path.join拼接路径、os.path.exists检查文件是否存在),避免因Windows/Linux路径格式差异导致错误。
  2. 异常处理:办公文件常出现格式错误(如损坏的Excel、加密的PDF),务必用try-except捕获异常,避免程序崩溃。
  3. 批量操作逻辑:批量处理的核心是“循环+函数”——用函数封装单个文件的处理逻辑,用循环遍历所有文件,代码更清晰。
  4. 格式简化:复杂的Excel/Word格式(如宏、复杂图表)可能导致处理失败,尽量用简单格式(纯文本、基础表格)。

总结

这篇我们掌握了办公自动化的核心技能,覆盖Excel、Word、PDF三大场景:

  1. Excel处理:用pandas批量计算、筛选、排序数据,openpyxl美化格式;
  2. Word生成:通过“模板+占位符”模式,用python-docx批量生成个性化文档;
  3. PDF提取:用pdfplumber提取文本和表格,正则表达式匹配关键信息。

这些技能能直接应用于实际工作,解决“重复劳动”痛点。下一篇我们将学习“Python小工具开发”,把这些功能打包成可双击运行的程序,甚至分享给不懂代码的同事使用!

更多推荐