こちらの記事 に触発されて、svg-report というライブラリを作りました。
Inkscapeで作成したテンプレートSVGに、JSONで書式や値を渡し、ブラウザー上で表示した見た目をそのまま印刷できる帳票を作ります。
GitHubはこちらです。
何をするライブラリか
帳票をHTML/CSSで作ると、ブラウザー上ではきれいに見えていても、印刷時に微妙に位置がずれたり、改ページが意図した通りにならなかったりすることがあります。
そこで、帳票そのものをSVGで作り、そのSVGをブラウザー上に表示して、そのまま印刷する方式にしました。
帳票レイアウトはInkscapeで作成します。
たとえば、SVG内に次のようなプレースホルダーを配置します。
%name%
%price%
%comment%
そしてJavaScript側から値を渡します。
const recipe = {
svgUrl: "template.svg",
holderMap: {
"%name%": {
value: "商品A"
},
"%price%": {
value: "12,000",
opt: {
align: "e",
width: 30
}
},
"%comment%": {
value: "商品の説明です。",
opt: {
align: "T",
width: 80,
height: 30
}
}
}
};
これを svg-report に渡すと、SVG内のプレースホルダーが値に置き換えられます。
const report = new SvgReport(recipe, "#report");
report.render();
特徴
主な機能は次の通りです。
- Inkscapeで作成したSVGを帳票テンプレートとして利用
- プレースホルダーに値を埋め込み
- 文字の左寄せ・中央寄せ・右寄せ
- 複数行テキスト
- テキスト領域に合わせた自動縮小
- 文字幅・高さ・フォントサイズの指定
- 複数ページの帳票
- ブラウザー上の表示をそのまま印刷
実行時の依存ライブラリはありません。
なぜSVGなのか
HTML/CSSはWeb画面を作るには非常に便利ですが、帳票のように「この位置に、この文字を、このサイズで置く」という固定レイアウトでは、少し扱いづらいところがあります。
SVGなら、座標やサイズを明示的に指定できます。
またInkscapeを使えば、帳票レイアウトそのものをGUIで編集できます。
つまり、
Inkscape
↓
SVGテンプレート
↓
svg-report
↑
JSONの値・書式
↓
ブラウザー表示
↓
印刷
という構成になります。
レイアウト変更のたびにJavaScriptやHTMLを書き直す必要がなく、帳票デザインとプログラムを分離できます。
文字が長い場合
帳票では、設計時には長さが分からない値を扱うことがあります。
たとえば、
1,000
と
100,000,000,000,000,000
が同じ欄に入ることがあります。
svg-report では、文字列が指定された領域より長い場合、SVGの textLength を利用して領域内に収めます。
複数行テキストについては、指定された幅と高さに収まるように行を分割し、必要に応じてフォントサイズも小さくします。
複数行テキスト
たとえばコメント欄は次のように指定できます。
"%comment%": {
value: "1行目\n2行目\n3行目",
opt: {
align: "T",
width: 80,
height: 30
}
}
align に大文字の T、M、B を指定すると、複数行領域として扱います。
| 指定 | 縦方向の位置 |
|---|---|
T |
上寄せ |
M |
中央 |
B |
下寄せ |
横方向の配置
1行のテキストは次の指定ができます。
| 指定 | 配置 |
|---|---|
s |
左寄せ |
m |
中央寄せ |
e |
右寄せ |
金額欄などは、
"%price%": {
value: "12,000",
opt: {
align: "e"
}
}
のようにすると右寄せになります。
値が存在しないプレースホルダー
テンプレート側にプレースホルダーがあっても、JSON側に値がない場合は空欄として扱います。
たとえば、明細を最大10行分テンプレートに用意していて、実際のデータが3行しかない場合でも、4行目以降をすべて空文字として指定する必要はありません。
帳票ではこの使い方がかなり便利です。
複数ページ
レシピを配列にすると複数ページにできます。
const recipe = [
{
svgUrl: "page1.svg",
holderMap: {
"%title%": {
value: "1ページ目"
}
}
},
{
svgUrl: "page2.svg",
holderMap: {
"%title%": {
value: "2ページ目"
}
}
}
];
SVGテンプレート1枚が、そのまま帳票1ページになります。
サンプル
リポジトリにはサンプルも入れています。
cd sample
npm install
npm start
ブラウザーで
http://localhost:8080/
を開くと確認できます。
長い商品名、大きな数値、複数行コメント、複数ページなどを試しています。
まとめ
svg-report は、
Inkscapeを帳票デザイナーとして使い、SVGをそのままブラウザー表示・印刷する
という考え方のライブラリです。
HTML/CSSで帳票レイアウトを細かく調整するより、帳票そのものをInkscapeで作った方が楽なケースもあると思います。
まだ小さなライブラリですが、
- 見積書
- 請求書
- 注文書
- 申込書
- 固定レイアウトの業務帳票
などには使いやすい方式ではないかと思っています。
GitHub:
