python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python办公自动化

Python办公自动化之Excel/Word/PDF实战完整教学

作者:菩提风

本文将为大家分享一套生产就绪的Python办公自动化工程包,覆盖Excel、Word、PDF三大高频文档的程序化处理,内容包括环境隔离、核心库选型、UUID注入、按列拆分Excel等内容,希望对大家有所帮助

简介:本资源是一份面向零基础学习者与职场办公人员的Python自动化办公实战指南,聚焦Excel、Word、PDF、PPT及CSV等高频办公文档的程序化处理,解决重复性文档操作效率低、跨格式数据整合难等实际问题。压缩包为RAR格式,共包含百余个结构化文件,以PDF教程、代码脚本、学习笔记和案例源码为主——其中PDF覆盖五大核心模块(PDF/PPT/Excel处理篇+综合学习笔记+案例集锦),代码示例可直接运行调试,笔记详述关键API用法与典型报错解决方案,案例均来自真实办公场景。资源大小102.94MB,目录层级清晰,便于按需检索各模块内容。目前已有202人下载学习,适合希望系统掌握Python办公自动化技能、快速提升文档处理效率的初学者与转岗技术人员。

1. Python办公自动化:Excel、Word、PDF等集合PDF完整版最新版本

你有没有遇到过这种场景:财务同事凌晨三点发来27个Excel,要求把每张表里“客户编号”列统一补全UUID,再按地区拆成子表,最后合并生成带目录的PDF报告,附上Word版摘要——而你手头只有Excel双击打开、Ctrl+C/V、打印另存为PDF这三板斧?这不是效率问题,是工具链断层。这份被误称为“PDF完整版”的资源,本质是一套经过真实业务压测的Python办公自动化工程包:它不教print("Hello World"),而是直接给你 excel_to_pdf_pipeline.py 、 word_template_filler.py 、 pdf_merge_with_bookmarks.py 三个主力脚本,配套12个真实数据样例(含带合并单元格的财务报表、含OLE对象的旧版Word、含扫描件图层的PDF),所有依赖已锁定在 requirements.txt 里,连 openpyxl==3.1.2 和 python-docx==1.1.2 的兼容性坑都提前填好了。适合两类人:一是被重复报表压得喘不过气的业务岗(行政/HR/财务),想用5行代码替代2小时手工;二是刚学完基础语法的转行者,需要一个能立刻跑通、看到结果、还能反向拆解的“生产级样板”。别被标题里的“PDF完整版”误导——它最值钱的部分,是那个能让你在Windows/Mac/Linux上一键复现的 ./scripts/run_all.bat (或 ./scripts/run_all.sh )。

2. 从零启动:环境隔离、依赖安装与核心模块选型逻辑

2.1 为什么必须用venv隔离环境?——避开Office COM组件与现代库的版本战争

很多初学者直接 pip install openpyxl python-docx PyPDF2 ,结果在Windows上跑 win32com 时爆红,或在Mac上因 pypdf 和 PyPDF2 混装导致PDF页码错乱。这不是你的错,是办公自动化特有的“生态撕裂”:

本项目采用 分层选型策略 :

提示:项目根目录下 env_setup.md 文件详细记录了各系统(Win10/11, macOS Sonoma, Ubuntu 22.04)的venv创建命令。Windows用户务必注意:PowerShell需先执行 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser 解除脚本限制,否则 run_all.ps1 会报错。

2.2 三步完成环境初始化:命令、验证与常见失败点

步骤1:创建并激活虚拟环境(以Windows PowerShell为例)

# 进入项目根目录(含requirements.txt的位置)
cd C:\path\to\your\project
# 创建名为venv的虚拟环境
python -m venv venv
# 激活虚拟环境(PowerShell)
venv\Scripts\Activate.ps1
# 若提示执行策略被禁止,运行以下命令后再激活
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

逻辑说明 : python -m venv venv 调用Python内置venv模块,在当前目录下创建独立环境。 Activate.ps1 是PowerShell专用激活脚本, .bat 文件用于CMD, source venv/bin/activate 用于Linux/macOS。激活后命令行前缀会显示 (venv) ,表示已进入隔离环境。

步骤2:安装锁定依赖

pip install --upgrade pip
pip install -r requirements.txt

参数说明 :

步骤3:验证核心模块是否可用

# 在Python交互式环境中执行
import openpyxl
import docx
from pypdf import PdfReader

