在日常工作中,重复性的任务不仅耗时,还容易出错。Python凭借其简洁易学的语法,成为许多办公室自动化任务的首选工具。今天,我们就一起来看看如何用Python编写一些实用的小脚本,提高工作效率。

1. 文本文件批量重命名

在整理文档时,经常需要对大量文件进行重命名。下面是一个简单的脚本,帮助你批量处理这些任务。

import os

def rename_files(directory, prefix=""):
    """
    批量重命名指定目录下的所有文件。
    
    :param directory: 要处理的文件夹路径
    :param prefix: 文件的新前缀,默认为空字符串
    """
    # 遍历指定目录下的所有文件
    for filename in os.listdir(directory):
        # 获取文件名和扩展名
        file_base, file_ext = os.path.splitext(filename)
        
        # 生成新文件名
        new_filename = f"{prefix}{file_base}{file_ext}"
        
        # 拼接完整路径
        old_path = os.path.join(directory, filename)
        new_path = os.path.join(directory, new_filename)
        
        # 重命名文件
        os.rename(old_path, new_path)
        print(f"Renamed '{filename}' to '{new_filename}'")

# 使用示例
rename_files("path/to/your/directory", "New_")

输出示例:

Renamed 'old_file.txt' to 'New_old_file.txt'
Renamed 'another_file.docx' to 'New_another_file.docx'

2. Excel数据清洗

Excel表中的数据经常需要清理才能进一步分析。这个脚本可以帮助你删除空行、格式化日期等。

import pandas as pd

def clean_excel(file_path):
    """
    清洗Excel表格中的数据。
    
    :param file_path: Excel文件的路径
    """
    # 读取Excel文件
    df = pd.read_excel(file_path)
    
    # 删除空行
    df.dropna(inplace=True)
    
    # 格式化日期列(假设日期列名为'Date')
    if 'Date' in df.columns:
        df['Date'] = pd.to_datetime(df['Date'], format='%Y-%m-%d')
    
    # 保存修改后的数据
    df.to_excel(file_path, index=False)
    print(f"Data cleaned and saved to {file_path}")

# 使用示例
clean_excel("path/to/your/excel/file.xlsx")

3. PDF合并器

工作中经常需要将多个PDF文件合并成一个。下面这个脚本可以轻松实现这一点。

from PyPDF2 import PdfMerger

def merge_pdfs(output_path, *input_paths):
    """
    合并多个PDF文件为一个。
    
    :param output_path: 输出文件的路径
    :param input_paths: 一个或多个输入文件的路径
    """
    merger = PdfMerger()
    
    # 循环添加每个PDF文件
    for path in input_paths:
        merger.append(path)
    
    # 写入输出文件
    merger.write(output_path)
    merger.close()
    print(f"Merged files into {output_path}")

# 使用示例
merge_pdfs("path/to/output.pdf", "path/to/file1.pdf", "path/to/file2.pdf")

输出示例:

Merged files into path/to/output.pdf

4. 图片压缩工具

发送邮件或者上传图片时,常常需要先压缩图片以减少文件大小。这个脚本利用Pillow库来完成这一任务。

from PIL import Image

def compress_image(file_path, output_path=None, quality=75):
    """
    压缩图片文件。
    
    :param file_path: 输入图片的路径
    :param output_path: 输出图片的路径,默认为原文件覆盖
    :param quality: 压缩质量,范围0-100
    """
    img = Image.open(file_path)
    
    if not output_path:
        output_path = file_path
    
    img.save(output_path, optimize=True, quality=quality)
    print(f"Image compressed and saved to {output_path}")

# 使用示例
compress_image("path/to/image.jpg")

输出示例:

Image compressed and saved to path/to/image.jpg

5. 文本内容替换

编辑文档时,可能需要批量替换某些文本内容。这个脚本可以帮你快速实现。

