Python Excel操作 逆引き集 | xls(旧形式)ファイルを読む

Python Python
スポンサーリンク

xls(旧形式)を読むときにまず知っておくべきこと

.xls は Excel 97〜2003 の旧形式で、現在の .xlsx とは内部構造がまったく違います。
そのため、pandas が .xls を読むときは xlrd という専用エンジンを使う必要があります。

ただし重要な点として、現在の xlrd は .xlsx をサポートしないだけでなく、
環境によっては .xls の読み込みも制限されることがあります。

そのため .xls を扱うときは、

  • 本当に .xls なのか確認する
  • engine="xlrd" を明示する
  • 読めない場合は .xlsx に変換する(最も安定)

という流れを意識しておくと安全です。


xls を xlrd で読む基本形

最小コード

import pandas as pd

df = pd.read_excel(
    "old_data.xls",
    engine="xlrd"
)

print(df.head())
print(df.info())
Python

.xls を読むときは、まずこの形を試します。
engine="xlrd" を付けないと、環境によってはエラーになることがあります。


なぜ engine=’xlrd’ が必要なのか

よく出るエラーの例

.xls を engine 指定なしで読み込むと、次のようなエラーが出ることがあります。

ValueError: Excel file format cannot be determined, you must specify an engine manually.
Python

または、

ImportError: xlrd is not installed
Python

これは pandas が「どのエンジンで開けばいいかわからない」状態です。
.xls は古い形式なので、openpyxl では読めません。
そのため、engine="xlrd" を明示する必要があります。


xls を読むときの注意点

xlrd のバージョンによっては .xls しか読めない

現在の xlrd は .xlsx をサポートしていません。
つまり、.xlsx を xlrd で読むことはできません。

xls の仕様が古く、読み込みが不安定なことがある

.xls は古いバイナリ形式で、セルの型やエンコーディングが不安定なことがあります。
そのため、読み込み後に型を整える処理が必要になることが多いです。


xls を読み込んだあとに型を整えるテンプレート

日付・数値を整える例

import pandas as pd

df = pd.read_excel(
    "old_sales.xls",
    engine="xlrd",
    usecols=["日付", "数量", "金額"]
)

df["日付"] = pd.to_datetime(df["日付"], errors="coerce")
df["数量"] = pd.to_numeric(df["数量"], errors="coerce")
df["金額"] = pd.to_numeric(df["金額"], errors="coerce")

print(df.head())
print(df.dtypes)
Python

.xls はセルの型が崩れやすいため、
to_datetimeto_numeric を使って「読み込み後に整える」ことが非常に重要です。


xls を読み込んでから xlsx に変換する(安定運用)

一度だけ変換してしまう方法

import pandas as pd

df = pd.read_excel("old_data.xls", engine="xlrd")
df.to_excel("converted.xlsx", index=False)
Python

この方法のメリットは、

  • 以降は .xlsx として openpyxl で安定して読める
  • 型崩れが減る
  • 将来の pandas バージョンでも動きやすい

という点です。

実務では「古い .xls は最初に .xlsx に変換してしまう」運用が最も安定します。


xls を複数シート含むブックとして読む

sheet_name=None と組み合わせる

import pandas as pd

dfs = pd.read_excel(
    "old_book.xls",
    sheet_name=None,
    engine="xlrd"
)

for name, df in dfs.items():
    print("=== シート:", name, "===")
    print(df.head())
Python

.xls でも複数シートを辞書として読み込めます。
ただし、古い形式なのでシート名の文字化けが起きることがあります。


xls を扱うときの実務的な判断ポイント

  • .xls は古い形式で、読み込みが不安定
  • engine="xlrd" を明示しないとエラーになることがある
  • xlrd のバージョンによっては制限がある
  • .xlsx に変換してしまう方が長期的に安全
  • 読み込み後の型変換は必須レベル

特に「型崩れ」「文字化け」「日付が数字になる」などの問題は .xls で頻発します。


実践テンプレート

テンプレ1:旧形式の売上データを読み、月次集計する

import pandas as pd

df = pd.read_excel(
    "old_sales.xls",
    engine="xlrd",
    usecols=["日付", "金額"]
)

df["日付"] = pd.to_datetime(df["日付"], errors="coerce")
df["金額"] = pd.to_numeric(df["金額"], errors="coerce")

monthly = (
    df.assign(month=df["日付"].dt.to_period("M"))
      .groupby("month", as_index=False)["金額"].sum()
)

print(monthly)
Python

テンプレ2:旧形式のマスタと明細を読み、結合する

import pandas as pd

dfs = pd.read_excel("old_book.xls", sheet_name=None, engine="xlrd")

master = dfs["master"]
detail = dfs["detail"]

master["商品コード"] = master["商品コード"].astype(str)
detail["商品コード"] = detail["商品コード"].astype(str)

merged = detail.merge(master, on="商品コード", how="left")

print(merged.head())
Python

小さな練習問題

練習1:old_sales.xls を読み、日付と金額を整えて月次合計を出す

条件は次の通りです。

  • engine="xlrd" を指定する
  • 日付to_datetime で整える
  • 金額to_numeric で整える
  • 月次合計を計算する

練習2:old_book.xls の "master" と "detail" を読み、商品コードで結合する

条件は次の通りです。

  • sheet_name=None で辞書として読む
  • 商品コードを文字列に揃える
  • merge で結合する

最後に

.xls は古い形式で、現在の pandas では扱いにくい場面が増えています。
そのため、

  • 読むときは engine="xlrd" を明示
  • 読めない場合は .xlsx に変換
  • 読み込み後に型を整える

という3ステップを基本にしておくと、トラブルを最小限にできます。

タイトルとURLをコピーしました