「テーマフォントが原因」というところまでは、探せば辿り着ける。だが実際にファイルの中で何が参照し合っているのかを見た人は少ない。本稿では .xlsx の中身を開いて仕組みを確かめ、そのうえで「では、どう直すか」までを書く。急いでいる人は、先に「直し方」の節へ進んでかまわない。
フォントが勝手に変わったセルを選び、[ホーム]タブのフォント欄を見てほしい。
游ゴシック (本文) のように 括弧つき で表示される → そのセルは書体名を持っておらず、ブックの「テーマ」が本文用に指定している書体を参照している游ゴシック のように 括弧なし → 書体名を直接持っている(固定指定)括弧つきのセルは、テーマが変わると自分では一文字も触っていないのに書体が入れ替わる。[ページ レイアウト]→[テーマ]や[フォント]を切り替えたとき、別のテーマのブックにシートをコピーしたとき、既定のテーマが違う環境で新しいブックを作ったとき、いずれも同じことが起きる。「フォントが勝手に変わる」の大半は、この参照先の差し替えで説明がつく。
.xlsx はただの ZIP なので、覗くのに5分もかからない。手元の適当なブックで試すなら、拡張子を .zip に変えるか unzip コマンドを叩くだけでいい。
$ unzip -l sample.xlsx
Length Date Time Name
--------- ---------- ----- ----
1234 2026-07-01 09:00 xl/theme/theme1.xml
5678 2026-07-01 09:00 xl/styles.xml
...
2345 2026-07-01 09:00 xl/worksheets/sheet1.xml
犯人は xl/theme/theme1.xml にいる。中を cat すると、こんな塊が出てくる。
<a:fontScheme name="Office">
<a:majorFont>
<a:latin typeface="Aptos Display"/>
<a:font script="Jpan" typeface="游ゴシック Light"/>
</a:majorFont>
<a:minorFont>
<a:latin typeface="Aptos"/>
<a:font script="Jpan" typeface="游ゴシック"/>
</a:minorFont>
</a:fontScheme>
ここで面白いのは、<a:latin> と <a:font script="Jpan"> が別枠だという点だ。「テーマの本文フォント」はひとつの値ではなく、スクリプト(文字体系)ごとに引き当て先が分かれたテーブルになっている。Microsoft は 2023年7月に既定の書体を Calibri から Aptos に切り替えると発表したが、このファイルで Aptos になっているのは Latin 側の値で、Jpan 側は游ゴシックのままだ。日本語の見た目は変わらず、英数字だけが Aptos に寄っている——「変わったような、変わっていないような」という体感は、これで説明がつく。
セル側の参照は xl/styles.xml の <fonts> コレクションを見るとわかる。
<font>
<sz val="11"/>
<color theme="1"/>
<name val="游ゴシック"/>
<family val="2"/>
<scheme val="minor"/>
</font>
name val="游ゴシック" は一見固定指定に見えるが、<scheme val="minor"/> が付いている限り、Excel はテーマ(theme1.xml)の本文フォントを参照する。name 側の値は、スキームを解釈できないリーダー向けのフォールバックと考えるとよい。フォント欄の括弧つき表示は、この scheme 属性の有無に対応している。
グラフやテキスト ボックスを含むブックだと、xl/drawings/ 配下に DrawingML が混ざる。ここでは +mn-lt(minor latin)や +mj-lt(major latin)というショートハンドがそのまま typeface 属性に書かれる。セル側の scheme 属性と表現は違うが、指している先は theme1.xml の同じテーブルだ。グラフだけフォントが変な動きをするときは、大抵ここを疑うといい。
ブック全体をバイナリで diff しても意味はない。見るべきは該当パーツだけを取り出した差分だ。
$ diff <(unzip -p a.xlsx xl/theme/theme1.xml) <(unzip -p b.xlsx xl/theme/theme1.xml)
これで「テーマそのものが別物」なのか「テーマは同じでセル側のフォント指定だけ違う」のかが一発で分かる。
共有フォルダーのテンプレートが複数世代あって、どれが「本家」か分からなくなっている職場なら、フォルダー全体を機械的に棚卸しするのも難しくない。
import zipfile, xml.etree.ElementTree as ET, glob
ns = {"a": "http://schemas.openxmlformats.org/drawingml/2006/main"}
for path in glob.glob("*.xlsx"):
with zipfile.ZipFile(path) as z:
xml = z.read("xl/theme/theme1.xml")
root = ET.fromstring(xml)
minor = root.find(".//a:minorFont/a:latin", ns).get("typeface")
print(path, minor)
どのテンプレートが Calibri 前提で、どれが Aptos 前提なのかが一覧で出る。ズレの発生源、つまり「最初にズレた1個」を名指しできるのが強い。
書体だけでなく行の高さまで変わる場合、そのブックが使っている書体が、開いた PC に入っていない可能性がある。入っていない書体は別の書体に置き換えて表示され、その書体に合わせて行の高さも計算し直される。送った側では整っていた表が、受け取った側では詰まったり間延びしたりするのはこのためだ。
共有するファイルは、相手の PC にも確実に入っている書体を使うと、この事故はほぼ防げる。
これでセルはテーマ参照をやめ、書体名を直接持つようになる。以後テーマが変わっても釣られない。
テーマ参照のまま、参照先の書体をそろえたい場合は、**[ページ レイアウト]→[テーマ]グループの[フォント]** で書体の組み合わせを選ぶ。独自の組み合わせを作るなら[フォントのカスタマイズ]で見出し用・本文用の書体を指定して保存する。
新しいブックが毎回思わぬ書体で始まるのを止めるには、既定のフォントを決めておく。
変更が反映されるのは、再起動後に作成した新しいブックだけで、既存のブックには影響しない。既存のブックに適用したい場合は、新しいブックを作ってシートを移す必要がある。
組織として再発を止めたいなら、直すべきは末端の個々のブックではなく、theme1.xml を内包しているテンプレート(.xltx)の側だ。テンプレートの棚卸しには、上の Python スクリプトがそのまま使える。
Web ページや別のブックからコピーすると、書式ごと貼り付いてフォントが混ざることがある。貼り付けるときに Ctrl + Alt + V(形式を選択して貼り付け)で[値]を選べば、書式は持ち込まれない。
Windows の表示スケール(125%・150% など)や、Excel の表示倍率を変えた状態では、フォント サイズは変わっていないのに見た目だけ変わることがある。フォント欄の書体名とサイズの数値が同じなら、ファイルの中身は変わっていない。疑うべきは表示設定のほうだ。
列の幅や行の高さが変わる問題はこちらの記事で扱っている。
参考: