SlideShare uma empresa Scribd logo
1 de 25
Baixar para ler offline
Webブラウザ上で動作する
帳票エンジンを作る話
terurou
2022-01-22
terurou
• デンキヤギ代表取締役
• NGKの実行委員を12年ぐらいやってました
• 今回も関与はしてるけど、大して仕事してないです
1
[ad] yagisan-reports
2
帳票とは?
• 請求書、申請書、明細書とか
• PDF出力したい
3
帳票システムを作るのはだるい
• 帳票エンジンの選定
• 超高価エンプラ製品 ~ OSS
• 高機能な専用デザイナー ~ 低レベルな描画APIでゴリゴリ
• 普通に作ると帳票サーバーが必要
• FaaSでやってもいいけど、処理時間やメモリ量とかが…
• そもそも商用製品は帳票サーバーを立てる前提
4
帳票エンジンのつらいところ
• 商用/OSS共に、全体的に古臭い
• 古臭い帳票デザイナーを使わないといけないのがしんどい
• headless Chromeを最近よく見るけど…
• HTML/CSSで帳票デザインを作れる人、どれだけいる?
• FaaSで動かすにはオーバーヘッドが大きい
5
帳票サーバーがしんどい
• 単純にサーバーの構築/運用はめんどくさい…
• 死活監視、ストレージ運用、エラー時にどうするか…
• 帳票サーバーの負荷対策 → ジョブキュー化で泥沼
• 設計難易度が上がって、対応できる人が減る
• 帳票出力が非同期になるので、UIにどう組み込む?
• 出力依頼を出しておいて、完了したらメールで通知?
6
7
サーバーサイドで帳票出力すると
めんどくさいことが多すぎるから、
ブラウザ側で生成させたらよくね?
ブラウザ上で動くPDFライブラリ
• JS実装のOSSがいくつかある
• jsPDF
• PDFKit.js
• pdf-lib.js など
• C++の実装をWASM化
• この中では、 pdf-lib.js が比較的おすすめ
• yagisan-reportsでも使用(2022年1月時点)
8
pdf-lib.jsが比較的オススメだが、問題もある
• UIスレッドの占有
• 日本語の取り扱い
• 日本語フォント
• 「Macの濁点」「中華フォント」「CP932」
• 低レベルな描画APIしかない
• レイアウト記述言語
• 改ページ処理
9
魔界
比較的マシ
UIスレッドの占有
• JSライブラリなので、当然UIスレッドで動く
• 大量ページ出力とかやると、UIが止まる
• Web Workerを使って別スレッドで実行しましょう
• これはそんなに難しくない
10
日本語フォント
• pdf-lib内部ではfontkitにフォント処理を委譲
• fontkitの日本語フォント実装が不完全
• どうやら、OTFのcmap処理に問題があるっぽい
• 将来的には直したいが、当面は後回しにしている
• TTFであれば動作する
• ただしIVSは未実装→異体字は扱えない
11
OTFの日本語フォントが使えないと困る
• 使いたいフォントは全部OTF
• 自由に使える「JIS第4水準漢字」対応フォントは限られている
• Notoフォントとか、源ノ角ゴシックとか
• OTF→TTFに変換すればいける
• [注意] 前述のフォントはSIL Open Font License v1.1
12
SIL Open Font License v1.1 日本語訳抜粋
3)フォントソフトウェアの改変バージョンで、予約さ
れたフォント名を使用することは、その著作権所有者が
書面による明示的な許可を与えていない限りできない。
この制限はユーザーに示される主要なフォント名だけに
適用される。
→ TTFに変換したフォントは別名にする必要がある
13
「Macの濁点」問題
• Apple社製OSで「だ」を入力すると、文字コード上は
「た」+「濁点」の2文字で構成されてしまう
• 濁点、半濁点は全てこうなる
• OS混在の開発現場で、たびたび発生する問題
• 正規化しないとPDF出力時に不都合がある
14
「中華フォント」問題
• Notoフォントなどを使っていても発生する
• 「中華フォント」の字体にも
Code Pointが割り当て
• フォントではなく入力文字列が
誤っている→正規化が必要
15
引用: https://heistak.github.io/your-code-displays-japanese-wrong/
Unicode文字列の正規化
• String#normalize('NFC')が使えない
• Unicodeの正規化を行ってくれる便利メソッド
• JIS第3-4水準漢字の一部まで過剰に正規化してしまう
• 神 : U+FA19 (JIS第3水準漢字)
• 神 : U+795E
16
「CP932」問題
• CP932 = MSが定めた日本語文字コードセット
• JISに収録されていない漢字が存在する
• 代表例は 髙 (はしごだか)
• 「JISに収録されている漢字」でバリデーションすると、
「はしごだか」を弾いてしまう
17
都合の良い文字セットで、都合の良い正規化
• Unicode正規化アルゴリズムをベースに、
正規化ルールをごっそり入れ替えて対応
• JIS X 0213:2004 + CP932を含む文字セット
• 「Macの濁点」「中華フォント」は正規化
• ユニコードコンソーシアムが使えるネタを公開している
• https://unicode.org/Public/UNIDATA/UnicodeData.txt
• https://www.unicode.org/Public/security/latest/confusablesSummary.txt
18
低レベルな描画APIしかない
• PDF仕様には低レベルな描画命令しかない
• 「この座標に」「文字を書く」「線を引く」みたいな感じ
• 表を描画するにも、自分で全部線を引く必要がある
• これを帳票を作るたびに毎回書いていたら生産性が低すぎる
19
レイアウト記述言語
• XMLベースの帳票レイアウト記述言語を自前実装
• XMLにしたのは、人間が読み書きしやすいから
• 最初はJSONで書いてたけど、人類には早すぎた
• XAMLやAndroidのLayout XMLに似た仕様
• 表組みのネストにも対応した
20
レイアウト記述言語の例
21
改ページ処理
• 「明細が1ページに収まらない請求書」のような帳票は
改ページ処理に対応できないと出力できない
• 改ページ処理から逃げたエンジンは結構見かける
• 既存PDFをテンプレートにして、文字や図形を置くだけ
• これはこれで便利なので、yagisan-reportsでも対応している
• まともに向き合うと地獄
22
改ページ処理の難しさ
• Webサイトを印刷した際に表示が崩れますよね?
あれを全部うまくやれるようにするイメージです
• もちろん仕様をかなり絞ってるが、それでもかなり面倒
• コーナーケースが大量にあり、テストコードの量がやばい
23
まとめ
• ブラウザ上で動く日本語帳票エンジンを作るのは大変
• 狂気の沙汰、やる前はここまで大変だと思ってなかった
• yagisan-reportsを使うと、今日話してきた問題が
全部対処済みらしいよ!
• 2022年春のパブリックリリースを目標にしてるらしいよ!
• クローズドのアーリーリリース版でよければ、すぐ使えます
• こういうのを開発したい人を募集中(アルバイト可)
24

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

