🎯 はじめに:この記事のスコープ
シリーズ「脱Microsoft・OSS移行」は、ここまで ハードウェア → OS → 開発環境 → データ層 → Microsoft 365 → Google Workspace → リモート開発 と積み上げてきました。第 8 回は、第 1 回で 「移行の最大ブロッカー」 と書いた ActiveReports の置換です。
読み進めやすい順番では後半に置いていますが、移行プロジェクトとしては Phase 1 です。帳票が Windows + Visual Studio のままでは、Linux 開発機に移っても出荷業務が止まります。
| 本記事の扱う範囲 | 隣接領域 | |
|---|---|---|
| 本記事(第 8 回) | A4 納品書・ピッキングリストを Scriban HTML + Playwright Chromium の PDF に置換 / Code128・日本語 QR をサーバー側 SVG で埋め込み / 用紙超過の描画前拒否 / Windows 印刷エージェントの claim・submitted・要確認 / ラベルプリンターは PDF にせず SBPL | 運送会社の送り状 API・配送ラベル規格、実紙のミシン目合わせ、適格請求書の税計算 |
💡 Playwright は Microsoft 製 OSS です。 本シリーズの「脱Microsoft」は、Windows / Visual Studio / 商用帳票の ライセンス連鎖を切る話であって、Apache 2.0 の Playwright や .NET ランタイムまで捨てる話ではありません。帳票の描画エンジンとして Chromium を使う判断と、IDE のサブスクを払い続ける判断は別物です。
🚫 なぜ ActiveReports が移行の最大ブロッカーなのか
第 1 回で書いた 4 つの値上げのうち、帳票だけが 「OS を変えると業務が止まる」 種類のロックインです。今回 CTS が切った直接の理由は、次の 3 点です。
1. .NET を上げるたびに、高額なバージョンアップ費用が乗る
ActiveReports は 特定の .NET バージョン専用に組まれています。.NET 8 → 9 → 10 とランタイムを追うたびに、帳票エンジンも対応版へ買い直す必要があります。Microsoft が .NET を年次リリースに変えた結果、帳票側の更新サイクルも引きずられて短くなり、事実上の毎年課金になります。
アプリ本体は SDK を入れれば上がる。帳票だけが、そのたびに見積と発注を要求する。この非対称が、少数精鋭では特に効きます。
2. 1 ライセンス = 1 PC が、人数より先に重荷になる
ライセンスは PC 単位です。開発機、印刷用の Windows、予備ノート、検証用のもう 1 台、と増えるたびに 1 本ずつ必要になります。社員数ではなく 触る機械の台数で課金されるため、デュアルブートやリモート開発(第 7 回)を始めると、すぐ台数が膨らみます。Linux 側の VS Code には載せられず、Windows に戻って設計器を開く、その Windows にもライセンスが要る、という循環です。
3. ソースを共有すると、ActiveReports のファイルだけ宙に浮く
RDLX は Git に入ります。ただし開けるのは ライセンスの入ったその PC の Visual Studio 設計器だけです。ライセンスのないマシン、Linux、Dev Container、AI エージェントの作業用クローンでは、ファイルはあるのにプレビューも編集もできません。共有リポジトリの中で、帳票定義だけが 誰も触れない遺物になります。
HTML/CSS のテンプレートなら、ブラウザかエディタで開いて差分が読めます。RDLX は「リポジトリにはあるが、設計器のある席に座らないと存在しない」状態です。ソース共有・レビュー・引き継ぎが前提の今の開発では、ここが決定的に合いません。
| 制約 | 現場で起きること |
|---|---|
| .NET 更新 × 高額バージョンアップ | 8 → 9 → 10 のたびに帳票エンジンも再購入。アプリは追えるが帳票だけ見積が要る |
| 1 ライセンス = 1 PC | 開発機・印刷機・予備機がそれぞれ 1 本。人数より台数で膨らむ |
| 共有ソースで RDLX が宙に浮く | Git にはあるが、ライセンス PC の設計器以外では開けない |
| Windows + Visual Studio 前提 | 設計器もランタイム印刷も Windows。Linux 側だけで納品書を出せない |
| RDLX + VB 式 | 紙面定義が専用 XML。CSS の mm 指定のように「ブラウザで開いて直す」ができない |
| プレビューと無人印刷が同一ランタイム | WPF の自動印刷も ActiveReports 依存。エンジンを残したまま UI だけ差し替えると二重投資になる |
⚠️ 「帳票だけ Windows に残す」は安全網に見えて、毎日の出荷を Windows に釘付けにします。 デュアルブートは e-Tax や周辺機器の退避先としては有効ですが、10 分間隔の無人印刷まで Windows に残すと、Linux 移行の効果が出ません。ブロッカーから潰す理由はここにあります。
代替候補は一通り見たうえで、次の結論にしています。
| 候補 | 見送り理由 |
|---|---|
| QuestPDF / PdfSharp | 紙面が C# になる。RDLX の mm 座標を再現する作業がコードレビューに乗りにくい |
| wkhtmltopdf | メンテが止まっている。古い WebKit では日本語フォントと CSS ページサイズが安定しない |
| Puppeteer | 実体は Node。CTS-EC の帳票処理は .NET 10 なので、ランタイムを増やしたくない |
| FastReport 等の別商用エンジン | ロックインの形が似る。Linux 対応があってもライセンス再購入サイクルは残る |
| 採用: Scriban + Playwright Chromium | HTML/CSS で mm 指定できる。Linux / Windows 同じ Chromium。C# から直接呼べる |
ラベルプリンター(SATO Petit lapin 等)は PDF に寄せません。 203 dpi の感熱紙は CSS ページでは再現しにくく、既存資産は SBPL です。A4 とラベルを一つの描画エンジンに統一しない、が本記事のもう一つの結論です。
✅ 結論:HTML を組んで Chromium で刷る、ラベルは印字言語のまま
到達点は次の 5 つです。
- 帳票データはテナント・拠点付きの DTO。 テンプレート側が文書から拠点を推測しない
- HTML はレビュー済みテンプレートだけ。 利用者が Scriban を投稿して実行する API は持たない
- PDF はヘッドレス Chromium。 JavaScript 無効、外部リソース遮断、フォント読み込み完了後に寸法検査
- バーコードはサーバー側 SVG。 ページ内 JS で描かない
- 印刷送信と紙の排出は別状態。 スプーラー受理を「印刷完了」にしない
共通納品書(新規テンプレート)は 12 明細で改ページする A4 横です。架空データ、2 ページ。

