商品名の改称や部署の統合など、表の中の同じ表記をまとめて直したい場面は少なくありません。数式で参照されているわけではなく、ただ文字だけを新しい名前に揃えたい——そんなとき、Excel の[検索と置換]ダイアログを開いて 1 件ずつ確認していくのは、行数が増えるほど手間になります。
本記事では、Spire.XLS for Python を使用して Python で Excel のデータを検索して置換する方法 を紹介します。シート全体を対象にする場合と、特定のセル範囲に限定する場合の 2 通りを、実際の動作を確認しながら解説します。
クイックナビゲーション
実行環境の準備
本記事のコードは Spire.XLS for Python と plum-dispatch v1.7.4 で検証しています(動作確認は Spire.XLS for Python 16.8.2)。Excel 本体は必要ありません。
pip install Spire.XLS
スクリプトでは、次の 2 行をインポートします。
from spire.xls import *
from spire.xls.common import *
以降のサンプルには、商品別と担当者別の 2 つの集計表を持つブックを使います。金額は数値セル(桁区切り #,##0)で、どちらの表にも「合計」と「合計(税込)」の行があります。

検索の基本:FindAllString() が返すもの
置換の前段は検索です。Worksheet.FindAllString() に探したい文字列を渡すと、一致したセルが CellRange のコレクションとして返ります。for 文でそのまま反復でき、各要素はセル範囲なので Text や Style を普段どおり操作できます。
found = sheet.FindAllString("合計", False, False)
print(len(found)) # 見つかったセルの件数
サンプルブックで実行すると、4 件が見つかります。
FindAllString('合計', False, False) -> 4 件
'売上データ'!A5: '合計'
'売上データ'!A6: '合計(税込)'
'売上データ'!A12: '合計'
'売上データ'!A13: '合計(税込)'
ここで押さえておきたいのが 一致の判定ルールです。実測した挙動は次のとおりです。
- 大文字と小文字は区別されない —
"plan"と"PLAN"は同じ結果になります。区別するオプションはありません。 - 部分一致である — 「合計」で検索すると「合計(税込)」もヒットします。
- ワイルドカードや正規表現は使えない —
"合*"のような指定は 0 件になります。 - 比較対象は「表示されている文字列」 — 数値セルは書式を適用したあとの文字列で判定されます。
#,##0を設定した 2,940 のセルは"2,940"でヒットし、"2940"ではヒットしません。
第 2・第 3 引数は数式に関するフラグです(数式を対象に含めるか、その計算結果を含めるか)。文字列セル・数値セルを検索するだけなら False, False のままで構いません。実際、4 通りの組み合わせを試しても結果は同じでした。
なお、数値セルを検索で見つけたあと CellRange.Text を読むと空文字が返ります。 Text が返すのは文字列セルの中身だけだからです。画面に見えているとおりの文字列を確認したいときは、CellRange.DisplayedText を使ってください。
cell = sheet.Range["B5"]
print(cell.Text) # '' ── 数値セルでは空
print(cell.DisplayedText) # '2,940' ── 画面に見えている文字列
シート全体のデータを置換する
見つかったセルは CellRange なので、書き換えは Text への代入だけで済みます。シート全体を対象にする場合の流れは次のとおりです。
- ブックを読み込む
Worksheet.FindAllString()で一致するセルを集める- 見つかったセルをループし、
Textに新しい値を代入する - あとから確認しやすいように背景色を付ける
- 別名で保存する
from spire.xls import *
from spire.xls.common import *
# Workbook オブジェクトを作成し、ファイルを読み込む
workbook = Workbook()
workbook.LoadFromFile("SampleSales.xlsx")
# 最初のワークシートを取得
sheet = workbook.Worksheets[0]
# 「合計」を含むセルをシート全体から探す
found = sheet.FindAllString("合計", False, False)
# 見つかったセルの値を「総計」に書き換える
for cell in found:
cell.Text = "総計"
cell.Style.Color = Color.get_Yellow()
# 別名で保存
workbook.SaveToFile("ReplaceInWorksheet.xlsx", ExcelVersion.Version2016)
workbook.Dispose()

4 セルすべてが「総計」になりました。ただし、2 つの表の「合計(税込)」も「総計」になっている点に注目してください。FindAllString() は部分一致でセルを拾いますが、Text への代入はセルの中身を丸ごと差し替える操作です。一致した部分だけが置き換わるわけではないため、後ろに続く文字列は失われます。
「合計(税込)」の行はそのまま残したい——そうした場合は「一致した部分だけを置き換える」の方法を使ってください。
特定のセル範囲だけを置換する
商品別の表はそのままにして、担当者別の表だけを直したいこともあります。その場合は Worksheet ではなく、セル範囲に対して FindAllString() を呼びます。書き換えの手順はシート全体のときと同じです。
from spire.xls import *
from spire.xls.common import *
workbook = Workbook()
workbook.LoadFromFile("SampleSales.xlsx")
sheet = workbook.Worksheets[0]
# 置換したいセル範囲を取得(担当者別の表)
target = sheet.Range["A8:D13"]
# その範囲の中だけで「合計」を含むセルを探す
found = target.FindAllString("合計", False, False)
for cell in found:
cell.Text = "総計"
cell.Style.Color = Color.get_Yellow()
workbook.SaveToFile("ReplaceInRange.xlsx", ExcelVersion.Version2016)
workbook.Dispose()

対象が 2 件に減り、上の商品別の表は「合計」のまま残っています。範囲は Range["A8:D13"] のようなアドレス指定でも、Range[8, 1, 13, 4] のような行・列指定でも構いません。
一致した部分だけを置き換える
セルの中身を丸ごと書き換えたくない場合は、見つかったセルの現在の値を読み、文字列として差し替えてから代入します。テキストセルであれば CellRange.Text に現在の値が入っているので、Python の str.replace() がそのまま使えます。
found = sheet.FindAllString("合計", False, False)
for cell in found:
cell.Text = cell.Text.replace("合計", "総計")
cell.Style.Color = Color.get_LightGreen()
実行すると、次のように「(税込)」が保たれたまま置き換わります。

シート全体を対象にしてよいなら、Worksheet.ReplaceAll() を使う手もあります。こちらはセルの値の一部だけを差し替え、戻り値として置換件数を返します。第 3 引数は省略できず、2 引数で呼び出すと NotFoundLookupError で停止します。
# シート全体で「合計」を「総計」に差し替える(戻り値は置換件数)
count = sheet.ReplaceAll("合計", "総計", False)
print(count) # 4
一方、セル範囲に対する CellRange.Replace() は実測では機能しません。 呼び出しても例外は出ず、戻り値は None のまま、値も変化しません。範囲を限定して一部だけを置き換えたいときは、CellRange.FindAllString() で対象を絞り、cell.Text.replace(...) で書き換える形にしてください。
なお、ReplaceAll() は数値セルを文字列に変えてしまいます。桁区切り書式の 1,200 を "2,000" に置換すると、セルは数値ではなく文字列の 2,000 になります。数値を保ったまま書き換えたいときは、FindAllString() で見つけたセルに CellRange.Value を使います。
for cell in sheet.FindAllString("2,940", False, False):
cell.Value = "3,000" # 数値として入る(NumberValue は 3000.0)
まとめ
検索から置換までの流れを、あらためて確認します。
- 探す —
Worksheet.FindAllString()でシート全体、CellRange.FindAllString()でセル範囲から、一致するセルを集める - 書き換える — 見つかったセルの
Textに新しい値を代入する。前後の文字列を残したいときはcell.Text.replace()を使う - 印を付ける —
Style.Colorで背景色を付けておくと、置換箇所をあとから目視で確認できる
判定は「表示されている文字列」に対する部分一致で、大文字小文字は区別されません。ワイルドカードや正規表現は使えないため、複雑な条件で絞り込みたい場合は、いったん全件を取り出してから Python 側で if を書くほうが確実です。
「合計」のような短い語を検索するときは、意図しないセルまで拾いやすい点にも気を付けてください。置換前に found の中身を出力して、対象を一度確認する習慣を付けておくと安全です。
Spire.XLS for Python の全機能を評価したい場合は、30 日間の無料ライセンスを申請できます。なお無償の試用版では、保存したファイルに評価用の警告シートが追加されます。ライセンスを適用するとこれも出力されなくなります。
FAQ
大文字と小文字を区別して検索・置換できますか?
できません。FindAllString() は大文字小文字を区別せずに比較するため、"plan" と "PLAN" は同じ結果を返します。区別するための引数やオプションは用意されていません。大文字小文字を厳密に扱いたい場合は、found の各セルについて CellRange.Text を Python 側で比較し、条件に合うものだけを書き換えてください。
「合計」を含むセルではなく、完全一致のセルだけを置換するには?
FindAllString() に完全一致の指定はないため、見つかったセルを取得したあとに値を比較して絞り込みます。テキストセルであれば CellRange.Text にセルの中身が入っているので、次のように書けます。
found = [c for c in sheet.FindAllString("合計", False, False) if c.Text == "合計"]
この条件では「合計(税込)」は除外され、「合計」だけが書き換わります。数値セルが混ざる可能性がある場合は、CellRange.DisplayedText で比較してください。
数式セルの中身も置換されますか?
数式そのものは検索対象になりません。=1+2 のような数式があるセルを "1+2" で検索してもヒットしません。数式の計算結果を対象にしたい場合は、Workbook.CalculateAllValue() で計算させたうえで、第 2・第 3 引数を両方 True にします。実測では、この組み合わせのときだけ =CONCATENATE("合","計") のセルが「合計」でヒットしました。
ブック内の複数のシートをまとめて置換できますか?
できます。FindAllString() はワークシート単位のメソッドなので、シートを順に処理します。このとき for sheet in workbook.Worksheets で反復しないでください。 反復で得られるのは XlsWorksheet という別のオブジェクトで、FindAllString() を持っていません。インデックスで取得します。
for i in range(workbook.Worksheets.Count):
sheet = workbook.Worksheets[i]
for cell in sheet.FindAllString("合計", False, False):
cell.Text = "総計"
数値セルを置換したら文字列になってしまいました。
Worksheet.ReplaceAll() は値の一部を文字列として差し替えるため、数値セルが文字列に変わります(桁区切り書式の 1,200 を "2,000" に置換すると、セルは文字列の 2,000 になります)。数値のままにしたい場合は、FindAllString() で見つけたセルに CellRange.Value で代入してください。cell.Value = "3,000" のように桁区切りを含む文字列を渡しても、数値の 3000 として格納されます。
置換したセルにだけ色を付けられますか?
付けられます。見つかったセルは CellRange なので、CellRange.Style.Color に色を代入します。Color.get_Yellow() や Color.get_LightGreen() のように名前付きの色を指定できます。塗りつぶしではなく文字色を変えたい場合は Style.Font.Color、太字にしたい場合は Style.Font.IsBold を使ってください。