テストコードの DRY と DAMP
テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMP
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)
 
デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣
 
シリコンバレーの「何が」凄いのか
シリコンバレーの「何が」凄いのかシリコンバレーの「何が」凄いのか
シリコンバレーの「何が」凄いのか
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
ふつうのRailsアプリケーション開発
ふつうのRailsアプリケーション開発ふつうのRailsアプリケーション開発
ふつうのRailsアプリケーション開発
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っている
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
地理分散DBについて
地理分散DBについて地理分散DBについて
地理分散DBについて
 
Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略
 
ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
Java8でRDBMS作ったよ
Java8でRDBMS作ったよJava8でRDBMS作ったよ
Java8でRDBMS作ったよ
 
開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門
 
心理的安全性の構造 デブサミ2019夏 structure of psychological safety
心理的安全性の構造 デブサミ2019夏 structure of psychological safety心理的安全性の構造 デブサミ2019夏 structure of psychological safety
心理的安全性の構造 デブサミ2019夏 structure of psychological safety
 

Semelhante a Webブラウザ上で動作する帳票エンジンを作る話

第11回SIA例会プレゼン資料
第11回SIA例会プレゼン資料第11回SIA例会プレゼン資料
第11回SIA例会プレゼン資料
Tae Yoshida
 
はじめよう FinOps クラウドコスト最適化への第一歩とは 日本IBMカスタマーサクセスチーム
はじめよう FinOps クラウドコスト最適化への第一歩とは 日本IBMカスタマーサクセスチームはじめよう FinOps クラウドコスト最適化への第一歩とは 日本IBMカスタマーサクセスチーム
はじめよう FinOps クラウドコスト最適化への第一歩とは 日本IBMカスタマーサクセスチーム
勇 黒沢
 

Semelhante a Webブラウザ上で動作する帳票エンジンを作る話 (20)

Web入稿自動組版の過去・現在・未来
Web入稿自動組版の過去・現在・未来Web入稿自動組版の過去・現在・未来
Web入稿自動組版の過去・現在・未来
 
第11回SIA例会プレゼン資料
第11回SIA例会プレゼン資料第11回SIA例会プレゼン資料
第11回SIA例会プレゼン資料
 
