Excelのシート間参照をPNG図解する:pywin32 COM + Pillowで矢印を合成する
Excelコンテンツを書くとき、Sheet1のマスタ表からSheet2へINDEX/MATCHで参照していることを図で示す機会が多い。今までは Excelのウィンドウを Snipping Tool でキャプチャして、Illustrator を立ち上げて矢印を1本1本引いていた。1図あたり20分ほど消えていく。今日はこれをスクリプト化する方針を決めて、最初のプロトタイプまで動かした。
既存スキルとのすみ分け
リポジトリには既に excel-screenshot スキルがあり、こちらは HTMLレンダリング方式でExcel風のテーブルを描画する。文字組みもセル罫線もきれいに揃うが、本物のExcelとは見た目がわずかに違う。読者に「これは現物のExcelだ」と伝えたいときには使いにくい。
そこで今回は方針を分けた。
- HTML方式(既存): 文字情報が主で、見た目より構造を伝えたいとき
- 現物Excel方式(新規): シート間の参照リンクを「実際のExcelで動いている図」として見せたいとき
「現物Excelらしさ」を残す方を優先したかったので、pywin32 COM で本物のExcelを開いて CopyPicture で範囲を画像化することにした。
試作したスクリプトの流れ
scripts/excel-ref-diagram/ に以下の3要素を置いた。
- サンプルExcel生成: openpyxl で
Sheet1にマスタ表(社員ID・氏名・部署・給与)、Sheet2に=INDEX(Sheet1!C:C, MATCH(A2, Sheet1!A:A, 0))の参照式を入れた検証用ファイルを作る - 範囲キャプチャ: pywin32 で Excel.Application を起動し、
Range("B5:E10").CopyPicture(Appearance:=1, Format:=2)でクリップボードにビットマップを置き、PIL のImageGrab.grabclipboard()で取り出す - 矢印合成: Pillow で2枚のキャプチャ画像を左右に並べ、
ImageDrawで参照元セルから参照先セルへ曲線矢印を引く
最終的に scripts/excel-ref-diagram/output.png が生成される。指定はYAML/JSONで以下のように from/to を並べる想定にした。
arrows:
- from: "Sheet1!C5:C5"
to: "Sheet2!B2:B2"
label: "INDEX/MATCH"
複数の参照線がある場合も、配列に追記すれば一気に描ける構造にしてある。
Excelスクショ手段の選択肢比較
途中でユーザーから「そもそもExcelスクショをきれいに撮る方法はないか」と聞かれて、4つの選択肢を整理した。
| 方法 | クリーンさ | 手軽さ | 自動化 |
|---|---|---|---|
| 現物Excel + COM CopyPicture(今回) | 高 | 中 | 可能 |
| HTMLレンダリング(既存スキル) | 中 | 高 | 可能 |
| LibreOffice CLI でPDF出力→画像化 | 中 | 中 | 可能 |
| Snipping Tool 等の手動 | 高 | 低 | 不可 |
「現物の見た目」と「自動化」を両立できるのが COM 方式しかなく、結果として今回の方針に落ち着いた。ただし pywin32 COM は Windows 限定で、ヘッドレスでは動かない(Excel.exe を実際に起動する必要がある)という制約は残る。CI で回すのは現実的ではないので、ローカルで記事を書くときに走らせる手元スクリプトという位置づけになる。
朝の別セッションで話したSVGの話
同じ日の朝、SVGをPowerPoint/Illustratorに貼り付けられるかを別セッションで聞かれていた。これも今回の図解方針と地続きの話で、整理だけ残しておく。
- SVGは ベクター形式(Scalable Vector Graphics)。PowerPoint 2016以降と Illustrator の両方で扱える
- ピクセル/ラスター(PNG・JPG)と対比される。拡大しても破綻しない
- 「HTMLをSVGに変換する」のは罠が多い。一般的な方法では正確に変換できず、
html2canvas経由でラスタライズしてしまうのが現実解
今回のExcel図はラスター(PNG)で出している。CopyPicture には EMF 出力もあるので、必要になったらベクター化も検討する余地がある。
次にやること
- YAML設定ファイルのスキーマを固める(複数矢印・ラベル位置・色)
- 矢印が表をまたぐときの自動レイアウト(縦並び vs 横並びの判定)
- スキル化して
excel-ref-diagramとして.claude/skills/に登録 - サンプル出力をブログ記事に貼って実例を示す