タイトル: Excelのセルの値を読み込む方法(xlrd編)
SEOタイトル: Python xlrd で Excel を読み込む方法と xlsx 非対応問題(openpyxl 移行ガイド)
| この記事の要点 |
|
重要: xlrd 2.0+ は .xls 専用
2020 年 12 月に xlrd 2.0.0 がリリースされ、.xlsx の読み込みサポートが削除されました。.xlsx を扱いたい場合は別ライブラリへの移行が必要です。
| バージョン | 対応形式 | 推奨度 |
|---|---|---|
| xlrd 1.2.0 以下 | .xls / .xlsx 両方 | セキュリティ更新なし、新規利用は非推奨 |
| xlrd 2.0+ | .xls のみ | レガシー .xls 専用 |
| openpyxl | .xlsx のみ | .xlsx の標準 |
| pandas.read_excel | 両方(内部で openpyxl / xlrd) | 表形式データには最も便利 |
xlrd の基本的な使い方(.xls)
pip install xlrdimport xlrd
# ファイルを開く
book = xlrd.open_workbook('sample.xls')
# シート一覧
print(book.sheet_names()) # ['Sheet1', 'Sheet2']
print(book.nsheets) # 2
# シート取得
sheet = book.sheet_by_index(0)
# または名前で取得
sheet = book.sheet_by_name('Sheet1')
# シートの行数・列数
print(sheet.nrows, sheet.ncols) # 100 5
# セルの値取得(0 始まり)
value = sheet.cell_value(0, 0) # A1
print(value)
# セル全体(型情報も含む)
cell = sheet.cell(0, 0)
print(cell.value, cell.ctype)
全セルをループで読む
import xlrd
book = xlrd.open_workbook('sample.xls')
sheet = book.sheet_by_index(0)
# 1 行目をヘッダーとして使う
headers = [sheet.cell_value(0, c) for c in range(sheet.ncols)]
print(headers) # ['name', 'age', 'email']
# 2 行目以降をデータとして読む
for r in range(1, sheet.nrows):
row = {}
for c in range(sheet.ncols):
row[headers[c]] = sheet.cell_value(r, c)
print(row)
セルの型(ctype)
| 定数 | 値 | 意味 |
|---|---|---|
XL_CELL_EMPTY | 0 | 空セル |
XL_CELL_TEXT | 1 | 文字列 |
XL_CELL_NUMBER | 2 | 数値(int / float) |
XL_CELL_DATE | 3 | 日付(シリアル値) |
XL_CELL_BOOLEAN | 4 | 真偽値 |
XL_CELL_ERROR | 5 | エラー値 |
XL_CELL_BLANK | 6 | 空白セル |
日付の変換
Excel の日付は内部的に「1900-01-01 からのシリアル値」なので、Python の datetime に変換する必要があります:
import xlrd
from datetime import datetime
book = xlrd.open_workbook('sample.xls')
sheet = book.sheet_by_index(0)
cell = sheet.cell(1, 2)
if cell.ctype == xlrd.XL_CELL_DATE:
# シリアル値 → (年, 月, 日, 時, 分, 秒)
date_tuple = xlrd.xldate_as_tuple(cell.value, book.datemode)
dt = datetime(*date_tuple)
print(dt) # 2024-03-15 10:30:00
.xlsx を読みたい: openpyxl への移行
pip install openpyxlimport openpyxl
# ファイルを開く(data_only=True で数式の結果値を取得)
book = openpyxl.load_workbook('sample.xlsx', data_only=True)
# シート取得
sheet = book['Sheet1']
# または book.active で先頭シート
# セルの値(A1, B2 等の表記が使える)
print(sheet['A1'].value)
print(sheet.cell(row=1, column=1).value) # 1 始まり
# 行数・列数
print(sheet.max_row, sheet.max_column)
# 全行イテレート
for row in sheet.iter_rows(min_row=2, values_only=True):
print(row) # tuple
# 範囲指定
for row in sheet['A2:C10']:
for cell in row:
print(cell.value)
pandas.read_excel が一番楽
import pandas as pd
# xlsx も xls も読める(要 openpyxl or xlrd)
df = pd.read_excel('sample.xlsx', sheet_name='Sheet1')
# 1 行目を自動でヘッダーに
print(df.head())
print(df.columns.tolist()) # 列名
print(df['name'].tolist()) # 特定列を list で
# 全シート読み込み
sheets = pd.read_excel('sample.xlsx', sheet_name=None) # dict
for name, df in sheets.items():
print(name, df.shape)
# 指定行から
df = pd.read_excel('sample.xlsx', skiprows=3, header=0)
# 列を指定して読む
df = pd.read_excel('sample.xlsx', usecols='A:C')
df = pd.read_excel('sample.xlsx', usecols=['name', 'age'])
xlrd / openpyxl / pandas の使い分け
| 用途 | 推奨ライブラリ |
|---|---|
| 古い .xls ファイル | xlrd 2.0+ |
| .xlsx を読むだけ | openpyxl(軽量) |
| .xlsx を書く・編集 | openpyxl |
| 表形式データを集計・加工 | pandas(最も楽) |
| 大量データ(100MB+) | pandas + chunksize / openpyxl read_only |
| 図形やグラフを含む xlsx | openpyxl(一部制限あり) |
よくあるエラー
xlrd.biffh.XLRDError: Excel xlsx file; not supported
→ xlrd 2.0+ で .xlsx を開こうとした
→ 対処: openpyxl に切替 or pip install xlrd==1.2.0FileNotFoundError: [Errno 2] No such file or directory: 'sample.xlsx'
→ 相対パス問題。実行ディレクトリと違う場所にファイルがある
→ 対処: 絶対パスで指定 or os.path.dirname(__file__) を使う
FAQ
Q: 既存スクリプトが xlrd で xlsx を読んでいる、最小修正で動かしたい
A: pip install xlrd==1.2.0 でダウングレード可能。ただしセキュリティ更新なしのため、新規開発では openpyxl 推奨。
Q: パスワード付き Excel を開きたい
A: xlrd / openpyxl では非対応。msoffcrypto-tool で復号してから読み込む手順が必要。
Q: 数式の結果ではなく式そのものを取得したい
A: openpyxl で load_workbook(... , data_only=False)。セルの .value が =SUM(A1:A10) 等の文字列で取れます。