Communityコーディング&開発github.com

html-to-pptx

HTMLスライドデッキ(1スライドあたり `.slide` div、1280x720)を、ネイティブかつ完全編集可能なPowerPointに変換——スライド画像ではなく、実際の矩形、角丸ボックス、ピル、円、線、矢印、自由形状、箇条書き、曲線テキストとテキストボックスにします。ユーザーが「このHTMLをパワポにしたい」「デッキをpptxに変換して」「PowerPointで編集できるようにして」「PowerPointに画像を貼るだけはやめて」と言ったり、HTMLデッキ/HTMLスライドショーを渡して.pptxにする必要があるときに使用します。どのブランドでも動作します。

html-to-pptx とは?

このスキルは、HTMLで書かれたスライドデッキ(各スライドが `.slide` クラスのdiv要素、解像度1280x720)を、完全に編集可能なPowerPoint (.pptx) ファイルに変換するためのツールです。単にスライドのスクリーンショット画像を貼り付けるのではなく、すべての視覚要素(矩形、角丸ボックス、ピル型、円、線、矢印、自由形状、箇条書き、曲線テキストなど)をPowerPointのネイティブオブジェクトとして再現する点が最大の特徴です。これにより、ユーザーは変換後のPowerPoint内で各要素を自由に移動、色変更、テキスト編集できます。Playwrightを使ってHTMLページの実際のレンダリング結果をキャプチャし、python-pptxライブラリで正確な座標に形状を書き出します。ArialおよびArial Blackフォントのテキスト配置は厳密に較正されており、CSSのグラデーション、クリップパス、SVG、箇条書き、テキスト変形なども適切に変換します。対応プラットフォームはPythonスクリプトとして提供され、PowerPointでの検証プロセスも含まれています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ImperaBusinessServices/html-to-pptx/tree/HEAD

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

HTMLデッキ → ネイティブ編集可能PPTX

このスキルが強制するルール:PowerPointにスライド画像を決して貼り付けないこと。 すべての矩形、バー、ドット、ピル、線、テキストブロックは、ユーザーが移動、色変更、再入力できる実際のPowerPointオブジェクトでなければなりません。コンバーターは、CSSを再推測する代わりにレンダリング済みページ(Playwright + ブラウザ自身の計算レイアウト)を読み取り、python-pptxのシェイプを全く同じ座標に書き出します。

実行方法

python scripts/html_to_pptx.py <deck.html> <out.pptx> [all | 1,3,5]

必要:pip install -r requirements.txt および playwright install chromium。 スライドは .slide(1280x720 px)にマッチする要素です。.html ファイルは、画像をインライン(data: URI)で含むか、または同じディレクトリに配置してください。examples/sample-deck.html は最初に試す小さなデッキです。

キャプチャ時のページの状態(スクリプトが自動実行):<html> から anim クラスを削除、CSSアニメーション/トランジションをオフ、window beforeprint を発火(デッキは印刷時にチャートを表示することが多い)、印刷メディア、ズーム1、.mode または .jump クラスの要素を非表示(テーマ切り替え、スライドナビゲーター)。ライト/ダーク切り替えがあるデッキは表示中のテーマで変換されます——それがユーザーの希望するテーマであることを確認してください。

変換対応表

HTML内PPTX内
背景・ボーダー・radiusを持つdiv/カード矩形/角丸矩形(radius → コーナー調整)
グラデーション背景(線形)ネイティブグラデーション塗りつぶし
片側ボーダー(アクセントストライプ)細い矩形;ヘアライン/破線ボーダー → 実線
border-radius:999px のピル、円ピル/楕円
テキスト(任意のブロック、太字/色付きラン、<br>、リンクを含む)ブロックごとに1テキストボックス、ランは維持、ハイパーリンクも維持
<li>実際のPowerPoint箇条書き(マーカー色も維持)
インラインSVG rect/circle/line/polyline/path/text矩形、楕円、コネクタ(矢印先端維持)、自由形状(実ベジェ曲線)、テキストボックス
SVG <textPath>(曲線上のテキスト)PowerPoint曲線テキスト(アーチ上/下ワープ)
CSS clip-path: polygon(...)(シェブロン、斜めカット)自由形状;内部の写真はポリゴンに切り抜き
<img>、写真、アイコンPNGピクチャ(ビットマップであることは許容)
text-transform、letter-spacing、取り消し線、opacity/alphaラン/塗りつぶしに適用
2ビュートグル(.vtog に data-view=code と data-view=time ボタン)もう一方のビュー用に2枚目のスライド
JSアニメーション最終静止状態のみ