RPAをきっかけに業務効率の輪を広げてみませんか.pdf
RPAをきっかけに業務効率の輪を広げてみませんか.pdfRPAをきっかけに業務効率の輪を広げてみませんか.pdf
RPAをきっかけに業務効率の輪を広げてみませんか.pdf
 
グリー株式会社『私たちが GCP を使い始めた本当の理由』第 9 回 Google Cloud INSIDE Game & Apps
グリー株式会社『私たちが GCP を使い始めた本当の理由』第 9 回 Google Cloud INSIDE Game & Appsグリー株式会社『私たちが GCP を使い始めた本当の理由』第 9 回 Google Cloud INSIDE Game & Apps
グリー株式会社『私たちが GCP を使い始めた本当の理由』第 9 回 Google Cloud INSIDE Game & Apps
 
私たちがGCPを使い始めた本当の理由
私たちがGCPを使い始めた本当の理由私たちがGCPを使い始めた本当の理由
私たちがGCPを使い始めた本当の理由
 
connpass特徴と開発の流れ
connpass特徴と開発の流れconnpass特徴と開発の流れ
connpass特徴と開発の流れ
 
はじめよう FinOps クラウドコスト最適化への第一歩とは 日本IBMカスタマーサクセスチーム
はじめよう FinOps クラウドコスト最適化への第一歩とは 日本IBMカスタマーサクセスチームはじめよう FinOps クラウドコスト最適化への第一歩とは 日本IBMカスタマーサクセスチーム
はじめよう FinOps クラウドコスト最適化への第一歩とは 日本IBMカスタマーサクセスチーム
 
Itで中小企業の生産性向上3
Itで中小企業の生産性向上3Itで中小企業の生産性向上3
Itで中小企業の生産性向上3
 
WooCommerce & AWS
WooCommerce & AWSWooCommerce & AWS
WooCommerce & AWS
 
インフラ費用を節約したいあなたに!サーバー事業者がお送りする節約術5選
インフラ費用を節約したいあなたに!サーバー事業者がお送りする節約術5選インフラ費用を節約したいあなたに!サーバー事業者がお送りする節約術5選
インフラ費用を節約したいあなたに!サーバー事業者がお送りする節約術5選
 
hb-agent 秘伝のタレからソースコードへ (ITインフラ 業務自動化現状確認会 ) #infra_auto
hb-agent 秘伝のタレからソースコードへ (ITインフラ 業務自動化現状確認会 ) #infra_autohb-agent 秘伝のタレからソースコードへ (ITインフラ 業務自動化現状確認会 ) #infra_auto
hb-agent 秘伝のタレからソースコードへ (ITインフラ 業務自動化現状確認会 ) #infra_auto
 
DevOps Overview
DevOps OverviewDevOps Overview
DevOps Overview
 
「まちの本屋の総合情報サイト」の紹介 カスタマイズ編
「まちの本屋の総合情報サイト」の紹介 カスタマイズ編「まちの本屋の総合情報サイト」の紹介 カスタマイズ編
「まちの本屋の総合情報サイト」の紹介 カスタマイズ編
 
[db tech showcase Tokyo 2018] #dbts2018 #E37 『Attunity Replicateが変えた Oracle D...
[db tech showcase Tokyo 2018] #dbts2018 #E37 『Attunity Replicateが変えた Oracle D...[db tech showcase Tokyo 2018] #dbts2018 #E37 『Attunity Replicateが変えた Oracle D...
[db tech showcase Tokyo 2018] #dbts2018 #E37 『Attunity Replicateが変えた Oracle D...
 
Redmine + Lychee導入のアンチパターン
Redmine + Lychee導入のアンチパターンRedmine + Lychee導入のアンチパターン
Redmine + Lychee導入のアンチパターン
 
.NET Lab2022年2月
.NET Lab2022年2月.NET Lab2022年2月
.NET Lab2022年2月
 
仮想化専門コンサルタントが教える「成功する仮想化導入のポイント」
仮想化専門コンサルタントが教える「成功する仮想化導入のポイント」仮想化専門コンサルタントが教える「成功する仮想化導入のポイント」
仮想化専門コンサルタントが教える「成功する仮想化導入のポイント」
 
20170705 apiをつくろう
20170705 apiをつくろう20170705 apiをつくろう
20170705 apiをつくろう
 
AWS Black Belt Online Seminar 2018 Amazon WorkSpaces
AWS Black Belt Online Seminar 2018 Amazon WorkSpacesAWS Black Belt Online Seminar 2018 Amazon WorkSpaces
AWS Black Belt Online Seminar 2018 Amazon WorkSpaces
 