def replace_text_in_files(directory, old_text, new_text):
    """
    在指定目录下所有文本文件中替换指定文本。
    
    :param directory: 文件所在的目录
    :param old_text: 要被替换的文本
    :param new_text: 新文本
    """
    for filename in os.listdir(directory):
        if filename.endswith(".txt"):  # 只处理.txt文件
            file_path = os.path.join(directory, filename)
            
            with open(file_path, 'r', encoding='utf-8') as file:
                file_data = file.read()
            
            # 替换文本
            file_data = file_data.replace(old_text, new_text)
            
            # 写回文件
            with open(file_path, 'w', encoding='utf-8') as file:
                file.write(file_data)
            
            print(f"Replaced text in {filename}")

# 使用示例
replace_text_in_files("path/to/text/files", "old_text", "new_text")

输出示例:

Replaced text in file1.txt
Replaced text in file2.txt

6. 数据抓取与解析

在进行市场调研或数据分析时,从网页上抓取数据是一项常见的任务。下面是一个使用 requestsBeautifulSoup 库来抓取和解析网页数据的例子。

import requests
from bs4 import BeautifulSoup

def scrape_webpage(url):
    """
    抓取并解析网页上的数据。
    
    :param url: 目标网页的URL
    """
    # 发送请求获取网页内容
    response = requests.get(url)
    
    # 解析HTML内容
    soup = BeautifulSoup(response.text, 'html.parser')
    
    # 提取特定信息(例如标题)
    titles = soup.find_all('h1')
    
    # 打印提取的信息
    for title in titles:
        print(title.text.strip())

# 使用示例
scrape_webpage("https://example.com")

输出示例:

Example Domain
This domain is for use in illustrative examples in documents.
You may use this domain in literature without prior coordination or asking for permission.

7. 数据导出到CSV

抓取的数据通常需要导出到CSV文件以便进一步分析。以下脚本展示了如何将数据导出到CSV文件。

import csv

def export_to_csv(data, file_path):
    """
    将数据导出到CSV文件。
    
    :param data: 要导出的数据列表,每个元素是一个字典
    :param file_path: CSV文件的路径
    """
    # 确定CSV文件的字段
    fieldnames = data[0].keys()
    
    # 打开CSV文件并写入数据
    with open(file_path, 'w', newline='', encoding='utf-8') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        
        # 写入表头
        writer.writeheader()
        
        # 写入每一行数据
        for row in data:
            writer.writerow(row)
    
    print(f"Data exported to {file_path}")

# 示例数据
data = [
    {'Name': 'Alice', 'Age': 25, 'City': 'New York'},
    {'Name': 'Bob', 'Age': 30, 'City': 'San Francisco'}
]

# 使用示例
export_to_csv(data, "path/to/output.csv")

输出示例:

Data exported to path/to/output.csv

8. 邮件自动发送

工作中经常需要发送大量的电子邮件。下面是一个使用 smtplib 库自动发送邮件的例子。

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

def send_email(subject, body, recipient, sender="your_email@example.com"):
    """
    发送电子邮件。
    
    :param subject: 邮件主题
    :param body: 邮件正文
    :param recipient: 收件人邮箱地址
    :param sender: 发件人邮箱地址,默认为"your_email@example.com"
    """
    # 创建邮件对象
    message = MIMEMultipart()
    message['From'] = sender
    message['To'] = recipient
    message['Subject'] = subject
    
    # 添加邮件正文
    message.attach(MIMEText(body, 'plain'))
    
    # 发送邮件
    with smtplib.SMTP('smtp.example.com', 587) as server:
        server.starttls()
        server.login(sender, 'your_password')
        server.sendmail(sender, recipient, message.as_string())
    
    print(f"Email sent to {recipient}")

# 使用示例
send_email("Meeting Reminder", "Don't forget the meeting at 2 PM.", "recipient@example.com")

输出示例:

Email sent to recipient@example.com

9. 文件夹监控与同步