苦労して得たルール(それぞれに時間を費やした——守ること)

  1. テキスト位置は較正済み。目視で「修正」しないこと。 PowerPoint 100%行間 = 1.2 × フォントサイズ(ArialとArial Black共通)。テキストボックスは top = rangeTop + (ascent-cap)*fs - lineHeight + K*fs に配置(Arialの場合 (ascent-cap, K) = (0.189, 0.95)、Arial Blackの場合 (0.385, 1.0))、line_spacing = cssLineHeight / (1.2*fs)。単一行テキストは行間100%、wrap=none、少し余白を持たせて改行しません。
  2. Windows上のChromeは font-family: Arial でweight 800/900をARIAL BLACKとしてレンダリングする。 コンバーターはこれをArial Black(太字ではない)にマッピングします。これを守らないと、すべての太い見出しが細く、幅が正しくなくなります。
  3. インラインブロックの子要素をテキストブロックに吸収しないこと。 display:inline の子だけが1つのテキストボックスに統合されます。インラインブロック/flexの子は個別に処理します。
  4. テキストノードはその場で計測する(ノード上のRange)。ノードを一時的な <span> でラップすると、grid/flexレイアウトが変わります。
  5. 結果をPowerPointで開いて有効であることを確認すること。 python-pptxはPowerPointが拒否するファイルを平気で書き出します(「PowerPoint でファイルを開けませんでした」)。既知の原因:負の値やNaNのシェイプサイズ(クランプ、NaNポイントを削除)、clip-path 内の calc()(評価する)。シェイプを半分ずつ削除して開き直すことで原因を特定します。
  6. カスタムジオメトリを持つピクチャは、フレームではなくパスのバウンディングボックスに収まる。 写真をポリゴンに切り抜くには、ピクチャをポリゴンのバウンディングボックスにサイズ合わせし、残りの部分にソースクロップ(srcRect)を設定します。
  7. シェイプをスクリーンショットでキャプチャしない(「変わったものはラスタライズ」)。代わりに、ロゴのSVGパスやクリップパスのポリゴンを自由形状に変換します。raster ブランチは最終手段です。
  8. クリップされたゴーストテキストはスキップする(カードで切り取られる大きなぼやけた数字)——PowerPointはテキストボックスをクリップできません。
  9. PowerPointの a:ln は spPr 内の塗りつぶしの後に配置します;テーマの p:style を削除するか、シェイプが影を拾わないようにします。
  10. ユーザーが開いている.pptxを上書きしない——代わりに新しいファイル名で書き出します。

検証(常に——確認せずに出荷しないこと)

PowerPointがインストールされたWindows:

powershell -NoProfile -File scripts/render_pptx.ps1 -pptx <out.pptx> -outdir <png_dir>     # PowerPointからPNG出力
python scripts/compare.py <deck.html> <png_dir> 1,2,3 <out.png>                           # HTML | PPTX 横並び比較
python scripts/compare.py <deck.html> <png_dir> 6:6,7:8 <out.png>                          # スライド番号が異なる場合 html:pptx

render_pptx.ps1 はユーザーが既にPowerPointを開いている場合はそのまま残します。PowerPointがない場合は、.pptxを他の方法(例:LibreOfficeヘッドレス)でPNGに変換し、s1.png、s2.png…として compare.py を実行します。

比較PNGを確認し、修正し、再ビルドします。実行後の典型的な微調整:PowerPointのテキストがわずかに広い(カーニング)、構造的な問題はありません。

既知の制限(ユーザーに伝えること)

  • テキスト配置は ArialおよびArial Black で較正されています。他のフォントでも変換されますが、そのフォントが較正されるまではテキストが数ピクセル上下にずれる可能性があります(PowerPointでキャップハイトと行間を測定してください)。
  • 写真、アイコン、ロゴがビットマップで提供された場合は、そのままピクチャとして残ります。テキストはカードの上に個別のボックスとして配置されます(グループ化されません)。
  • アニメーション/トグルは1フレームに平坦化されます(トグルの別ビューは追加スライドになります)。
  • 放射グラデーションとコーナーごとの半径は近似値です。ボックスシャドウは削除されます。
  • スライドサイズは1280x720ピクセル → 13.333 x 7.5インチに固定されます。

クレジット

Impera Business Services によって構築されました。MITライセンス — LICENSE を参照してください。

関連スキル