はじめに:openpyxlとは何か? 🤔
openpyxlは、Pythonプログラミング言語を使用してExcelファイル(主に.xlsx/.xlsm/.xltx/.xltm形式)を読み書きするための強力なライブラリです。Excelは、データ分析、レポート作成、日々の業務管理など、多くのビジネスシーンで不可欠なツールですが、繰り返し作業や大量データの処理は手作業では非常に時間がかかります。
そこで登場するのがopenpyxlです! 🎉 このライブラリを使えば、Pythonスクリプトから直接Excelファイルを生成したり、既存のファイルを読み込んでデータを抽出・加工したり、書式を設定したりすることが可能になります。これにより、定型的なExcel作業を自動化し、大幅な時間短縮とヒューマンエラーの削減を実現できます。
データサイエンティスト、開発者、あるいは日常業務でExcelを多用するすべての人にとって、openpyxlは作業効率を劇的に向上させる可能性を秘めた必須ツールと言えるでしょう。このブログ記事では、openpyxlの基本的な使い方から、少し高度なテクニックまで、幅広く解説していきます。
インストール方法 💻
openpyxlを使用するには、まずPython環境にインストールする必要があります。インストールはPythonのパッケージマネージャであるpip
を使って簡単に行えます。ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行してください。
pip install openpyxl
通常、これにより最新版のopenpyxlがインストールされます。特定のバージョンを指定したい場合は、pip install openpyxl==バージョン番号
のように指定することも可能です。
また、openpyxlは内部でlxml
というライブラリを利用すると、特に大きなファイルを書き込む際のパフォーマンスが向上することがあります。必須ではありませんが、パフォーマンスを重視する場合はlxml
もインストールしておくと良いでしょう。
pip install lxml
インストールが成功したかどうかは、Pythonのインタラクティブシェルやスクリプトでimport openpyxl
を実行してみて、エラーが出なければOKです。
基本的な使い方:読み込みと書き込み 📖✍️
openpyxlの基本的な操作として、Excelファイルの新規作成、既存ファイルの読み込み、データの書き込み、そして保存の方法を見ていきましょう。
1. 新しいExcelブック(ファイル)の作成
まっさらなExcelファイルを作成するには、Workbook
クラスを使用します。
from openpyxl import Workbook
# 新しいワークブックを作成
wb = Workbook()
# アクティブなワークシートを取得 (デフォルトで1つ作成される)
ws = wb.active
ws.title = "最初のシート" # シート名を変更
# データをセルに書き込む (A1セルに値を設定)
ws['A1'] = "こんにちは、openpyxl!"
# 別のシートを作成
ws2 = wb.create_sheet("二番目のシート")
ws2['B2'] = 12345
# ファイルとして保存
wb.save("新しいブック.xlsx")
print("新しいブック.xlsx を作成しました。")
上記コードを実行すると、カレントディレクトリに「新しいブック.xlsx」という名前のExcelファイルが作成され、指定した内容が書き込まれます。
2. 既存のExcelブックの読み込み
既存のExcelファイルを読み込むには、load_workbook()
関数を使用します。
from openpyxl import load_workbook
try:
# 既存のワークブックを読み込む
wb = load_workbook(filename = '既存のブック.xlsx')
# シート名の一覧を取得
print("シート名一覧:", wb.sheetnames)
# 特定のシートを取得 (シート名で指定)
ws = wb['シート1'] # シート名が 'シート1' の場合
# アクティブなシートを取得することも可能
# ws = wb.active
# セルの値を取得 (A1セル)
cell_value = ws['A1'].value
print(f"A1セルの値: {cell_value}")
# 行番号と列番号でセルを指定して値を取得 (B2セル)
# row=2, column=2 は B2セルを表す (1始まり)
cell_value_b2 = ws.cell(row=2, column=2).value
print(f"B2セルの値: {cell_value_b2}")
# ワークブックを閉じる (読み込み専用の場合など)
# wb.close() # 通常は自動で閉じられるため、明示的に呼ぶ必要は少ない
except FileNotFoundError:
print("エラー: 既存のブック.xlsx が見つかりません。")
except KeyError:
print("エラー: 指定されたシート名が見つかりません。")
load_workbook()
でファイルを開き、シート名やactive
プロパティで操作したいワークシートを選択します。セルの値はws['A1'].value
やws.cell(row=1, column=1).value
のようにして取得できます。
注意点: openpyxlは数式を含むセルを読み込む際、デフォルトでは数式そのものを読み込みます。もし数式の結果(最後にExcelで計算された値)を取得したい場合は、load_workbook(filename='...', data_only=True)
オプションを使用します。ただし、data_only=True
で開いたブックは数式を失う可能性があるので注意が必要です。
3. セルへのデータの書き込み
セルへの書き込みは、読み込みと同様にセルを指定し、値を代入するだけです。
from openpyxl import load_workbook
try:
wb = load_workbook(filename = '書き込みテスト.xlsx')
ws = wb.active # アクティブシートを取得
# セルに値を書き込む
ws['A1'] = "新しい値"
ws.cell(row=2, column=2, value="行と列で指定") # B2セルに書き込み
# 複数のセルに一括で値を書き込む (行を追加する)
new_row_data = ["データ1", "データ2", "データ3"]
ws.append(new_row_data) # 次の空いている行に追加される
# 変更を保存
wb.save("書き込みテスト_更新後.xlsx")
print("書き込みテスト_更新後.xlsx を保存しました。")
except FileNotFoundError:
print("エラー: 書き込みテスト.xlsx が見つかりません。作成します。")
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws['A1'] = "初期値"
wb.save("書き込みテスト.xlsx")
print("書き込みテスト.xlsx を作成しました。再度スクリプトを実行してください。")
ws['セル座標'] = 値
や ws.cell(row=行番号, column=列番号, value=値)
で書き込めます。ws.append(リストやタプル)
を使うと、シートの末尾に新しい行としてデータを簡単に追加できます。書き込み後は必ず wb.save()
で保存するのを忘れないようにしましょう。
4. ワークシートの操作
ワークブック内のワークシートに対する基本的な操作も簡単です。
from openpyxl import Workbook
wb = Workbook()
# アクティブシートの名前変更
ws = wb.active
print(f"最初のアクティブシート名: {ws.title}")
ws.title = "メインデータ"
print(f"変更後のシート名: {ws.title}")
# 新しいシートを作成 (末尾に追加)
ws_new = wb.create_sheet("追加シート1")
print(f"作成されたシート名: {ws_new.title}")
# 特定の位置にシートを作成 (最初の位置に追加)
ws_first = wb.create_sheet("最初のシート", 0)
print(f"最初の位置に追加されたシート名: {ws_first.title}")
# 2番目の位置 (インデックス1) にシートを作成
ws_second = wb.create_sheet("二番目のシート", 1)
print(f"二番目の位置に追加されたシート名: {ws_second.title}")
# 現在のシート名一覧
print("現在のシート名一覧:", wb.sheetnames)
# シートのコピーを作成
ws_copy = wb.copy_worksheet(ws_second) # "二番目のシート" をコピー
ws_copy.title = "二番目のシートのコピー"
print("コピー後のシート名一覧:", wb.sheetnames)
# シートを削除
del wb["追加シート1"] # または wb.remove(wb["追加シート1"])
print("削除後のシート名一覧:", wb.sheetnames)
wb.save("シート操作テスト.xlsx")
シート名の変更、新規作成(位置指定も可能)、コピー、削除などが直感的に行えます。
高度な機能 ✨
openpyxlは基本的な読み書きだけでなく、より高度なExcelの機能もサポートしています。
1. セルのスタイリング(書式設定)🎨
セルの見た目を変更するには、openpyxl.styles
モジュールを使います。フォント、塗りつぶし(背景色)、罫線、配置などを設定できます。
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment
wb = Workbook()
ws = wb.active
# スタイルを適用するセル
cell = ws['A1']
cell.value = "スタイルのテスト"
# フォント設定: 太字、イタリック、サイズ14、赤色
font_style = Font(name='游ゴシック', size=14, bold=True, italic=True, color='FF0000') # 色はARGB形式
cell.font = font_style
# 塗りつぶし設定: 黄色の単色塗りつぶし
fill_style = PatternFill(fill_type='solid', fgColor='FFFF00') # または start_color='FFFF00'
cell.fill = fill_style
# 罫線設定: 全ての辺に黒色の細い実線
thin_border_side = Side(border_style='thin', color='000000')
border_style = Border(top=thin_border_side, left=thin_border_side, right=thin_border_side, bottom=thin_border_side)
cell.border = border_style
# 配置設定: 水平中央揃え、垂直中央揃え、テキストを折り返す
alignment_style = Alignment(horizontal='center', vertical='center', wrap_text=True)
cell.alignment = alignment_style
# 列幅と行高の調整 (例: A列の幅を20に、1行目の高さを30に)
ws.column_dimensions['A'].width = 20
ws.row_dimensions[1].height = 30
wb.save("スタイル設定テスト.xlsx")
print("スタイル設定テスト.xlsx を保存しました。")
重要: openpyxlの最近のバージョンでは、スタイルオブジェクト(Font, PatternFillなど)はイミュータブル(不変)です。つまり、一度作成したスタイルオブジェクトのプロパティを後から変更することはできません。スタイルを変更したい場合は、新しいスタイルオブジェクトを作成してセルに再割り当てする必要があります。これは、スタイルが複数のセルで共有される際の意図しない副作用を防ぐためです。
2. 数式の利用 🧮
セルにExcelの数式を書き込むことができます。数式は文字列としてセルに代入します。
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws['A1'] = 10
ws['A2'] = 20
ws['A3'] = 30
# 合計を計算するSUM関数
ws['A4'] = "=SUM(A1:A3)"
# 条件によって表示を変えるIF関数
ws['B1'] = 50
ws['B2'] = "=IF(B1>40, \"合格\", \"不合格\")" # 文字列はダブルクォートで囲む
# 注意: 数式内の文字列リテラルはダブルクォートを使うため、
# Pythonの文字列定義ではシングルクォートを使うか、
# ダブルクォートをエスケープする必要があります。
# ws['B2'] = '=IF(B1>40, "合格", "不合格")' # これでもOK
# ws['B2'] = "=IF(B1>40, \"合格\", \"不合格\")" # エスケープする場合
wb.save("数式テスト.xlsx")
print("数式テスト.xlsx を保存しました。")
openpyxlは数式の計算自体は行いません。ファイルを開いたExcelアプリケーションが計算を実行します。data_only=True
で読み込んだ場合は、Excelが最後に計算した結果の値が取得されます。
3. セルの結合と解除 🔗
複数のセルを結合して1つのセルのように見せることができます。
from openpyxl import Workbook
from openpyxl.styles import Alignment, Font
wb = Workbook()
ws = wb.active
# セル範囲を結合 (A1からC2まで)
ws.merge_cells('A1:C2') # または ws.merge_cells(start_row=1, start_column=1, end_row=2, end_column=3)
# 結合したセルに値を書き込み、スタイルを設定 (左上のセル A1 に対して行う)
top_left_cell = ws['A1']
top_left_cell.value = "結合されたセル"
top_left_cell.alignment = Alignment(horizontal='center', vertical='center')
top_left_cell.font = Font(bold=True, size=16)
# D4からE5を結合
ws.merge_cells(start_row=4, start_column=4, end_row=5, end_column=5)
ws['D4'].value = "別の結合セル"
# 結合の解除 (A1からC2の結合を解除)
ws.unmerge_cells('A1:C2') # または ws.unmerge_cells(start_row=1, start_column=1, end_row=2, end_column=3)
wb.save("セル結合テスト.xlsx")
print("セル結合テスト.xlsx を保存しました。")
結合されたセル範囲への値の設定やスタイリングは、その範囲の左上のセルに対して行います。
4. グラフの作成 📈
openpyxlを使って、Excelシート内にグラフを作成することも可能です。様々な種類のグラフ(棒グラフ、折れ線グラフ、円グラフなど)をサポートしています。
from openpyxl import Workbook
from openpyxl.chart import BarChart, Reference, Series, LineChart
wb = Workbook()
ws = wb.active
# グラフの元になるサンプルデータ
rows = [
['カテゴリー', 'シリーズ1', 'シリーズ2'],
['A', 10, 40],
['B', 20, 30],
['C', 30, 60],
['D', 40, 25],
['E', 50, 50],
]
for row in rows:
ws.append(row)
# --- 棒グラフの作成 ---
bar_chart = BarChart()
bar_chart.title = "棒グラフの例"
bar_chart.style = 10 # グラフのスタイル番号 (任意)
bar_chart.y_axis.title = '数値'
bar_chart.x_axis.title = 'カテゴリー'
# データの範囲を指定 (B1:C6 の範囲)
# min_col=2 は B列, max_col=3 は C列
# min_row=1 は 1行目 (ヘッダー含む), max_row=6 は 6行目
data = Reference(ws, min_col=2, min_row=1, max_col=3, max_row=6)
# カテゴリ軸のラベル範囲を指定 (A2:A6 の範囲)
cats = Reference(ws, min_col=1, min_row=2, max_row=6)
bar_chart.add_data(data, titles_from_data=True) # titles_from_data=True で1行目を凡例に使用
bar_chart.set_categories(cats)
# グラフをシートに追加 (E2セルを左上隅として配置)
ws.add_chart(bar_chart, "E2")
# --- 折れ線グラフの作成 ---
line_chart = LineChart()
line_chart.title = "折れ線グラフの例"
line_chart.style = 12
line_chart.y_axis.title = "数値"
line_chart.x_axis.title = "カテゴリー"
# データ範囲とカテゴリは棒グラフと同じものを利用
line_chart.add_data(data, titles_from_data=True)
line_chart.set_categories(cats)
# グラフをシートに追加 (E18セルを左上隅として配置)
ws.add_chart(line_chart, "E18")
wb.save("グラフ作成テスト.xlsx")
print("グラフ作成テスト.xlsx を保存しました。")
グラフ作成は少し複雑に見えますが、Reference
クラスでデータ範囲とカテゴリ(軸ラベル)範囲を指定し、それをグラフオブジェクトに追加して、最後にws.add_chart()
でシート上の位置を指定して配置する、という流れになります。
パフォーマンスに関する注意点とヒント 🚀
openpyxlは非常に高機能ですが、特に巨大なExcelファイルを扱う際にはパフォーマンス(処理速度やメモリ使用量)に注意が必要です。
メモリ使用量
公式ドキュメントによると、通常の読み書きモードでは、openpyxlは元のファイルサイズの約50倍のメモリを使用することがあります(例:50MBのファイルで2.5GBのメモリ)。これは、Excelファイルの複雑な構造(書式、オブジェクトなど)をメモリ上にPythonオブジェクトとして表現するためです。
数GB単位のメモリが必要になることもあるため、非常に大きなファイルを扱う場合はメモリ不足に陥る可能性があります。
最適化モード (Optimized Modes)
大量のデータを扱う場合のために、openpyxlにはメモリ効率の良い「読み取り専用モード」と「書き込み専用モード」が用意されています。
-
読み取り専用モード (Read-Only Mode):
非常に大きなファイルを読み込む際にメモリ使用量を抑えます。ファイル全体を一度にメモリにロードせず、必要に応じてデータをストリーミング的に読み込みます。
from openpyxl import load_workbook # read_only=True を指定 wb = load_workbook(filename='巨大なファイル.xlsx', read_only=True) ws = wb.active # または wb['シート名'] # 読み取り専用モードでは、セルオブジェクトではなく直接値が返されることが多い # イテレータを使うのが効率的 for row in ws.iter_rows(values_only=True): # values_only=True で値のみのタプルを取得 # 各行の処理 print(row) # pass # 読み取り専用モードでは書き込みやスタイル変更はできません # 最後にワークブックを閉じるのが推奨される wb.close()
-
書き込み専用モード (Write-Only Mode):
大量のデータを書き込む際にメモリ使用量を最小限(10MB以下程度)に抑えます。データは逐次ファイルに書き込まれ、メモリ上には保持されません。
from openpyxl import Workbook from openpyxl.cell.cell import WriteOnlyCell # 書き込み専用セル from openpyxl.styles import Font # write_only=True を指定 wb = Workbook(write_only=True) ws = wb.create_sheet() # 書き込み専用モードでは append() を使うのが基本 ws.append(['ヘッダー1', 'ヘッダー2', 'ヘッダー3']) # 大量データの書き込み例 for i in range(1, 100001): # 10万行書き込む ws.append([i, f'データ {i}-A', f'データ {i}-B']) # 書き込み専用モードでは、個別のセルへのアクセスや既存データの読み取りはできない # スタイル設定は限定的に可能 (WriteOnlyCell を使う) styled_cell = WriteOnlyCell(ws, value="スタイル付き") styled_cell.font = Font(bold=True) ws.append([styled_cell, "通常のセル"]) # 最後に保存 wb.save("書き込み専用テスト.xlsx") print("書き込み専用テスト.xlsx を保存しました。")
書き込み専用モードでは、
append()
を使用して行単位でデータを追加していくのが主な使い方です。既存のセルへのアクセスや読み取りはできません。スタイルの適用も可能ですが、WriteOnlyCell
オブジェクトを介して行う必要があります。
その他のヒント
lxml
のインストール: 前述の通り、lxml
がインストールされていると書き込みパフォーマンスが向上することがあります。- イテレータの活用: 大量のセルを処理する場合、
ws.iter_rows()
やws.iter_cols()
を使うと、メモリ効率が良い場合があります。特にvalues_only=True
オプションを付けると、セルオブジェクトではなく値のタプルとして取得できるため、さらに効率的です。 - 不要な操作を避ける: 必要のないシートやセルまでアクセスしないように注意します。
- 代替ライブラリの検討: 非常に高速な書き込みが求められる場合や、.xlsx 形式の書き込みに特化したい場合は、
xlsxwriter
ライブラリも選択肢になります。ただし、xlsxwriter
は既存ファイルの読み込みや変更はできません。データ分析が主目的で、Excelの書式設定があまり重要でない場合は、pandas
ライブラリの Excel 入出力機能 (内部でopenpyxl
やxlsxwriter
を利用) を使うのが便利な場合も多いです。
ライブラリ | 主な用途 | メリット | デメリット |
---|---|---|---|
openpyxl | .xlsx/.xlsmファイルの読み書き、編集、書式設定、グラフ作成など全般 | 高機能、書式やグラフなど多くのExcel機能を扱える、既存ファイルの編集が可能 | メモリ使用量が大きい場合がある、巨大ファイルの処理は遅くなることがある |
xlsxwriter | .xlsxファイルの新規作成と書き込み | 書き込みが高速、メモリ効率が良い | 既存ファイルの読み込み・編集は不可 |
pandas | データ分析、データフレームのExcel入出力 | データ分析に特化、簡潔なコードで入出力可能 | Excelの詳細な書式設定やグラフ作成には不向き(別途openpyxl等が必要) |
実践的なユースケース 🏢
openpyxlは様々な場面で活用できます。以下にいくつかの例を挙げます。
- 定型レポートの自動生成: データベースや他のデータソースから取得した情報を基に、毎週・毎月提出するExcelレポートを自動で作成する。📈
- データ集計・整形: 複数のExcelファイルから特定のデータを抽出し、集計して新しいExcelファイルにまとめる。🧹
- 設定ファイルとしての利用: アプリケーションの設定情報をExcelファイルで管理し、Pythonスクリプトで読み込んで利用する。⚙️
- テストデータの生成: 大量のテスト用データをExcelファイル形式で生成する。🧪
- Webスクレイピング結果の保存: Webサイトから収集したデータをExcelファイルに整理して保存する。🕸️
- 請求書や見積書の自動作成: テンプレートとなるExcelファイルを基に、顧客情報や商品情報を埋め込んで個別の帳票を作成する。📄
例えば、2022年頃に筆者が個人的な健康管理のために、スマートウォッチで記録した運動データを手入力する代わりに、Pythonとopenpyxlを使って簡単な入力スクリプトを作成し、日々のデータをExcelに追記していく、といった活用例もありました。このように、日常のちょっとした作業の自動化にも役立ちます。
まとめ ✨
openpyxlは、PythonでExcelファイルを扱うための非常に強力で多機能なライブラリです。基本的な読み書きから、セルのスタイリング、数式の利用、グラフ作成、そして最適化モードによる大量データ処理まで、幅広いニーズに対応できます。
最初は覚えることが多いかもしれませんが、基本的な操作をマスターすれば、これまで手作業で行っていた多くのExcel作業を自動化し、大幅な効率化が図れるはずです。データ分析の前処理、レポート作成、業務の自動化など、活用の幅は無限大です。🚀
ぜひ、この解説を参考に、openpyxlを使ったExcel操作に挑戦してみてください! 😊
コメント