有时需要实时监控文件夹的变化,并将更改同步到另一个位置。以下脚本展示了如何使用 watchdog 库实现这一功能。

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class FolderSyncHandler(FileSystemEventHandler):
    def __init__(self, source_folder, target_folder):
        self.source_folder = source_folder
        self.target_folder = target_folder

    def on_modified(self, event):
        """
        当文件夹中的文件被修改时触发。
        """
        if event.is_directory:
            return
        
        source_path = event.src_path
        target_path = source_path.replace(self.source_folder, self.target_folder)
        
        # 复制文件
        with open(source_path, 'rb') as src_file:
            with open(target_path, 'wb') as target_file:
                target_file.write(src_file.read())
        
        print(f"File synced from {source_path} to {target_path}")

def sync_folders(source_folder, target_folder):
    """
    监控源文件夹并将更改同步到目标文件夹。
    
    :param source_folder: 源文件夹路径
    :param target_folder: 目标文件夹路径
    """
    event_handler = FolderSyncHandler(source_folder, target_folder)
    observer = Observer()
    observer.schedule(event_handler, source_folder, recursive=True)
    observer.start()
    
    try:
        while True:
            pass
    except KeyboardInterrupt:
        observer.stop()
    
    observer.join()

# 使用示例
sync_folders("path/to/source/folder", "path/to/target/folder")

输出示例:

File synced from path/to/source/folder/file.txt to path/to/target/folder/file.txt

10. 数据库操作

在处理大量数据时,数据库是一个非常有用的工具。下面是一个使用 sqlite3 库来创建和查询数据库的例子。

import sqlite3