# 测试Excel读取
wb = openpyxl.load_workbook("samples/excel/sample_data.xlsx")
print(f"Excel加载成功,工作表数:{len(wb.sheetnames)}")

# 测试Word读取
from docx import Document
doc = Document("samples/word/sample_contract.docx")
print(f"Word加载成功,段落数:{len(doc.paragraphs)}")

# 测试PDF读取
reader = PdfReader("samples/pdf/sample_invoice.pdf")
print(f"PDF加载成功,页数:{len(reader.pages)}")

预期输出 :三行 加载成功 信息。若某行报错(如 ModuleNotFoundError: No module named 'docx' ),说明 python-docx 未正确安装,需检查是否在激活的venv中执行 pip install 。

2.3 避坑:办公自动化环境的五大血泪现场

现象1:ImportError: No module named 'win32api'(Windows专属)

原因 : xlwings 或某些旧版 comtypes 依赖 pywin32 ,但 pip install xlwings 未自动安装它,或安装后未运行 python Scripts/pywin32_postinstall.py -install 注册COM组件。
解决 :在venv中执行

pip install pywin32
python Scripts/pywin32_postinstall.py -install

注意: Scripts/ 目录在venv内,路径为 venv\Scripts\ (Windows)或 venv/bin/ (macOS/Linux)。

现象2:Mac上python-docx保存文件后,Word提示“文件已损坏”

原因 :macOS默认文件系统(APFS)对文件权限处理严格, python-docx 生成的临时文件可能因权限不足无法写入。

解决 :在保存前显式设置权限

from docx import Document
import os

doc = Document()
# ... 添加内容
output_path = "output/report.docx"
doc.save(output_path)
os.chmod(output_path, 0o644)  # 设置为可读可写

现象3:pypdf读取扫描版PDF时报PdfReadError: Invalid object ID

原因 :扫描PDF本质是图片,无文本层, pypdf 尝试解析文本结构失败。

解决 :改用 pdfplumber 提取图像区域,或先用OCR工具(如Tesseract)预处理。本项目 utils/pdf_scanner_handler.py 提供封装函数:

from utils.pdf_scanner_handler import extract_text_from_scanned_pdf
text = extract_text_from_scanned_pdf("samples/pdf/scanned_receipt.pdf", ocr_lang="chi_sim")

现象4:openpyxl读取含公式Excel时,cell.value返回None

原因 : openpyxl 默认只读取存储值,不计算公式。需启用 data_only=False (读取公式)或 data_only=True (读取计算结果)。

解决 :根据需求选择加载模式

# 读取公式本身(用于审计)
wb = openpyxl.load_workbook("formulas.xlsx", data_only=False)

# 读取公式计算结果(常用)
wb = openpyxl.load_workbook("formulas.xlsx", data_only=True)

现象5:python-docx插入图片后,Word中图片显示为“X”,且文档体积暴增

原因 :默认插入方式将图片二进制数据直接嵌入XML,未压缩。

解决 :使用 document.add_picture() 时指定 width / height ,并启用 python-docx 的压缩选项(需v1.1.0+):

from docx.shared import Inches
# 插入时指定尺寸,自动触发压缩
doc.add_picture("chart.png", width=Inches(6.0))
# 或手动压缩(高级用法)
from docx.oxml import parse_xml
from docx.oxml.ns import nsdecls
# (详见utils/docx_compressor.py)

3. Excel自动化实战:UUID注入、条件拆分与跨表联动

3.1 给Excel“客户编号”列批量注入UUID:不只是随机字符串

业务场景:销售部每月导出CRM数据为Excel,但“客户编号”列为空,需按规则生成唯一标识(非简单 uuid.uuid4() ,需兼容数据库主键长度且可读性可控)。本项目 excel_uuid_injector.py 提供三种策略:

# excel_uuid_injector.py 核心逻辑
import uuid
import base64
import time

def generate_short_uuid():
    """生成12位Base32短UUID"""
    uid = uuid.uuid4().bytes[:8]  # 取前8字节保证唯一性
    return base64.b32encode(uid).decode('ascii').replace('=', '')[:12]

def generate_timestamp_uuid(prefix="CUST"):
    """生成时间戳+随机码格式"""
    timestamp = time.strftime("%Y%m%d")
    random_part = str(uuid.uuid4().hex[:4]).upper()
    return f"{prefix}-{timestamp}-{random_part}"

