PR

Python×Excelでメール一括送信ツールを自作する【第1回】pandasでExcel名簿(氏名・アドレス・会社名)を読み込む

Python
スポンサーリンク

■ 導入:きっかけは「現場の困った」から

NINJIN Mail制作記 第1回

スポンサーリンク

Python×Excelでメール一括送信ツールを自作する|第1回:pandasでExcel名簿を読み込む

こんにちは、ニンジンです🥕

この記事は、Excelの名簿(氏名・アドレス・会社名)を読み込んで、Outlookから1件ずつ差し込んだメールを一括送信するツール「NINJIN Mail」を、全3回で自作していくシリーズの第1回です。今回は、ツールの設計方針を整理したうえで、pandasread_excel()df.iterrows() を使って、Excel名簿を1行ずつ読み込む基本処理を実装します。

プログラミングの経験が浅くても追えるよう、必要なライブラリの pip install 手順から、実行して分かった課題(次回以降で解決します)まで、順を追って解説します。

この記事で分かること

  • Excel名簿→Outlook一括送信ツールの設計方針(機能要件・実装方針5点)
  • 必要なライブラリ(pandas / openpyxl / tkinter / pywin32)と、その役割
  • pip install pandas openpyxl pywin32 のインストール手順(画面キャプチャ付き)
  • pandas.read_excel() でExcelを読み込み、df.iterrows() で氏名・アドレス・会社名を1行ずつ取り出すサンプルコード
  • この段階で残る3つの課題(ファイルパスの制約・列名への依存・空行)

開発のきっかけ

「Pythonで便利なソフトを作ったら、どのくらい使ってもらえるだろうか」と考えていたとき、営業部から相談を受けました。

展示会のあとに、お礼メールを一人ずつ送るのがかなりの手間になっている

この作業はパターン化しやすく、Pythonでの自動化に向いています。これが、メール一括送信ソフト「NINJIN Mail」を作り始めたきっかけです。


スポンサーリンク

開発の方向性を整理する|誰のための、どんなツールか

最初に、「誰に向けて」「何を実現するか」を整理しました。複雑な機能を詰め込むより、誰でも直感的に操作できることを優先しています。

機能要件

  • 想定ユーザー:展示会のお礼メールや、セミナーの招待メールを送る営業担当者
  • 名簿の読み込み:Excelファイルから氏名・アドレス・会社名を取得する
  • 一括送信:読み込んだ情報を本文に差し込みながら送信する
  • 送信記録:誰に送信したかをログとして残す
  • 想定シーン:展示会のお礼メール、セミナーの招待メールなど

実装方針

