日々の業務には、ファイルの整理、Excelレポートの作成、メールの一括送信など、繰り返しの定型作業が多く存在します。こうした作業を手動で行い続けると、時間の浪費だけでなく、ヒューマンエラーのリスクも高まります。
Pythonは、こうした業務の自動化に最適なプログラミング言語です。標準ライブラリとサードパーティパッケージを組み合わせることで、ファイル操作からメール送信、Excel処理まで、幅広い業務を自動化できます。本記事では、すぐに実務で使えるスクリプト集を紹介します。
業務自動化の前に|環境準備と基本方針
必要なパッケージのインストール
# 仮想環境の作成
python3 -m venv .venv
source .venv/bin/activate
# 必要なパッケージのインストール
pip install openpyxl python-docx PyPDF2 python-dotenv schedule
自動化スクリプトの設計方針
- 冪等性を確保する:スクリプトを複数回実行しても同じ結果になるよう設計する
- ログを残す:処理の実行結果をログファイルに記録し、問題発生時に原因を追跡可能にする
- エラーハンドリング:一部のファイルでエラーが発生しても、処理全体が停止しないようにする
- 設定を外部化する:パス、メールアドレス、パスワードなどを環境変数や設定ファイルに分離する
# ログ設定の基本テンプレート
import logging
from datetime import datetime
log_file = f"automation_{datetime.now():%Y%m%d}.log"
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[
logging.FileHandler(log_file, encoding="utf-8"),
logging.StreamHandler(),
],
)
logger = logging.getLogger(__name__)
ファイル操作の自動化
ファイルの整理・リネーム・移動は最も基本的な自動化対象です。
ファイルの一括リネーム
import os
from pathlib import Path
from datetime import datetime
def rename_files_with_date(directory: str, prefix: str = ""):
"""ディレクトリ内のファイルに日付プレフィックスを追加してリネームする"""
dir_path = Path(directory)
today = datetime.now().strftime("%Y%m%d")
for file_path in dir_path.iterdir():
if file_path.is_file() and not file_path.name.startswith(today):
new_name = f"{today}_{prefix}{file_path.name}"
new_path = file_path.parent / new_name
file_path.rename(new_path)
logger.info(f"リネーム: {file_path.name} → {new_name}")
# 実行
rename_files_with_date("./reports", prefix="report_")
ファイルの自動分類
from pathlib import Path
import shutil
def organize_files(source_dir: str):
"""拡張子ごとにファイルをフォルダに分類する"""
source = Path(source_dir)
extensions_map = {
"画像": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg"],
"文書": [".pdf", ".doc", ".docx", ".txt", ".xlsx", ".csv"],
"動画": [".mp4", ".avi", ".mov", ".wmv"],
"音声": [".mp3", ".wav", ".flac"],
"アーカイブ": [".zip", ".tar", ".gz", ".rar"],
}
for file_path in source.iterdir():
if not file_path.is_file():
continue
ext = file_path.suffix.lower()
category = "その他"
for cat, exts in extensions_map.items():
if ext in exts:
category = cat
break
dest_dir = source / category
dest_dir.mkdir(exist_ok=True)
shutil.move(str(file_path), str(dest_dir / file_path.name))
logger.info(f"移動: {file_path.name} → {category}/")
# 実行
organize_files("./downloads")
古いファイルの自動削除
from pathlib import Path
from datetime import datetime, timedelta
def delete_old_files(directory: str, days: int = 30):
"""指定日数以上前のファイルを削除する"""
dir_path = Path(directory)
cutoff = datetime.now() - timedelta(days=days)
deleted_count = 0
for file_path in dir_path.rglob("*"):
if file_path.is_file():
modified_time = datetime.fromtimestamp(file_path.stat().st_mtime)
if modified_time < cutoff:
file_path.unlink()
logger.info(f"削除: {file_path} (最終更新: {modified_time:%Y-%m-%d})")
deleted_count += 1
logger.info(f"合計 {deleted_count} 件のファイルを削除しました。")
# 30日以上前のログファイルを削除
delete_old_files("./logs", days=30)
Excel処理の自動化
openpyxlを使えば、ExcelファイルをPythonから自在に操作できます。
Excelファイルの読み込みとデータ抽出
import openpyxl
def read_excel_data(file_path: str, sheet_name: str = None):
"""Excelファイルからデータを読み込む"""
wb = openpyxl.load_workbook(file_path, data_only=True)
ws = wb[sheet_name] if sheet_name else wb.active
# ヘッダー行の取得
headers = [cell.value for cell in ws[1]]
# データ行の取得
data = []
for row in ws.iter_rows(min_row=2, values_only=True):
record = dict(zip(headers, row))
data.append(record)
wb.close()
return data
# 実行
data = read_excel_data("sales_report.xlsx", "Sheet1")
for record in data[:5]:
print(record)
Excelレポートの自動生成
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.chart import BarChart, Reference
from datetime import datetime
def create_monthly_report(data: list[dict], output_path: str):
"""月次レポートをExcelファイルとして生成する"""
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "月次レポート"
# スタイル定義
header_font = Font(bold=True, size=12, color="FFFFFF")
header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
border = Border(
left=Side(style="thin"),
right=Side(style="thin"),
top=Side(style="thin"),
bottom=Side(style="thin"),
)
# タイトル
ws.merge_cells("A1:E1")
title_cell = ws["A1"]
title_cell.value = f"月次売上レポート({datetime.now():%Y年%m月})"
title_cell.font = Font(bold=True, size=16)
# ヘッダー行
headers = ["部門", "売上(万円)", "前月比(%)", "目標達成率(%)", "備考"]
for col, header in enumerate(headers, 1):
cell = ws.cell(row=3, column=col, value=header)
cell.font = header_font
cell.fill = header_fill
cell.alignment = Alignment(horizontal="center")
cell.border = border
# データ行
for row_idx, record in enumerate(data, 4):
for col_idx, key in enumerate(headers, 1):
cell = ws.cell(row=row_idx, column=col_idx, value=record.get(key, ""))
cell.border = border
if col_idx >= 2 and col_idx <= 4:
cell.number_format = "#,##0"
# 列幅の調整
ws.column_dimensions["A"].width = 15
ws.column_dimensions["B"].width = 18
ws.column_dimensions["C"].width = 15
ws.column_dimensions["D"].width = 18
ws.column_dimensions["E"].width = 20
# 棒グラフの追加
chart = BarChart()
chart.title = "部門別売上"
chart.y_axis.title = "売上(万円)"
data_ref = Reference(ws, min_col=2, min_row=3, max_row=3 + len(data))
cats_ref = Reference(ws, min_col=1, min_row=4, max_row=3 + len(data))
chart.add_data(data_ref, titles_from_data=True)
chart.set_categories(cats_ref)
chart.shape = 4
ws.add_chart(chart, "A" + str(5 + len(data)))
wb.save(output_path)
logger.info(f"レポートを保存しました: {output_path}")
# サンプルデータ
sample_data = [
{"部門": "営業1課", "売上(万円)": 1500, "前月比(%)": 105, "目標達成率(%)": 98, "備考": ""},
{"部門": "営業2課", "売上(万円)": 1200, "前月比(%)": 98, "目標達成率(%)": 85, "備考": "人員減"},
{"部門": "営業3課", "売上(万円)": 1800, "前月比(%)": 112, "目標達成率(%)": 110, "備考": "大型案件"},
]
create_monthly_report(sample_data, "monthly_report.xlsx")
複数Excelファイルの集約
import pandas as pd
from pathlib import Path
def merge_excel_files(directory: str, output_path: str):
"""ディレクトリ内の全Excelファイルを1つに集約する"""
dir_path = Path(directory)
all_data = []
for excel_file in sorted(dir_path.glob("*.xlsx")):
logger.info(f"読み込み: {excel_file.name}")
df = pd.read_excel(excel_file)
df["ファイル名"] = excel_file.stem
all_data.append(df)
if all_data:
merged_df = pd.concat(all_data, ignore_index=True)
merged_df.to_excel(output_path, index=False)
logger.info(f"集約完了: {len(all_data)}ファイル → {output_path}")
else:
logger.warning("対象のExcelファイルが見つかりませんでした。")
merge_excel_files("./monthly_reports", "merged_report.xlsx")
メール送信の自動化
Pythonの標準ライブラリを使って、メールの自動送信を実装できます。
基本的なメール送信
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 os
from dotenv import load_dotenv
load_dotenv()
def send_email(to_address: str, subject: str, body: str, attachments: list[str] = None):
"""メールを送信する"""
smtp_server = os.getenv("SMTP_SERVER", "smtp.gmail.com")
smtp_port = int(os.getenv("SMTP_PORT", "587"))
from_address = os.getenv("EMAIL_ADDRESS")
password = os.getenv("EMAIL_PASSWORD")
msg = MIMEMultipart()
msg["From"] = from_address
msg["To"] = to_address
msg["Subject"] = subject
msg.attach(MIMEText(body, "plain", "utf-8"))
# 添付ファイル
if attachments:
for file_path in attachments:
with open(file_path, "rb") as f:
part = MIMEBase("application", "octet-stream")
part.set_payload(f.read())
encoders.encode_base64(part)
filename = os.path.basename(file_path)
part.add_header("Content-Disposition", f"attachment; filename={filename}")
msg.attach(part)
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(from_address, password)
server.send_message(msg)
logger.info(f"メール送信完了: {to_address}")
# 環境変数ファイル(.env)
# EMAIL_ADDRESS=your-email@gmail.com
# EMAIL_PASSWORD=your-app-password
# SMTP_SERVER=smtp.gmail.com
# SMTP_PORT=587
一括メール送信(テンプレート使用)
import csv
from string import Template
def send_bulk_emails(csv_path: str, template_path: str, subject: str):
"""CSVの宛先リストに基づいてテンプレートメールを一括送信する"""
# テンプレートの読み込み
with open(template_path, "r", encoding="utf-8") as f:
template = Template(f.read())
# CSVの読み込みと送信
with open(csv_path, "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
body = template.substitute(
name=row["名前"],
company=row["会社名"],
date=row["日付"],
)
try:
send_email(row["メールアドレス"], subject, body)
except Exception as e:
logger.error(f"送信失敗 ({row['メールアドレス']}): {e}")
# テンプレートファイル(template.txt)
# ${name}様
#
# いつもお世話になっております。
# ${company}様の${date}の報告書を添付いたします。
PDF操作の自動化
PDFの結合
from PyPDF2 import PdfMerger
from pathlib import Path
def merge_pdfs(directory: str, output_path: str):
"""ディレクトリ内のPDFを1つに結合する"""
merger = PdfMerger()
dir_path = Path(directory)
pdf_files = sorted(dir_path.glob("*.pdf"))
if not pdf_files:
logger.warning("PDFファイルが見つかりませんでした。")
return
for pdf_file in pdf_files:
logger.info(f"追加: {pdf_file.name}")
merger.append(str(pdf_file))
merger.write(output_path)
merger.close()
logger.info(f"結合完了: {len(pdf_files)}ファイル → {output_path}")
merge_pdfs("./invoices", "merged_invoices.pdf")
PDFからテキストを抽出
from PyPDF2 import PdfReader
def extract_text_from_pdf(file_path: str) -> str:
"""PDFからテキストを抽出する"""
reader = PdfReader(file_path)
text = ""
for page in reader.pages:
text += page.extract_text() + "\n"
return text
# 実行
text = extract_text_from_pdf("document.pdf")
print(text[:500])
定期実行の仕組み
自動化スクリプトを定期的に実行する方法を紹介します。
scheduleライブラリを使った方法
import schedule
import time
def daily_report_task():
"""日次レポート生成タスク"""
logger.info("日次レポートの生成を開始します。")
# ここに処理を記述
logger.info("日次レポートの生成が完了しました。")
def weekly_cleanup_task():
"""週次クリーンアップタスク"""
logger.info("クリーンアップを開始します。")
delete_old_files("./logs", days=30)
delete_old_files("./temp", days=7)
# スケジュール設定
schedule.every().day.at("09:00").do(daily_report_task)
schedule.every().monday.at("06:00").do(weekly_cleanup_task)
# 実行ループ
while True:
schedule.run_pending()
time.sleep(60)
cronを使った方法(Linux/macOS)
# crontabの編集
crontab -e
# 毎日9時にスクリプトを実行
0 9 * * * /path/to/.venv/bin/python /path/to/daily_report.py >> /path/to/cron.log 2>&1
# 毎週月曜6時にクリーンアップ
0 6 * * 1 /path/to/.venv/bin/python /path/to/cleanup.py >> /path/to/cron.log 2>&1
Windowsタスクスケジューラ
Windowsの場合は、タスクスケジューラを使ってスクリプトを定期実行できます。PowerShellから設定することも可能です。
# PowerShellでタスクを登録する例
$action = New-ScheduledTaskAction -Execute "C:\path\.venv\Scripts\python.exe" -Argument "C:\path\daily_report.py"
$trigger = New-ScheduledTaskTrigger -Daily -At "09:00"
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "DailyReport" -Description "日次レポート生成"
実践:業務自動化のスクリプト統合例
これまでのスクリプトを組み合わせた統合的な自動化の例を紹介します。
"""
日次業務自動化スクリプト
- 各部署のExcelレポートを集約
- 月次レポートを生成
- 関係者にメールで送信
"""
import logging
from datetime import datetime
from pathlib import Path
logger = logging.getLogger(__name__)
def main():
today = datetime.now()
logger.info(f"=== 日次自動化処理開始: {today:%Y-%m-%d %H:%M} ===")
try:
# 1. 各部署のExcelファイルを集約
logger.info("Step 1: Excelファイルの集約")
merge_excel_files("./daily_reports", f"./output/merged_{today:%Y%m%d}.xlsx")
# 2. 古いファイルのクリーンアップ
logger.info("Step 2: 古いファイルの削除")
delete_old_files("./output", days=90)
# 3. レポートをメールで送信
logger.info("Step 3: メール送信")
recipients = ["manager@example.com", "team-lead@example.com"]
for recipient in recipients:
send_email(
to_address=recipient,
subject=f"【自動送信】日次レポート {today:%Y/%m/%d}",
body=f"{today:%Y年%m月%d日}の日次レポートを添付いたします。",
attachments=[f"./output/merged_{today:%Y%m%d}.xlsx"],
)
logger.info("=== 日次自動化処理完了 ===")
except Exception as e:
logger.error(f"処理中にエラーが発生しました: {e}")
# エラー通知メールの送信
send_email(
to_address="admin@example.com",
subject="【エラー】日次自動化処理",
body=f"エラー内容: {e}",
)
if __name__ == "__main__":
main()
まとめ
本記事では、Pythonを使った業務自動化の実践スクリプトを紹介しました。
- ファイル操作:pathlibとshutilでリネーム・分類・削除を自動化
- Excel処理:openpyxlとpandasでレポート生成・データ集約を実現
- メール送信:smtplibで添付ファイル付きメールの一括送信が可能
- PDF操作:PyPDF2でPDFの結合やテキスト抽出を自動化
- 定期実行:scheduleライブラリやcronで自動スケジューリング
業務自動化は、まず小さなスクリプトから始めることが重要です。毎日5分かかる作業を自動化するだけでも、年間で約20時間の工数削減になります。本記事のスクリプトをベースに、自社の業務に合わせたカスタマイズを行ってみてください。
#Python#自動化#業務効率化
関連記事
AIエージェント開発入門|自律型AIの仕組みと構築方法を解説【2026年版】
AI駆動コーディングワークフロー|Claude Code・Cursor・Copilotの実践的使い分け
プロンプトエンジニアリング上級編|Chain-of-Thought・Few-Shot・ReActの実践
APIレート制限の設計と実装|トークンバケット・スライディングウィンドウ解説
APIバージョニング戦略|URL・ヘッダー・クエリパラメータの使い分け
BIツール入門|Metabase・Redash・Looker Studioでデータ可視化する方法
チャットボット開発入門|LINE Bot・Slack Botの構築方法と活用事例
CI/CDパイプラインの基礎|継続的インテグレーション・デリバリーの全体像