# 应用到Excel指定列
from openpyxl import load_workbook

wb = load_workbook("input/sales_data.xlsx")
ws = wb.active

# 假设客户编号在B列,从第2行开始(跳过标题)
for row in range(2, ws.max_row + 1):
    if not ws[f"B{row}"].value:  # 仅填充空单元格
        ws[f"B{row}"].value = generate_short_uuid()

wb.save("output/sales_data_with_uuid.xlsx")

参数说明 :

3.2 按“地区”列自动拆分Excel为多个子表:保留原格式与公式

痛点:财务报表需按“华东/华北/华南”拆分发送给各区域经理,但原始Excel含复杂公式、条件格式、图表。 openpyxl 直接复制工作表会丢失图表( openpyxl 不支持图表对象),而 xlwings 又依赖本地Excel。本方案采用 公式冻结+样式继承 策略:

# excel_splitter.py
from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill, Border, Side

def split_by_column(input_path, output_dir, split_column="地区", header_row=1):
    wb = load_workbook(input_path)
    ws = wb.active
    
    # 获取所有唯一地区值
    regions = set()
    for row in range(header_row + 1, ws.max_row + 1):
        region = ws[f"{split_column}{row}"].value
        if region:
            regions.add(str(region))
    
    # 为每个地区创建新工作簿
    for region in regions:
        new_wb = load_workbook(input_path)  # 复制原始模板(含公式/样式)
        new_ws = new_wb.active
        
        # 删除非目标地区行(从底向上删,避免索引错乱)
        rows_to_delete = []
        for row in range(ws.max_row, header_row, -1):  # 从最后一行倒序
            if str(ws[f"{split_column}{row}"].value) != region:
                rows_to_delete.append(row)
        
        for row in rows_to_delete:
            new_ws.delete_rows(row)
        
        # 保存为独立文件
        output_path = f"{output_dir}/{region}_销售报表.xlsx"
        new_wb.save(output_path)
        print(f"已生成:{output_path}")

# 调用示例
split_by_column(
    input_path="samples/excel/quarterly_report.xlsx",
    output_dir="output/region_split",
    split_column="地区",  # 支持中文列名
    header_row=1
)

关键设计 :

3.3 跨Excel文件联动:用openpyxl实现“主表驱动子表更新”

场景:总部有一份 master_budget.xlsx (含各部门预算总额),各子公司有 sub_budget_2024.xlsx (含明细)。当总部调整总额,需自动按比例重算子公司明细。传统做法是手动复制粘贴,易出错。本方案通过 openpyxl 读取主表,计算缩放系数,写入子表:

# budget_sync.py
from openpyxl import load_workbook

def sync_budget(master_path, sub_paths, master_total_cell="B2", sub_ratio_cell="C1"):
    """
    主表B2为总预算,子表C1为分配比例(如0.15表示15%)
    """
    # 读取主表总预算
    master_wb = load_workbook(master_path, data_only=True)
    master_ws = master_wb.active
    total_budget = master_ws[master_total_cell].value
    
    # 遍历每个子公司文件
    for sub_path in sub_paths:
        sub_wb = load_workbook(sub_path)
        sub_ws = sub_wb.active
        
        # 读取子表比例
        ratio = sub_ws[sub_ratio_cell].value
        if not isinstance(ratio, (int, float)) or ratio <= 0:
            print(f"警告:{sub_path}中{sub_ratio_cell}比例无效,跳过")
            continue
        
        # 计算子公司应得预算 = 总预算 × 比例
        allocated = total_budget * ratio
        
        # 写入子表指定单元格(如D2为“核定预算”)
        sub_ws["D2"] = allocated
        sub_wb.save(sub_path)
        print(f"已同步:{sub_path} → 核定预算={allocated:.2f}")

# 调用示例
sync_budget(
    master_path="samples/excel/master_budget.xlsx",
    sub_paths=[
        "samples/excel/sub_budget_beijing.xlsx",
        "samples/excel/sub_budget_shanghai.xlsx"
    ],
    master_total_cell="B2",
    sub_ratio_cell="C1"
)

边界处理 :

4. Word自动化:模板填充、公式转换与批量生成

4.1 用docxtpl实现合同/报告批量生成:告别复制粘贴