先行テナント向けに移植した受注票兼納品書は、旧 RDLX の座標・条件表示を HTML に移したものです。7 商品で改ページ、加工指示 QR、包装・入金待ちなどの条件欄を維持しています。架空データ、A4 横 3 ページ。

🧱 プロジェクト分割:ブラウザを知らない契約から始める
帳票処理は「PDF を出すライブラリ」ではなく、端末・API・プレビューが同じ DTO を共有する層として切り出しています。
| 層 | 役割 | 依存しないもの |
|---|---|---|
| Contracts | テナント・拠点・発行 ID・明細の DTO | ブラウザ、テンプレート、プリンター |
| Reporting | テンプレート選択、HTML エンコード、Code128、改ページ、PDF、印刷履歴 | 運送会社 API、Windows キュー名 |
| Legacy 移植 | 旧 JSON の比較用変換と、固定 3 レイアウトの組み込み Scriban | 実行時の VB / 任意テンプレート |
| Sato | 感熱ラベル・サーマル帳票の SBPL | Chromium |
| Agent | claim 済みジョブの照合、ローカル履歴、方式別ディスパッチ | サーバーから届く生 SBPL / IP / キュー名 |
| Agent.Http | HTTPS で claim / submitted / review-required | Windows キュー名、プリンター資格情報 |
| Cli | 架空サンプル、ブラウザ導入、PDF、比較用 JSON | 本番認証 |
📌 公開 API の確定契約ではありません。 ローカル検証とエージェント実装のための入力形式です。CLR の型名や任意 JSON を復元せず、許可したスキーマ(共通帳票 / 固定レイアウト)だけを読みます。
System.Text.Jsonは未マップメンバーを拒否します。
拠点設定(TenantReportSettings)は 呼出側が渡します。 文書の店名や住所からテンプレートを推測すると、別テナントの紙面が混ざる事故が起きます。ログイン拠点と DTO のテナント・拠点が一致しない場合は描画せず拒否します。
📝 Scriban:mm で紙面を書き、データは必ずエンコードする
テンプレートはアセンブリの埋め込みリソースです。一般利用者が任意の Scriban を実行する口はありません。レンダラー側では次を固定しています。
StrictVariables = true(未定義変数で失敗)EnableRelaxedMemberAccess = false- ループ上限・再帰上限
- データ文字列は
WebUtility.HtmlEncode - 文字数・数量・単価の上限
紙面は CSS の mm 指定です。A4 横なら @page { size: 297mm 210mm; margin: 0; } と .page { width: 297mm; height: 210mm; } を一致させ、Playwright 側も同じ mm を渡します。
<!doctype html>
<html lang="ja"><head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'none'; style-src 'unsafe-inline'; img-src data:; font-src data:; base-uri 'none'; form-action 'none'">
<style>
@page { size: 297mm 210mm; margin: 0; }
.page { width: 297mm; height: 210mm; overflow: hidden; break-after: page; }
body { color: #000; font: 10pt/1.4 'Noto Sans CJK JP','Yu Gothic','Meiryo',sans-serif; }
</style>
</head><body>
{{ for page in pages }}
<section class="page">
<!-- 宛名・明細・バーコード。値はホスト側で HTML エンコード済み -->
</section>
{{ end }}
</body></html>
CSP は default-src 'none' です。スタイルと data: 画像(SVG バーコード)以外は読みません。帳票 HTML に外部 CDN や Google Fonts を足すと、オフライン印刷とテナント隔離の両方を壊します。
💡 行間 1.4 は Windows の日本語フォント対策です。 Linux の Noto Sans CJK JP では収まっていた 12 明細が、Windows の游ゴシック系では備考付きで用紙を食みました。行間を上げて「Windows でも 12 明細が A4 に収まる」側に寄せています。見た目の密度より、環境差で溢れる事故を先に潰す判断です。
🖨 Playwright:描画エンジンであって、ブラウザアプリではない
PDF 化は Microsoft.Playwright(本実装は 1.62)の Chromium です。インストール済み Google Chrome を使う場合はチャネル chrome を指定できます。ポイントは「ブラウザを開く」ではなく 印刷メディアとして Chromium のレイアウトエンジンだけ借りることです。
await using var context = await browser.NewContextAsync(new()
{
JavaScriptEnabled = false,
ServiceWorkers = ServiceWorkerPolicy.Block,
AcceptDownloads = false,
Locale = "ja-JP",
TimezoneId = "Asia/Tokyo"
});
await context.RouteAsync("**/*", route => route.AbortAsync());
await page.EmulateMediaAsync(new() { Media = Media.Print });
await page.SetContentAsync(html, new() { WaitUntil = WaitUntilState.Load });
| 設定 | 意図 |
|---|---|
JavaScriptEnabled = false | 帳票内 JS でバーコードやトラッキングを動かさない |
| 全ルート Abort | 外部画像・フォント・ビーコンを取らせない |
EmulateMedia(Print) | 画面用 CSS ではなく印刷用でレイアウトする |
PreferCSSPageSize | @page の mm を優先する |
| 余白 0 | テンプレート側の mm が正。Chromium 既定余白で紙面がずれるのを防ぐ |
HTML を SetContent したあと、フォント読み込み完了を待ってから寸法検査します。検査に落ちた PDF は書きません。
await document.fonts.ready;
// [data-check-fit] の枠に対し、内容の scrollWidth / 高さが枠を超えていないか
// shrink 指定なら 6px 下限までフォントを詰める
// それでも収まらなければ field ID だけを返す(顧客文字列はエラーに出さない)
長い住所・商品名は「小さくなるまで描く」ではなく PDF 作成前に拒否します。旧 RDLX の ShrinkToFit 相当は 4.5pt(実装上の下限は px 換算で 6px 付近)まで縮小し、それでも溢れる値はジョブを失敗させます。黙って折り返して宛先が欠けるより、現場で直せる失敗のほうが安全です。
Linux 検証では Noto Sans CJK JP、Windows 検証では游ゴシック / メイリオ系です。Windows の MS PGothic 太字では「納品書」3 文字が幅 13mm に収まらず 2 行に折り返したため、見出し幅を 14mm に広げて 12pt 太字と位置は維持しました。座標を全部動かすのではなく、溢れた枠だけを 1mm 広げるのが移植の基本です。
📊 バーコードはページ内 JS ではなく、サーバー側 SVG
用語集の構想段階では JsBarcode を例に出していましたが、実装は ZXing.Net でビット行列を作り、SVG の <rect> にする方式です。JavaScript を無効にしている以上、クライアント側バーコードは選べません。
| 種類 | 用途 | 実装上の約束 |
|---|---|---|
| Code128 | 社内出荷番号 | 数字のみ。桁数が偶数ならコードセット C、奇数なら値を変えず混合 |
| QR | 加工指示などの日本語自由文 | Shift_JIS(旧帳票の Encoding=932)、誤り訂正 M、余白 4 モジュール |
共通納品書の出荷番号は英数字・ピリオド・ハイフン 1〜24 文字、固定レイアウト側の出荷番号は数字、という差があります。どちらも運送会社の送り状バーコードではありません。 配送ラベル規格は未実装で、ここにヤマトの送り状イメージを足すと誤出荷の原因になります。
旧 RDLX の DistributeAllLines(文字列を枠幅へ均等配置)は、Chromium では効きません。バーコード下の出荷番号は、各桁をバーコードと同じ 38mm 幅へ CSS で均等配置して再現しています。

復号テストでは、生成 SVG を読み戻して元の数字・日本語・改行と一致することを見ています。これは 画像一致や実機スキャナの保証ではありません。 QR の実機読取は残作業です。
📐 印刷品質:座標は維持し、線の持ち方をブラウザ向けに直す
RDLX を HTML に移すと、最初に崩れるのは文字より 罫線です。隣り合う枠がそれぞれ内側に線を描くと、共有境界だけが二重幅になります。
対応は次の 3 点です。
- 線幅を縦横とも 1 CSS px(0.75pt) に統一する
- 枠の境界を中心に描き、同じ位置に重ねる
- 共有線は 片方の欄だけが描く(支払情報の「店名」と「支払方法」など)
Windows Chromium で生成した PDF を 300 dpi で画像化すると、変更前に 6〜7 px あった二重線は 3〜4 px になりました。端数画素の 1px 差は含みます。ネコポス/発払/コレクトの右側欄は、同じ範囲を 300 dpi で比較して画素差 0 まで揃えました。
その他、ブラウザ移植で踏んだ差分です。
| 現象 | 対応 |
|---|---|
| COD の印刷日欄が幅 2mm | 他 2 帳票と同じ位置・28mm に修正(元の欠陥) |
| 単価見出しの右端が明細列からずれる | 後から描く白背景に隠れないよう、見出しを先に描く |
| 本文・挨拶文が薄い | 純黒に統一。Canon 実紙でも「黒くなった」ことを確認 |
Fields!!ShipmentId の誤記 | 移植時に修正。旧式を再現しない |
| 実運用では未使用だったネコポス原紙に包装欄がない | SaaS では後期の発払・コレクトと同じ右側欄を正とする |
⚠️ 移したのは受注票兼納品書の紙面です。 送り状の運送会社バーコード・仕分コード・発送データ発行は別工程です。左側の大きな余白を「新しい配送ラベルの実装済み領域」とは扱いません。
RDLX からの取り込みは、座標・表示条件を読み、許可した式だけを C# の固定処理へ対応付けるスクリプトにしています。未知の式・項目は変換を止めます。実行時に VB も、利用者が入力したテンプレートも評価しません。
🖥 印刷エージェント:取得しただけで印刷完了にしない
旧 WPF は 10 分間隔で発払・コレクトを取りに行き、その Windows 端末のキュー名へ ActiveReports を送っていました。キュー名は端末ローカルの値で、スマホの SATO IP とは混ぜられません。
新しいエージェントが引き継ぐのは「Windows 常駐・自動取得・ドライバー送信」という 役割だけです。ActiveReports は使わず、PDF をスプーラーへ渡します。ラベル用 SBPL は同じジョブ契約の別ディスパッチャーへ渡し、PDF をラベル用紙へ送るフォールバックは禁止です。
| 状態 | 意味 | 意味しないこと |
|---|---|---|
| claim | 短いリースで 1 件を確保 | 印刷成功 |
| submitted | スプーラーまたは SATO 送信口が受理 | 用紙排出・配送完了 |
| review-required | 送信前失敗、結果不明、設定版不一致 | 自動再送してよい |
| 再発行 | 権限付き管理画面が新しいジョブ ID を作る | ローカル履歴を消して同じ ID を再送 |
HTTP 本文に Windows キュー名、プリンター IP、TCP ポート、資格情報、任意 SBPL を入れません。 サーバーが返すのは不透明な印刷先 ID です。実キュー名への解決は、その Windows PC のローカル設定だけが行います。接続は HTTPS 必須です。
旧自動印刷には、取得引数 code ではなくプロセス全体の可変値でテンプレートを選ぶ経路があり、手動操作のあとで発払データにコレクト紙面が載る余地がありました。新方式はサーバーが各ジョブのスキーマとレイアウトを指定し、共有の可変コードを使いません。
ローカルの印刷履歴は、再起動後の重複送信を防ぎます。複数 PC の排他にはなりません。 排他の正本は claim リースとサーバー状態です。期限切れの claim は再送待ちへ戻さず、要確認へ移します。
🏷 サーマル印刷は「PDF の縮小」ではない
SATO Petit lapin(検証機種は PW208 W-LAN、203 dpi)向けは、共通 DTO から SBPL を組み立てます。Chromium は使いません。
| 帳票 | 扱い |
|---|---|
| 感熱ラベル | 各業務の旧座標を維持。チェックデジットを確認。未対応文字の黙った ? 置換はしない |
| 追跡番号付きラベル | 差出人を明示データで渡す。追跡番号は発行済み値を受け取るだけで、採番しない |
| サーマル納品書 | 新レイアウト候補。旧実装が単一商品前提で明細を上書きしていた制限は継承しない |
方式ルーターは、登録したディスパッチャーにだけジョブを渡します。PDF 用キューへ SBPL を流す、ラベル機へ PDF を流す、未登録方式へ落とす、はいずれもオペレーターが見るべき失敗です。
📌 実機への送信と用紙原点の受入は未完了です。 SBPL 生成・非同期 Status3・ACK / ページ完了のテストダブルは通していますが、PW208 への実送信は別工程です。旧コードとのバイト比較成功を、配送に使える判定とはしません。
🧪 検証:何を見て、何を見ていないか
2026-09-10 時点の Linux 検証では、帳票テスト 78 件が成功しています(ブラウザーを使う PDF 生成・紙面超過を含む)。Windows では Chromium / Chrome の両方で、共通納品書 2 ページ、固定 3 帳票は各 3 ページの A4 横を確認しました。Canon LBP621C へ Linux CUPS から PDF を送り、挨拶文の濃度を実紙で確認しています。
| 見ていること | 見ていないこと |
|---|---|
| テナント/拠点不一致の拒否 | 現行 ActiveReports 紙との重ね合わせ |
| HTML 混入のエンコード | 実紙のミシン目・プリンター倍率 |
| 改ページ(12 明細 / 7 商品) | 運送会社バーコードの規格適合 |
| Code128 / QR の復号 | 実機スキャナでの読取 |
| 用紙超過の描画前拒否 | Windows ドライバーからの本番自動印刷 |
| 再起動後の重複送信抑止 | 複数端末をまたぐ排他の実運用 |
| 方式誤配線の拒否 | 税・送料・値引き・適格請求書 |
単価のない行がある場合、全明細金額は出しません。送料・値引き・税率別計算は未移植です。「PDF が綺麗に出た」と「請求書として正しい」は分けて扱います。
⚠️ 残作業と、切替前に必要な受入
エンジン置換はここまで来ています。現行紙への切替条件にはまだ足りません。
- 現行 ActiveReports 出力との重ね合わせ(長い住所、複数口、セット品、代引、日本語 QR)
- 使用プリンターの余白・倍率、ミシン目への位置合わせ
- 運送会社の送り状発行 API・配送ラベル
- サーバー側の印刷履歴正本、許可付き再印刷、複数端末排他の通し受入
- QR / Code128 の実機読取
- Windows ドライバー実送信と PW208 の原点
手元の新規サンプル PDF の成功だけで切り替えない、が受入の一文です。デュアルブートで Windows を残しているのは、この受入が終わるまでの安全網でもあります。
✅ 第 8 回まとめ
- ActiveReports を切った直接の理由は .NET 8 → 9 → 10 のたびに発生する高額バージョンアップ、1 ライセンス = 1 PC、共有ソースで RDLX だけが宙に浮くことの 3 点。Windows + Visual Studio 前提と重なり、Linux 移行の最大ブロッカーになる
- 代替は「別の帳票ベンダー」ではなく Scriban で HTML を組み、Playwright Chromium で PDF にすること。ラベルは PDF にせず SBPL のまま出す
- テンプレートはレビュー済みの組み込みに限定し、データは HTML エンコード、Chromium は JS 無効・外部通信遮断
- 用紙に収まらない文字は縮小の末に 描画前拒否。黙って欠けるより失敗させる
- バーコードは ZXing のサーバー側 SVG。ページ内 JS に依存しない
- 印刷エージェントは claim / submitted / 要確認を分け、スプーラー受理を紙の排出にしない。方式のフォールバックは禁止
- 旧 RDLX の受注票兼納品書は座標・条件表示を移植済み。送り状・実紙合わせ・税計算は残作業
これでシリーズの Phase 1(帳票エンジン)は、Linux 上で PDF を再現できるところまで来ました。Windows を残している理由は「まだ ActiveReports が必要だから」から、「実紙と配送ラベルの受入が残っているから」に変わっています。
次回「Mac / Windows をリモートビルド機にする — Ubuntu から SSH で出て MAUI・WPF を確認する」では、Ubuntu を正本にしたまま Mac と Windows 11 へ SSH で出て、iOS シミュレーターと WPF のビルドを回す接続手順を書きます。第 10 回(公開予定)「コスト削減効果と 1 年運用レビュー」では、ライセンス削減の実績と、本シリーズ全体の運用上のハマりどころをまとめます。帳票の実紙切替コストも、そこで初めて数字になります。
📚 シリーズ記事
| 回 | タイトル | 主題 |
|---|---|---|
| 1 | 総論:脱Microsoft・OSS移行 | 動機・コスト・全体地図 |
| 2 | Windows 11 + Ubuntu デュアルブート構築 | M.2 物理分離・KDE Plasma・GRUB |
| 3 | Ubuntu PC セットアップ | NVIDIA・サスペンド・Howdy・プリンター |
| 4 | Ubuntu 開発環境セットアップ | Docker Engine ネイティブ・DevContainer・Claude Code |
| 5 | Ubuntu データ共有セットアップ | rclone Drive + systemd・QNAP NFS/SMB・Obsidian・AppArmor |
| 6 | Microsoft 365 → Google Workspace 全面移行 | メール・SSO・MFA・MX 切替・OneDrive → Drive |
| 7 | Ubuntu リモート開発セットアップ | Tailscale + SSH + VS Code Remote / DevContainer・Wayland ホスト |
| 8 | ActiveReports → Playwright + Scriban 移行(本記事) | 帳票エンジン置換・バーコード・印刷品質 PDF |
| 9 | Mac / Windows をリモートビルド機にする | Ubuntu から SSH で出る・Windows OpenSSH Server・ローカル標準ユーザー・送信元限定の許可ルール |
| 10 | コスト削減効果と 1 年運用レビュー(公開予定) | 実績ベースのコスト・運用上のハマりどころ |
🔗 関連リソース
CTS-KB 内の関連記事
- レガシー置換とは — 帳票エンジン置換を、旧実装を原典にする系列へ位置づける
- 脱Microsoft 全体戦略・総論 — Phase 1 に帳票を置いた理由とコスト試算
- Ubuntu 開発環境セットアップ — .NET / Docker を Linux ネイティブで回す前提
- Ubuntu リモート開発セットアップ — Windows 側から Linux の帳票 CLI を叩く経路
関連用語
- ActiveReports — 置換対象の商用帳票ライブラリ
- Scriban — 帳票 HTML を生成する .NET テンプレートエンジン
- SBPL — ラベルプリンターの印字言語。A4 の PDF とは別経路
- Playwright — ヘッドレス Chromium で印刷品質 PDF を出す
- .NET MAUI — 検品端末。ラベル印刷は PDF とは別経路
- Ubuntu / Linux — 帳票 CLI とテストを回している実行環境
外部リソース
- Playwright for .NET —
Page.PdfAsync— CSS ページサイズと余白 - Playwright — ブラウザ導入 — Chromium のインストール
- Scriban — テンプレートエンジン
- ZXing.Net — Code128 / QR のビット行列生成