20180207 AWS blackbelt online seminar Amazon Workspaces
20180207 AWS blackbelt online seminar Amazon Workspaces20180207 AWS blackbelt online seminar Amazon Workspaces
20180207 AWS blackbelt online seminar Amazon Workspaces
 

Mais de terurou

FIRST STEP to Haxe/JavaScript
FIRST STEP to Haxe/JavaScriptFIRST STEP to Haxe/JavaScript
FIRST STEP to Haxe/JavaScript
terurou
 
大規模なギョームシステムにHaxeを採用してみた話
大規模なギョームシステムにHaxeを採用してみた話大規模なギョームシステムにHaxeを採用してみた話
大規模なギョームシステムにHaxeを採用してみた話
terurou
 
Metro Style AppsでMSIL ver.2012/06/09
Metro Style AppsでMSILver.2012/06/09Metro Style AppsでMSILver.2012/06/09
Metro Style AppsでMSIL ver.2012/06/09
terurou
 
Scala×silverlight
Scala×silverlightScala×silverlight
Scala×silverlight
terurou
 
DLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミングDLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミング
terurou
 

Mais de terurou (20)

自社サービスでDurable Functionsを採用した話
自社サービスでDurable Functionsを採用した話自社サービスでDurable Functionsを採用した話
自社サービスでDurable Functionsを採用した話
 
Computation Expressions for Haxe
Computation Expressions for HaxeComputation Expressions for Haxe
Computation Expressions for Haxe
 
デンキヤギの採用の考え方
デンキヤギの採用の考え方デンキヤギの採用の考え方
デンキヤギの採用の考え方
 
Vue.jsをhaxeで
Vue.jsをhaxeでVue.jsをhaxeで
Vue.jsをhaxeで
 
MQTTとAMQPと.NET
MQTTとAMQPと.NETMQTTとAMQPと.NET
MQTTとAMQPと.NET
 
altJSの選び方
altJSの選び方altJSの選び方
altJSの選び方
 
DataGridを自前実装する話
DataGridを自前実装する話DataGridを自前実装する話
DataGridを自前実装する話
 
オブジェクト指向の皮をかぶった関数型プログラミング言語 Haxe
オブジェクト指向の皮をかぶった関数型プログラミング言語 Haxeオブジェクト指向の皮をかぶった関数型プログラミング言語 Haxe
オブジェクト指向の皮をかぶった関数型プログラミング言語 Haxe
 
動的なILの生成と編集
動的なILの生成と編集動的なILの生成と編集
動的なILの生成と編集
 
FIRST STEP to Haxe/JavaScript
FIRST STEP to Haxe/JavaScriptFIRST STEP to Haxe/JavaScript
FIRST STEP to Haxe/JavaScript
 
大規模なギョームシステムにHaxeを採用してみた話
大規模なギョームシステムにHaxeを採用してみた話大規模なギョームシステムにHaxeを採用してみた話
大規模なギョームシステムにHaxeを採用してみた話
 
大規模なJavaScript開発の話
大規模なJavaScript開発の話大規模なJavaScript開発の話
大規模なJavaScript開発の話
 
Metro Style AppsでMSIL ver.2012/06/09
Metro Style AppsでMSILver.2012/06/09Metro Style AppsでMSILver.2012/06/09
Metro Style AppsでMSIL ver.2012/06/09
 
Metro Style AppsでMSIL
Metro Style AppsでMSILMetro Style AppsでMSIL
Metro Style AppsでMSIL
 
Yet Another DLR for Silverlightの試作
Yet Another DLR for Silverlightの試作Yet Another DLR for Silverlightの試作
Yet Another DLR for Silverlightの試作
 
スマートフォン×Cassandraによるハイパフォーマンス基盤の構築事例
スマートフォン×Cassandraによるハイパフォーマンス基盤の構築事例スマートフォン×Cassandraによるハイパフォーマンス基盤の構築事例
スマートフォン×Cassandraによるハイパフォーマンス基盤の構築事例
 
CommonJSの話
CommonJSの話CommonJSの話
CommonJSの話
 
Scala×silverlight
Scala×silverlightScala×silverlight
Scala×silverlight
 
DLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミングDLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミング
 
Iron Python / Iron Ruby で .NET Programming
Iron Python / Iron Ruby で .NET ProgrammingIron Python / Iron Ruby で .NET Programming
Iron Python / Iron Ruby で .NET Programming
 

Último

Último (11)

LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 

Webブラウザ上で動作する帳票エンジンを作る話