python-docx 适合修改现有文档,但生成结构化文档(如合同、周报)效率低。 docxtpl 基于Jinja2模板引擎,允许在Word中插入 {{ variable }} 和 {% for item in items %} ,本项目 templates/contract_template.docx 已预置占位符:

<!-- contract_template.docx 中的XML片段(实际不可见,由docxtpl渲染) -->
<p>甲方:{{ party_a }}</p>
<p>乙方:{{ party_b }}</p>
<table>
  {% for item in service_items %}
  <tr>
    <td>{{ item.name }}</td>
    <td>{{ item.price | currency }}</td>
  </tr>
  {% endfor %}
</table>
# word_template_filler.py
from docxtpl import DocxTemplate
import json

def fill_contract(template_path, context_json, output_path):
    """
    context_json: {"party_a": "北京科技有限公司", "party_b": "上海咨询公司", 
                   "service_items": [{"name": "系统开发", "price": 150000}]}
    """
    template = DocxTemplate(template_path)
    with open(context_json, 'r', encoding='utf-8') as f:
        context = json.load(f)
    
    # 自定义过滤器:金额转为中文大写
    def to_currency(amount):
        # 实现人民币大写转换(简化版)
        digits = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"]
        units = ["", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿"]
        # (完整实现见utils/currency_converter.py)
        return f"¥{amount:,.2f}"
    
    template.register_filter('currency', to_currency)
    template.render(context)
    template.save(output_path)

# 调用示例
fill_contract(
    template_path="templates/contract_template.docx",
    context_json="data/contract_context.json",
    output_path="output/contract_signed.docx"
)

优势对比 :

方案开发速度模板维护动态逻辑表格生成
python-docx 硬编码慢(每字段写add_paragraph)困难(改代码)弱(需if/else)需手动循环add_table
docxtpl 模板驱动快(改Word即可)简单(Word编辑)强(Jinja2语法){% for %} 自动渲染

4.2 Word公式转LaTeX:解决技术文档公式迁移难题

痛点:工程师用Word写技术方案,含大量公式(如 E=mc² ),但需转为LaTeX发布到学术平台。 python-docx 无法解析公式XML结构,本项目采用 docx2python 库提取原始OMML(Office Math Markup Language),再用 omml2mathml 转换为MathML,最终转LaTeX:

# word_formula_converter.py
from docx2python import docx2python
import re

def extract_formulas(docx_path):
    """提取Word中所有公式(OMML格式)"""
    docx_content = docx2python(docx_path)
    formulas = []
    
    # 遍历所有段落和表格单元格
    for paragraph in docx_content.body:
        if hasattr(paragraph, 'math') and paragraph.math:
            formulas.append(paragraph.math)
    
    for table in docx_content.tables:
        for row in table:
            for cell in row:
                if hasattr(cell, 'math') and cell.math:
                    formulas.append(cell.math)
    
    return formulas

def omml_to_latex(omml_str):
    """简化版OMML转LaTeX(真实项目用omml2mathml + mathml2latex)"""
    # 示例:将 <m:oMath><m:r><m:t>E=mc^2</m:t></m:r></m:oMath> → "E=mc^2"
    clean = re.sub(r'<[^>]+>', '', omml_str)  # 去除XML标签
    # 实际需解析OMML节点,此处仅示意
    return clean.replace('^', '**').replace('_', '\\_')  # 基础符号映射

# 调用流程
formulas = extract_formulas("samples/word/tech_proposal.docx")
for i, omml in enumerate(formulas):
    latex = omml_to_latex(omml)
    print(f"公式{i+1}: {latex}")

注意事项 :

4.3 避坑:Word自动化中的三大“静默失败”

现象1:docxtpl生成的Word打开后提示“发现错误,尝试恢复”

原因 :模板中存在未闭合的Jinja2标签(如 {{ name 漏掉 }} )或非法XML字符(如 & 未转义为 &amp; )。

解决 :

使用 docxtpl 的 strict 模式捕获语法错误

template = DocxTemplate(template_path)
try:
    template.render(context, autoescape=True)  # autoescape防止XML注入
except Exception as e:
    print(f"模板渲染失败:{e}")
    # 检查模板中所有{{ }}和{% %}是否配对

现象2:python-docx插入表格后,Word中列宽自动收缩为0

原因 : python-docx 默认表格无宽度设置,Word按内容自适应,窄内容导致列宽塌陷。

解决 :显式设置列宽(单位:EMU,1英寸=914400 EMU)

from docx.shared import Inches

table = doc.add_table(rows=1, cols=3)
# 设置列宽:第一列2英寸,第二列1.5英寸,第三列1英寸
table.columns[0].width = Inches(2.0)
table.columns[1].width = Inches(1.5)
table.columns[2].width = Inches(1.0)

现象3:Word宏安全设置阻止xlwings调用Excel

原因 : xlwings 需通过COM调用Excel,但Office默认禁用所有宏,且 python-docx 生成的文档可能被误判为含宏。

解决 :

try:
    import xlwings as xw
    app = xw.App(visible=False)
    # ... 执行操作
except Exception as e:
    print("Excel COM调用失败,请检查Office是否安装及宏设置")
    # 降级为openpyxl处理

5. PDF自动化:合并、加水印与OCR增强

5.1 合并PDF并添加书签:让20页报告秒变可导航文档

pypdf 的 PdfWriter 支持合并,但默认无书签。本项目 pdf_merger.py 在合并时为每个源文件添加顶层书签,并支持二级书签(如按章节):

# pdf_merger.py
from pypdf import PdfReader, PdfWriter
from pypdf.generic import OutlineItem

def merge_with_bookmarks(pdf_paths, output_path, bookmarks=None):
    """
    pdf_paths: ["report_ch1.pdf", "report_ch2.pdf"]
    bookmarks: [{"title": "第一章", "page": 0}, {"title": "第二章", "page": 12}]
    """
    writer = PdfWriter()
    
    # 记录每个文件的起始页码
    page_offset = 0
    outline_items = []
    
    for i, path in enumerate(pdf_paths):
        reader = PdfReader(path)
        
        # 添加所有页面
        for page in reader.pages:
            writer.add_page(page)
        
        # 为当前文件添加书签
        if bookmarks and i < len(bookmarks):
            title = bookmarks[i]["title"]
            # 书签指向当前文件第0页(在合并后文档中的绝对页码)
            outline_item = OutlineItem(title, page_offset)
            outline_items.append(outline_item)
        
        # 更新偏移量
        page_offset += len(reader.pages)
    
    # 写入书签
    writer.add_outline_item_dict({item.title: item.page for item in outline_items})
    
    # 保存
    with open(output_path, "wb") as f:
        writer.write(f)
    print(f"已合并并添加书签:{output_path}")

# 调用示例
merge_with_bookmarks(
    pdf_paths=["samples/pdf/ch1_intro.pdf", "samples/pdf/ch2_analysis.pdf"],
    output_path="output/annual_report.pdf",
    bookmarks=[{"title": "1. 引言", "page": 0}, {"title": "2. 分析", "page": 8}]
)

技术细节 :

sub_item = OutlineItem("1.1 背景", 1, parent=outline_items[0])

5.2 批量添加半透明水印:保护敏感报告不被截图传播

水印不是简单叠图,需考虑PDF多页、不同尺寸、文字抗锯齿。本项目 pdf_watermarker.py 使用 reportlab 生成矢量水印PDF,再用 pypdf 叠加:

# pdf_watermarker.py
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from pypdf import PdfReader, PdfWriter

def create_watermark(text, width=612, height=792):
    """生成单页水印PDF(A4尺寸)"""
    watermark_path = "temp/watermark.pdf"
    c = canvas.Canvas(watermark_path, pagesize=(width, height))
    
    # 设置字体和透明度
    c.setFont("Helvetica", 40)
    c.setFillColorRGB(0.8, 0.8, 0.8, alpha=0.3)  # RGB+alpha
    
    # 斜向绘制文字
    c.saveState()
    c.translate(width / 2, height / 2)
    c.rotate(30)
    c.drawCentredString(0, 0, text)
    c.restoreState()
    
    c.save()
    return watermark_path

def add_watermark(input_pdf, output_pdf, watermark_text="CONFIDENTIAL"):
    watermark_path = create_watermark(watermark_text)
    watermark_reader = PdfReader(watermark_path)
    
    input_reader = PdfReader(input_pdf)
    writer = PdfWriter()
    
    for page in input_reader.pages:
        # 将水印叠加到当前页
        page.merge_page(watermark_reader.pages[0])
        writer.add_page(page)
    
    with open(output_pdf, "wb") as f:
        writer.write(f)
    print(f"已添加水印:{output_pdf}")

# 调用
add_watermark("samples/pdf/financial_report.pdf", "output/secure_report.pdf")

关键参数 :

5.3 OCR增强:为扫描PDF添加可搜索文本层

扫描PDF本质是图片, pypdf 无法提取文字。本项目集成 pytesseract (Tesseract OCR引擎)和 pdf2image ,在 pdf_ocr_enhancer.py 中实现:

# pdf_ocr_enhancer.py
from pdf2image import convert_from_path
import pytesseract
from pypdf import PdfReader, PdfWriter

def ocr_pdf(input_path, output_path, lang="chi_sim+eng"):
    """
    lang: "chi_sim"中文简体, "eng"英文, "chi_sim+eng"中英混合
    """
    # 将PDF转为图像(每页一张PNG)
    images = convert_from_path(input_path, dpi=300)  # 高DPI提升OCR精度
    
    # 创建新PDF写入器
    writer = PdfWriter()
    
    for i, image in enumerate(images):
        # OCR识别文字
        text = pytesseract.image_to_string(image, lang=lang, config="--psm 6")
        
        # 创建空白PDF页(同原PDF尺寸)
        from reportlab.pdfgen import canvas
        from reportlab.lib.pagesizes import letter
        from io import BytesIO
        
        packet = BytesIO()
        can = canvas.Canvas(packet, pagesize=letter)
        can.drawString(10, 10, text)  # 文字层(实际需精确匹配图像位置)
        can.save()
        
        # 合并图像层与文字层(简化版,真实项目用pdfkit或pdfrw)
        # (完整实现见utils/ocr_merger.py)
        print(f"第{i+1}页OCR完成,识别字数:{len(text)}")
    
    # 保存(此为示意,实际需用pdfkit生成含文本层的PDF)
    # writer.write(output_path)

# 注意:需提前安装Tesseract
# Windows: https://github.com/UB-Mannheim/tesseract/wiki
# macOS: brew install tesseract
# Ubuntu: sudo apt install tesseract-ocr libtesseract-dev

部署要点 :

6. 生产就绪:错误日志、进度反馈与一键打包交付

6.1 用logging模块构建可追溯的办公流水线

手工操作出错难定位,自动化脚本必须留痕。本项目 core/logger.py 配置了文件+控制台双输出,按模块分级:

# core/logger.py
import logging
from datetime import datetime

def setup_logger(name, level=logging.INFO):
    logger = logging.getLogger(name)
    logger.setLevel(level)
    
    # 文件处理器:按天滚动
    file_handler = logging.handlers.RotatingFileHandler(
        f"logs/{name}_{datetime.now().strftime('%Y%m%d')}.log",
        maxBytes=10*1024*1024,  # 10MB
        backupCount=5
    )
    file_handler.setLevel(logging.DEBUG)
    
    # 控制台处理器:仅INFO及以上
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    
    # 格式化
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    file_handler.setFormatter(formatter)
    console_handler.setFormatter(formatter)
    
    logger.addHandler(file_handler)
    logger.addHandler(console_handler)
    return logger

# 在excel_uuid_injector.py中使用
logger = setup_logger("excel_uuid")
logger.info("开始处理sales_data.xlsx")
logger.debug(f"生成UUID: {uuid_str}")
logger.error("列B为空,跳过第5行")

日志价值 :

6.2 进度条与实时反馈:让等待不再焦虑

长任务(如OCR、PDF合并)需可视化进度。本项目 utils/progress_bar.py 封装 tqdm ,适配各模块:

# utils/progress_bar.py
from tqdm import tqdm
import time

def process_with_progress(items, desc="Processing", unit="item"):
    """通用进度条包装器"""
    for item in tqdm(items, desc=desc, unit=unit, colour="green"):
        yield item
        time.sleep(0.1)  # 模拟处理耗时

# 在pdf_merger.py中应用
pdf_paths = ["ch1.pdf", "ch2.pdf", "ch3.pdf"]
for pdf_path in process_with_progress(pdf_paths, desc="Merging PDFs", unit="file"):
    reader = PdfReader(pdf_path)
    # ... 合并逻辑

效果 :终端显示 Merging PDFs: 100%|██████████| 3/3 [00:00<00:00, 30.23file/s] ,支持中断恢复( tqdm 自动记录)。

以上就是Python办公自动化之Excel/Word/PDF实战完整教学的详细内容,更多关于Python办公自动化的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文