def create_and_query_database():
    """
    创建一个简单的SQLite数据库并进行查询。
    """
    # 连接到SQLite数据库
    conn = sqlite3.connect('example.db')
    
    # 创建游标
    cursor = conn.cursor()
    
    # 创建表
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS employees (
            id INTEGER PRIMARY KEY,
            name TEXT,
            age INTEGER
        )
    ''')
    
    # 插入数据
    cursor.execute("INSERT INTO employees (name, age) VALUES ('Alice', 25)")
    cursor.execute("INSERT INTO employees (name, age) VALUES ('Bob', 30)")
    
    # 提交事务
    conn.commit()
    
    # 查询数据
    cursor.execute("SELECT * FROM employees")
    rows = cursor.fetchall()
    
    # 打印查询结果
    for row in rows:
        print(row)
    
    # 关闭连接
    conn.close()

# 使用示例
create_and_query_database()

输出示例:

(1, 'Alice', 25)
(2, 'Bob', 30)

11. 日志记录

在开发过程中,日志记录是非常重要的。以下脚本展示了如何使用 logging 库记录日志。

import logging

def setup_logger():
    """
    设置日志记录。
    """
    # 创建logger
    logger = logging.getLogger('my_logger')
    logger.setLevel(logging.DEBUG)
    
    # 创建handler
    file_handler = logging.FileHandler('app.log')
    console_handler = logging.StreamHandler()
    
    # 设置日志级别
    file_handler.setLevel(logging.DEBUG)
    console_handler.setLevel(logging.INFO)
    
    # 定义日志格式
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    file_handler.setFormatter(formatter)
    console_handler.setFormatter(formatter)
    
    # 添加handler到logger
    logger.addHandler(file_handler)
    logger.addHandler(console_handler)
    
    return logger

def log_example(logger):
    """
    记录日志示例。
    
    :param logger: 日志记录器
    """
    logger.debug("This is a debug message")
    logger.info("This is an info message")
    logger.warning("This is a warning message")
    logger.error("This is an error message")
    logger.critical("This is a critical message")

# 使用示例
logger = setup_logger()
log_example(logger)

输出示例:

2023-09-25 14:30:00,123 - INFO - This is an info message
2023-09-25 14:30:00,123 - WARNING - This is a warning message
2023-09-25 14:30:00,123 - ERROR - This is an error message
2023-09-25 14:30:00,123 - CRITICAL - This is a critical message

12. 数据可视化

在数据分析中,数据可视化是必不可少的一部分。以下脚本展示了如何使用 matplotlib 库绘制简单的图表。

import matplotlib.pyplot as plt

def plot_data(x, y):
    """
    绘制数据图表。
    
    :param x: X轴数据
    :param y: Y轴数据
    """
    plt.plot(x, y)
    plt.xlabel('X Label')
    plt.ylabel('Y Label')
    plt.title('Simple Plot')
    plt.show()

# 使用示例
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]
plot_data(x, y)

13. PDF拆分器

有时需要将一个大的PDF文件拆分成多个小文件。以下脚本展示了如何使用 PyPDF2 库来实现这一功能。

from PyPDF2 import PdfReader, PdfWriter

def split_pdf(input_path, output_dir):
    """
    将PDF文件拆分成多个小文件。
    
    :param input_path: 输入PDF文件的路径
    :param output_dir: 输出文件夹路径
    """
    # 读取PDF文件
    reader = PdfReader(input_path)
    
    # 循环拆分每一页
    for page_num in range(len(reader.pages)):
        writer = PdfWriter()
        writer.add_page(reader.pages[page_num])
        
        # 生成输出文件名
        output_path = os.path.join(output_dir, f"page_{page_num + 1}.pdf")
        
        # 写入输出文件
        with open(output_path, 'wb') as output_file:
            writer.write(output_file)
        
        print(f"Split page {page_num + 1} to {output_path}")

# 使用示例
split_pdf("path/to/input.pdf", "path/to/output/directory")

输出示例:

Split page 1 to path/to/output/directory/page_1.pdf
Split page 2 to path/to/output/directory/page_2.pdf

14. 实战案例:自动化报表生成

假设你需要每个月自动生成一份销售报告。以下是一个完整的脚本,展示如何从Excel文件中读取数据,生成分析报告,并发送给相关人员。

import pandas as pd
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

def generate_report(excel_path, pdf_path):
    """
    从Excel文件中读取数据并生成PDF报告。
    
    :param excel_path: Excel文件路径
    :param pdf_path: PDF文件路径
    """
    # 读取Excel文件
    df = pd.read_excel(excel_path)
    
    # 分析数据
    total_sales = df['Sales'].sum()
    top_products = df.groupby('Product')['Sales'].sum().nlargest(5)
    
    # 创建PDF报告
    c = canvas.Canvas(pdf_path, pagesize=letter)
    c.drawString(100, 750, "Monthly Sales Report")
    c.drawString(100, 730, f"Total Sales: ${total_sales:.2f}")
    c.drawString(100, 710, "Top Products:")
    
    y = 690
    for product, sales in top_products.items():
        c.drawString(120, y, f"{product}: ${sales:.2f}")
        y -= 20
    
    c.save()
    print(f"Report generated at {pdf_path}")

def send_report(pdf_path, recipient, sender="your_email@example.com"):
    """
    发送PDF报告。
    
    :param pdf_path: PDF文件路径
    :param recipient: 收件人邮箱地址
    :param sender: 发件人邮箱地址,默认为"your_email@example.com"
    """
    # 创建邮件对象
    message = MIMEMultipart()
    message['From'] = sender
    message['To'] = recipient
    message['Subject'] = "Monthly Sales Report"
    
    # 添加邮件正文
    message.attach(MIMEText("Please find attached the monthly sales report."))
    
    # 添加附件
    with open(pdf_path, 'rb') as file:
        attachment = MIMEApplication(file.read(), _subtype="pdf")
        attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(pdf_path))
        message.attach(attachment)
    
    # 发送邮件
    with smtplib.SMTP('smtp.example.com', 587) as server:
        server.starttls()
        server.login(sender, 'your_password')
        server.sendmail(sender, recipient, message.as_string())
    
    print(f"Report sent to {recipient}")

# 使用示例
generate_report("path/to/sales_data.xlsx", "path/to/report.pdf")
send_report("path/to/report.pdf", "recipient@example.com")

输出示例:

Report generated at path/to/report.pdf
Report sent to recipient@example.com