Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
なぜブラウザで帳票を生成したいのか どのようにブラウザで帳票を生成するのか
Search
yagisan-reports
November 17, 2025
Technology
0
110
なぜブラウザで帳票を生成したいのか どのようにブラウザで帳票を生成するのか
JSConf JP 2025 デンキヤギセッションでのスライドです。
yagisan-reports
November 17, 2025
Tweet
Share
More Decks by yagisan-reports
See All by yagisan-reports
AIネイティブ時代の帳票エンジン yagisan-reports
yagisanreports
0
96
Other Decks in Technology
See All in Technology
やり方は一つだけじゃない、正解だけを目指さず寄り道やその先まで自分流に楽しむ趣味プログラミングの探求 2025-11-15 YAPC::Fukuoka
sugyan
2
810
生成AI時代に若手エンジニアが最初に覚えるべき内容と、その学習法
starfish719
2
410
⽣成 AI で進化する AWS オブザーバビリティ
o11yfes2023
0
130
プログラミング言語を書く前に日本語を書く── AI 時代に求められる「言葉で考える」力/登壇資料(井田 献一朗)
hacobu
PRO
0
170
Proxmox × HCP Terraformで始めるお家プライベートクラウド
lamaglama39
1
210
AIと自動化がもたらす業務効率化の実例: 反社チェック等の調査・業務プロセス自動化
enpipi
0
640
re:Invent2025 事前勉強会 歴史と愉しみ方10分LT編
toshi_atsumi
0
140
Devoxx Morocco 2025 - Like Spring but faster: The new Java Jedi
edeandrea
PRO
0
100
自己的售票系統自己做!
eddie
0
460
アジャイル社内普及ご近所さんマップを作ろう / Let's create an agile neighborhood map
psj59129
1
130
QAを"自動化する"ことの本質
kshino
1
130
Service Monitoring Platformについて
lycorptech_jp
PRO
0
230
Featured
See All Featured
It's Worth the Effort
3n
187
28k
Thoughts on Productivity
jonyablonski
73
4.9k
The Invisible Side of Design
smashingmag
302
51k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
33
1.8k
Documentation Writing (for coders)
carmenintech
76
5.1k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Music & Morning Musume
bryan
46
6.9k
How to Ace a Technical Interview
jacobian
280
24k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
37
2.6k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
Into the Great Unknown - MozCon
thekraken
40
2.2k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
Transcript
なぜブラウザで 帳票を生成したいのか terurou 2025-11-16 / JSConf JP どのようにブラウザで 帳票を生成するのか
デンキヤギ株式会社 • 名古屋の零細ソフトウェア開発会社 • GitHubに初めて就業規則を公開した会社らしい 1
2
terurouと帳票システム • [2005] セミナー受講システム : 修了証印刷 • PHP4.3の時代にFPDFをフォークして、縦書きサポート+高速化 • [2011]
物流 倉庫管理システム • wkhtmltopdf (CSS組版) ※今ならheadless Chrome • [2014] 販売管理システム • kintone +請求書SaaS(Misoca) • [2016] 金融系システム • JasperReports など 3
4 ざっくり、このセッションは、 なんでyagisan-reports作ったの??? という内容になります。
予備知識と前提 5
帳票とは? 実は明確は定義はないが…、 請求書が一番イメージしやすい • ビジネスにおける指示や記録を残す定型文書 • 紙かPDFで、書籍や資料とは異なるもの • 宛名ラベルや業務日報なども帳票と扱うことは多い 6
帳票が登場するビジネス領域の一例 • 経理 • 請求書、稟議書、決算、… • 物流 • 配送指示書、宛名ラベル、… •
製造業(FA) • 生産指示書、検査報告書、… • 監督省庁への届出・申告 • 医療、介護、建築、土木、 不動産、金融、… • 公共・行政 • 教育 • その他一般業務 など 7
このセッションでの前提(カバー範囲) • Webシステムに帳票機能を組み込む話 • PDF帳票のみに限定して、紙・印刷は含めない • 「Webシステムで帳票出力」と「印刷主体のシステム」では 求められる要素が全く異なる • 例:
物流倉庫のオートメーションなど 8
なぜブラウザで帳票を 生成したいのか? 9
10 楽したいし、 コストは安い方がいい
11 順に説明していきます
WebシステムでPDFを出力する方法 従来的な方法では、以下の2択 • サーバーサイドでPDF生成 • 商用製品やOSSなど、サーバーサイドでPDF生成 • ブラウザのPDF印刷 (Microsoft Print
to PDFなど) • Amazonを筆頭にECサイトでよく見る • HTML/CSSでレイアウト 12
帳票サーバーの負荷対策で泥沼化しがち • 設計難易度が上がって、対応できる人が減る • 水平分散にするか、ジョブキューにするか、バッチにするか… • 技術検証、サイジング、テストなども必要 • 帳票出力が非同期になるので、UIにどう組み込む? •
出力依頼を出しておいて、完了したらメールで通知? 13
サーバーを増やせば、インフラコストもかかる • 単純にサーバー台数の分だけコストがかかる • 商用帳票製品では、サーバー台数分のライセンスが必要に • FaaSを使ったときにライセンス数ってどう数えるんだっけ… • 監視環境やリカバリーも必要 •
一度構築したら数年稼働させるとかザラにある 14
15 サーバーサイドでPDF生成することは 人件費もランニングコストがかかるし、 設計難易度も決して低くはない
ブラウザのPDF印刷 低コストで有用だが、使えるケースが限定的 • 実行環境に依存して、描画結果が変わってしまう • 全ての環境で同じように描画するには、膨大なテストが必要 • 素朴なレイアウトに留めないと大変なことに • ECの場合、適格請求書の必要事項が記載されていれば、
表示が崩れても経費処理は可能 • ユーザー要件 だが、ダサいのはダサい… 16
17 ブラウザのPDF印刷は使えるシーンが限定的だが、 帳票用のサーバーが要らないことがすごく良い
18 JavaScriptで動く帳票エンジンがあれば PDF印刷と同じメリットが!
19 というノリで作ってるのが
ちなみにブラウザでのPDF生成に失敗したら? • エラーが出たときだけ、サーバーでPDFを作ればよい • 大半はブラウザで処理できるので、サーバーは最小限に 20 PDF生成 PDF生成 ブラウザ バックエンド
帳票生成 リクエスト エラー時のみ フォールバック
どのようにJavaScriptで 帳票を生成するのか 21
ブラウザ上で動作するPDFライブラリ • JavaScript/TypeScript実装のOSS • pdfme ※この中ではかなり高機能 • react-pdf • pdf-lib
• PDFKit など • C/C++やRustなどのWASMで使えるライブラリ • 有償のプロプラエタリ製品もいくつかある 22 数年前と比べると、 選択肢が増えてきた
yagisan-reportsでのPDF生成 • pdf-libをベースに実装 • pdfmeの他、他社の商用帳票製品でも使われてるらしい • ただし、将来的には自前実装に切り替えたい • pdf-libとは •
OSS、pure TypeScript • PDFの生成だけでなく、編集(追記、ページ削除など)も可能 23
日本語帳票エンジンに求められる要件 • 日本語サポート • 日本語フォント • 異体字(IVS) • 縦書きテキスト •
高レベルなレイアウトシステム • 動的明細(動的テーブル) • 自動改ページ 24
JavaScript製ライブラリの日本語サポート状況 • 日本語フォントには概ね対応しているが… • 異体字、縦書き対応がNG • 対応しているOSSはおそらくない • 人名・社名などで異体字は結構使われている •
特に社名は正しく描画しないと「失礼にあたる」的な話も… 25
異体字に対応するには? • fontkitが異体字(IVS)を実装していない • 大半のJS製PDFライブラリがフォント操作に使っている • https://github.com/foliojs/fontkit • これをフォークしたら対応できるのでは? •
やった → https://github.com/DenkiYagi/fontkit • yagisan-reports用にかなりカスタマイズしてるので、 オリジナル版とAPI互換がありません… 26
縦書きに対応するには • これもpdf-libが実装してない • フォークして対応するしかない… • やった • https://github.com/DenkiYagi/pdf-lib •
これもだいぶカスタマイズしてるので、オリジナルと互換なし… 27
高レベルなレイアウトシステム 動的明細と自動改ページがないと、請求書でさえ厳しいが 対応しているライブラリはほぼ無い 28
pdf-libでの帳票レイアウト • pdf-libでは低レベルAPIしか提供されていない • addPage(), drawText(), drawLine() など • 「この座標に」「文字を書く」「線を引く」みたいな感じ
• 低レベルAPIだけでは、請求書を作るだけでも大変 • 単純に実装・テストの工数がかかる • 誰でもできるわけではないので、仕事が分散できない • 例えば1年後に微修正がきたとしても、自分でも覚えてない… 29
動的明細を自前で実装する シンプルな実装であれば、そこまで難しくはない • 行と列の数から、罫線やテキスト描画位置を計算する • 技術的な難しさよりも、ひたすら計算が面倒なだけ 30
動的明細を高機能にすると面倒に • 明細の文字数が多い場合、当該行だけ複数行表示にする or 縮小して1行に収まるようにする • 文字列+フォント設定から必要な描画サイズを取得して計算 31
改ページを自前で実装する 基本概念は難しくない • コンテンツがページに収まらなかったら改ページ • 「要素の途中で改ページが必要になった場合」を ひたすら対応していけば実装できる • ケースの洗い出しとテストが地獄 32
改ページの例: 簡単なパターン 複数行テキストの途中で改ページが必要になった場合、 テキストが見切れない位置に調整する 33 あいうえこ かきくけこ さしすせそ たちつてと ページ下端
あいうえこ かきくけこ さしすせそ たちつてと 1ページ目 2ページ目
改ページの例: ややこしいパターン グリッドの途中で改ページ 34 あいうえお 12345 かきくけこ さしすせそ たちつてと なにぬねの
67890 ページ下端 改ページしたい位置は ケースバイケース…
その他に改ページ関連で出てくること • 動的明細を改ページしたら、ヘッダーを全ページに付ける • でも小計は最後のページにだけしか表示したくない • 強制的に任意位置で改ページしたい • レイアウトを変えたい(例えば、表紙+本体) •
どうしても「ちょうどいい改ページ位置」が決められない パターンはどのように振舞うべきか • ページサイズに収まらないようなサイズの画像の挿入など 35
改ページ制御は地獄 • 人間が気軽に手を出してよい領域ではない • 商用帳票製品でも実装してないものは多数ある • 安い製品はだいたい逃げている 36
37 基礎部分はこんな感じだが、 これだけは足りていない
帳票テンプレート(レイアウト記述言語) • 人間が扱いやすい帳票テンプレートが必要不可欠 • 低レベルAPIをラップするレイアウト記述言語が必要 • 商用帳票製品は専用GUIデザイナーを用意しがち • GUIはあれば、もちろん便利だが… •
普段からHTMLやJSXを書いているWebの人間の感覚では、 GUIしかないのは面倒に感じる 38
yagisan-reportsでのレイアウト記述言語 • XMLベースの帳票レイアウト記述言語を自前実装 • HTMLやJSXに慣れてるWebの人間には親しみやすい • 最初はJSONで設計していたが、思ってた以上に読みづらい • XAMLやAndroidのLayout XMLに似た構文
• コンポーネントのネストにも対応 39
蛇足: あとから生成AIが来た • XMLでレイアウトを記述する仕様にしたおかげで、 生成AI(Coding Agent)対応で非常に有利になった • デンキヤギブースでAI生成デモを展示中 • 内部的にはMCP
Serverを作ってるだけ • ただし、MCP Serverには工夫が必要 40
パフォーマンスチューニング 数ページ程度なら性能問題はまず出ないが、 数百ページ単位になると話が別 • JITが効くコード • ループの最適化 • メモリー管理、データ配置の最適化 •
GCの抑制 など地味な積み重ね 41
品質保証: 継続的テスト • ユニットテスト、機能テストは当然やる • ビジュアルリグレッションテスト • 生成したPDFを画像化して、旧バージョンとの比較 • パフォーマンスリグレッションテスト
• Valgrind、Cachegrindを使ってブレが出ないように計測 42 リグレッションテストは開発してると 度々ひっかかります…
その他、日本語帳票で言われがちなこと • Excelで作られた「罫線とセル結合のおばけ」 • このレイアウトで、動的に行が増える箇所がある • 厚生労働省管轄(医療・介護・社会保険など)の帳票でありがち • 1セルに1文字ずつ入れる •
選択肢は 〇 で囲む • 印影をちょっと文字に重ねたい 43
「罫線とセル結合のおばけ」の例 44
「罫線とセル結合のおばけ」の例 45
まとめ 46
47 帳票エンジンは買った方がいいよ!
帳票エンジンは買った方が良い理由 • OSSなどで安く上げようとしても、簡単にはいかない • サーバーサイド生成では、負荷分散とか監視とか大変 • 低レベルなライブラリから作るのと工数が爆発する • 長期で保守する必要があるのに、属人性が生まれがち •
そもそもみんな帳票に思い入れはないよね 48
どうしてもOSSだけでやりたい • pdfmeは試す価値はあり • ただし、ゴリゴリの日本語帳票に向き合うには機能不足 • ダメだったら諦めて商用製品を買うべき • pdfmeもお金を出せば機能追加に応じてくれるらしい 49