要件を実現するための方針として、以下の5点を決めました。

  1. 名簿は任意のフォルダに置かれたExcelファイルから読み込む(第2回
  2. 件名と本文はGUIアプリケーション上で入力する(第3回
  3. 送信処理にはOutlookのAPIを利用する(第3回
  4. 送信結果は名簿のExcelファイルに追記して記録する
  5. 使い勝手を高めるため、直前に使用したExcelファイルの場所を記憶する(第2回

スポンサーリンク

必要なライブラリ|pandas・openpyxl・pywin32ほか

設計を実現するために必要なライブラリを整理すると、以下のようになります。

役割ライブラリ
Excelの読み書きpandas / openpyxl
GUI(操作画面)の作成tkinter
Outlookの操作pywin32
設定ファイルの運用json
送信日時の記録time

補足:pywin32 は64bit版のWindows・Pythonでも問題なく動作します。ライブラリ側で自動調整されるため、利用する側で特別な対応は不要です。

ライブラリのインストール方法

インストールしていない場合は、コマンドプロンプトまたはWindows PowerShellで以下を実行してください。
まとめて入れる場合は pip install pandas openpyxl pywin32 の1行でも可能です。

コマンドプロンプトでpip install pandasを実行しSuccessfully installedと表示された画面

▲ pip install pandas の実行例

pip install pandas

インストール中にNumPyのWARNINGが出ることがありますが、最後に「Successfully installed」と表示されていれば問題ありません。

コマンドプロンプトでpip install openpyxlを実行している画面

▲ pip install openpyxl の実行例

pip install openpyxl

pandas が .xlsx を読み書きするときに内部で使うライブラリです。

コマンドプロンプトでpip install pywin32を実行している画面

▲ pip install pywin32 の実行例

pip install pywin32

第3回でOutlookを操作するときに使います。第1回の名簿読み込みだけなら pandasopenpyxl があれば動きます。


スポンサーリンク

pandasでExcelの顧客データを読み込む【サンプルコード】

ここでは、pandas.read_excel() でExcelを読み込み、df.iterrows() で1行ずつデータを取り出す基本処理を実装します。

氏名・アドレス・会社名の3列を持つ名簿Excelファイル client_list.xlsx

▲ 名簿Excel「client_list.xlsx」(氏名・アドレス・会社名の3列)

  • 名簿用のExcelファイル名を client_list.xlsx とします。
  • この段階では、client_list.xlsx をPythonコード(mail-soft-test01.py)と同じフォルダに置いてください。

サンプルコード:mail-soft-test01.py(※ VS Codeなどのエディターで実行してください)

import pandas as pd

def load_client_list(file_path):
    try:
        # Excelファイルを読み込む
        df = pd.read_excel(file_path)
        
        # 1行ずつ処理して読み込みを確認
        for index, row in df.iterrows():
            name = row['氏名']
            email = row['アドレス']
            company = row['会社名']
            
            print(f"読み込み中: {company} {name} 様 ({email})")
            
    except Exception as e:
        print(f"エラーが発生しました: {e}")

# 実行(同じフォルダにExcelがある前提)
load_client_list('client_list.xlsx')

実行結果と分かった課題

VS Codeのターミナルに会社名・氏名・アドレスが1行ずつ出力された実行結果

▲ ターミナルに名簿のデータが1行ずつ出力されれば成功

ターミナルにExcelのデータが「読み込み中: 〇〇株式会社 山田 太郎 様 (…)」のように出力されれば成功です。

読み込みには成功しましたが、実用的なツールにするには、この段階で以下の課題が残っています。いずれも第2回以降で解決していきます。

課題内容
1ファイルパスの制約Pythonファイルと同じフォルダにExcelを置かないと動作しない(→ 第2回で filedialog により解決)
2列名(ヘッダー)への依存row['氏名'] のように列名を直接指定するため、Excel側の見出し行が一致しないと KeyError になる
3空行への対応名簿の途中に空行があると、その行の読み取りでエラーになるため改良が必要(dropna() など)

スポンサーリンク

まとめ|次回はファイル選択画面を実装する

第1回では、ツールの設計方針を整理し、pandasread_excel()df.iterrows() でExcel名簿を1行ずつ読み込む基本処理を実装しました。ただし現状はまだ「プログラム」の段階で、ツールとしての使いやすさには課題が残っています。

次回(第2回)は、Windowsで見慣れた「ファイルを開く」画面を tkinterfiledialog で実装し、さらに「直前に選んだフォルダを記憶する」仕組みを config.json で追加して、操作性を改善します。

PR

販売版NINJIN Mailのメイン画面。customtkinterでモダンにしたGUI

▲ 完成版 NINJIN Mail(customtkinterでUIを刷新)

今回紹介したコードを含む開発の詳細は、noteでフルコード付きで販売しています。環境構築なしですぐ使えるパッケージ版もあります。コードに関心がある方も、コードは難しそうと感じる方も、内容だけでも覗いてみてください。

👉 noteでチェックする

次に読む記事


スポンサーリンク

よくある質問(pandas・read_excel・Excel名簿の読み込み)

Qimport pandas で ModuleNotFoundError: No module named ‘pandas’ になります

Apandas が未インストールです。コマンドプロンプトかWindows PowerShellで pip install pandas を実行してください。複数のPythonが入っている環境では、python -m pip install pandas のように実行中のPythonを明示すると確実です。

Qpd.read_excel() で「xlrd」や「openpyxl」が必要というエラーが出ます

A.xlsx ファイルの読み込みには openpyxl が必要です。pip install openpyxl を実行してください。古い .xls 形式の場合は xlrd が必要になります。

QExcelに複数シートがあります。特定のシートだけ読みたいです

Apd.read_excel(file_path, sheet_name=”名簿”) のように sheet_name にシート名(またはインデックス番号)を渡します。指定しないと先頭シートが読み込まれます。

Qrow[‘氏名’] で KeyError: ‘氏名’ になります

AExcelの見出し行(1行目)の列名と、コードで指定した文字列が完全に一致していないときに起きます。全角スペースや前後の空白、「氏 名」のような中黒・スペースの有無が原因になりがちです。print(df.columns.tolist()) で実際の列名を確認してください。

Q名簿の途中に空行があると処理が止まります

A空行があるとその行の値が NaN になり、後続の処理でエラーになることがあります。df = df.dropna(subset=[“アドレス”]) のように、必須列が空の行を事前に除外すると安全です。


この記事が役に立ったら、シェアしてもらえると嬉しいです🥕

Xでポスト はてブ LINE Pocket
ニンジン🥕アイコン

Follow me on X

本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕

@ninjin_py_vba をフォロー

PROJECT LOG — SERIES INDEX
スポンサーリンク

シリーズ記事一覧

電子工作・自動化ツールの製作記録をシリーズごとにまとめています。気になるテーマからお読みください。


超音波距離センサーHC-SR04をRaspberry Pi Picoで使う|仕組み・配線・精度検証
.uds1-block { position: relative; overflow: hidden; border-radius: 12px; border: 1px solid #f0cba8; background: linear-g…
今週の注目ガジェット〜09/07週〜|電子工作・自作向け新製品まとめ(TickrCast/Radxa Linkr ほか)
ニンジンのガジェット通信 09/07週。ESP32-P4の自作気象モニター、極小IP-KVM「Radxa Linkr」、ESP32のDINレール型PLC、LTE開発キットなど、電子工作で使えそうな新製品5つを解説。
サーボモータの角度をタクトスイッチで可変|OLED(SSD1306)に現在角度をリアルタイム表示
Raspberry Pi Pico 2W×MG996RにタクトスイッチとOLED(SSD1306)を追加。ボタンで角度を可変しながら現在角度をリアルタイム表示するMicroPython実装を、framebufの文字拡大やサーボの遊び対策まで実機ベースで解説します。
MG996RサーボモーターをRaspberry Pi Pico 2Wで動かす:PWM制御とキャリブレーション実践
MG996RサーボモーターをRaspberry Pi Pico 2Wで動かす方法を解説。公称180度のはずが実測198度だった個体差の原因究明から、ホーンのズレ補正、タクトスイッチでの角度制御まで実機検証の様子を紹介します。
Tapo P110Mの消費電力をExcelレポート化する【年次集計・電気代試算・セキュリティ判断編】
FastAPI+openpyxlでTapo P110Mの消費電力をExcelレポート化。15秒間隔の生ログを日次集計する設計や、31円/kWhでの電気代試算、外部公開を見送った理由まで解説します。

コメント