Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9360

SVG + CSS + Node.js + receiptline で電子レシートを発行してみよう

$
0
0

マークダウン言語で紙のレシートや電子レシートを簡単に作れる receiptline。
https://github.com/receiptline/receiptline
https://www.npmjs.com/package/receiptline

今回は receiptline 本来の用途と考えられる、電子レシートの発行です!

レシートを設計する

デザインツール

ReceiptLine Designer を使います。使い方はこの連載記事の初回から。
いますぐ試したい方は、開発元のホームページで公開されているのでこちらへ。
01.png

ロゴの背景を透明に

以前の記事で作成したロゴ画像を再利用します。
02.png

GIMP の「色を透明度に」 (Color to Alpha) 機能で、背景色を白から透明にしました。
03.png

2023年度インボイス制度対応

前回の記事で学習した、簡易適格請求書等の記載事項も追加しておきます。

  • ① 適格請求書発行事業者の氏名又は名称及び登録番号
  • ② 課税資産の譲渡等を行った年月日
  • ③ 課税資産の譲渡等に係る資産又は役務の内容(課税資産の譲渡等が軽減対象資産の譲渡等である場合には、資産の内容及び軽減対象資産の譲渡等である旨)
  • ④ 課税資産の譲渡等の税抜価額又は税込価額を税率ごとに区分して合計した金額
  • ⑤ 税率ごとに区分した消費税額等又は適用税率

04.png

作成したレシートデータ

ReceiptLine
{image:iVBORw0KGgoAAAANSUhEUgAAASAAAAAwAgMAAADMTE88AAAACVBMVEVwAAsAAAD///9xeVj9AAAAAXRSTlMAQObYZgAAAdZJREFUSMftlsFu4zAMRMUD73sI/0c59M4Amv//lXJI2XEWaGSgAVrsxuihtqgnmjOk09r7+pcv7esYAEtMM19yrCkWxwnOgEbk1Fc5nwBpRNgCpGdAhKi/4NVYaFmD1qqlYi8ACU6Y6BRo/DaQjk3hiARv4BeB834aVXBDk1bL0lHlCEs0Qz5zP4A89FVW3rgWNwGxWrRuCVIC7Ao3HjBCamY6mt7GHSQ9/rnQVEGZIBmlBPL0Fsvoig8Mg9N6KJAAB5ASFPDYzUcJytgEFXAQzpf2/ajMCMeMjCAwMX8A9ZQjQUJQ7mZs5G4TZMcaXRJd3bKBLOZLz4gC9Q00Y8030FE1Vga5egf5put0rTwDbT4SalV6fQmyp6DZIqCONXe+Aqk/A82mlcF3RO7eQeMRZH0JElePJ3P336BNfjwtdg42CV9PHynu8ldjSO7NIhxAD/Lvo1YDZONPgdIlg26JvwT4BAmud1AZstsOkhz+Fo3pERHhdLxiMCy9z89VgcAmnaCyPfCxg2hqnn4NWr/MtWgD0Fdeqt9qLAwbOyiaNtXRXV3eDeZlfAmKlPrxK6WbD2umR02i0diyyBmTdVEmvhhR3//Mv0H/M8jwIhBWv7ve189enyEmqNlnG50wAAAAAElFTkSuQmCC}
柳都市星降町7丁目8番9号
登録番号 T1234567890123

2020年12月16日(水)12:34  #0903
{border:line; width:22}
^領 収 書
{border:space; width:3,*,3,8; text:nowrap}
166003 |2021葱鏡餅 水引 | 3個| ¥1,620*
691004 |洗面器45RPM N025 | 1個| ¥1,210~
-
{width:auto; text:wrap}
小 計 |4点 | ¥2,830~
(税率10%対象 | ¥1,210)
(内消費税等10% | ¥110)
(税率 8%対象 | ¥1,620)
(内消費税等 8% | ¥120)
-
合 計 | ^¥2,830
お預り | ^¥3,000
お釣り | ^¥170
|*印は軽減税率対象商品です
{code:202012160903; option:code128,2,48}

電子レシート発行サーバーを作る

Node.js

Node.js で電子レシートを発行する HTTP サーバーを作ります。
receipt.jsの内部構成は、以下のようになっています。

  • ReceiptLine
    • 作成したレシートデータ (固定) を SVG に変換する
  • HTML
    • 作成した SVG を HTML に埋め込む
  • HTTP サーバー
    • 任意の GET リクエストを受けて、作成した HTML を返す
receipt.js
consthttp=require('http');constreceiptline=require('receiptline');// ReceiptLineconsttext=`{image:iVBORw0KGgoAAAANSUhEUgAAASAAAAAwAgMAAADMTE88AAAACVBMVEVwAAsAAAD///9xeVj9AAAAAXRSTlMAQObYZgAAAdZJREFUSMftlsFu4zAMRMUD73sI/0c59M4Amv//lXJI2XEWaGSgAVrsxuihtqgnmjOk09r7+pcv7esYAEtMM19yrCkWxwnOgEbk1Fc5nwBpRNgCpGdAhKi/4NVYaFmD1qqlYi8ACU6Y6BRo/DaQjk3hiARv4BeB834aVXBDk1bL0lHlCEs0Qz5zP4A89FVW3rgWNwGxWrRuCVIC7Ao3HjBCamY6mt7GHSQ9/rnQVEGZIBmlBPL0Fsvoig8Mg9N6KJAAB5ASFPDYzUcJytgEFXAQzpf2/ajMCMeMjCAwMX8A9ZQjQUJQ7mZs5G4TZMcaXRJd3bKBLOZLz4gC9Q00Y8030FE1Vga5egf5put0rTwDbT4SalV6fQmyp6DZIqCONXe+Aqk/A82mlcF3RO7eQeMRZH0JElePJ3P336BNfjwtdg42CV9PHynu8ldjSO7NIhxAD/Lvo1YDZONPgdIlg26JvwT4BAmud1AZstsOkhz+Fo3pERHhdLxiMCy9z89VgcAmnaCyPfCxg2hqnn4NWr/MtWgD0Fdeqt9qLAwbOyiaNtXRXV3eDeZlfAmKlPrxK6WbD2umR02i0diyyBmTdVEmvhhR3//Mv0H/M8jwIhBWv7ve189enyEmqNlnG50wAAAAAElFTkSuQmCC}
柳都市星降町7丁目8番9号
登録番号 T1234567890123

2020年12月16日(水)12:34  #0903
{border:line; width:22}
^領 収 書
{border:space; width:3,*,3,8; text:nowrap}
166003 |2021葱鏡餅 水引 | 3個| ¥1,620*
691004 |洗面器45RPM N025 | 1個| ¥1,210~
-
{width:auto; text:wrap}
小 計 |4点 | ¥2,830~
(税率10%対象 | ¥1,210)
(内消費税等10% | ¥110)
(税率 8%対象 | ¥1,620)
(内消費税等 8% | ¥120)
-
合 計 | ^¥2,830
お預り | ^¥3,000
お釣り | ^¥170
|*印は軽減税率対象商品です
{code:202012160903; option:code128,2,48}`;constsvg=receiptline.transform(text,{cpl:32,encoding:'cp932',spacing:true});// HTMLconststyle='float: left; padding: 24px; background: lavender;';consthtml=`<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>レシート</title>
    </head>
    <body>
        <div style="${style}">${svg}</div>
    </body>
</html>`;// HTTP Serverconstserver=http.createServer((req,res)=>{switch(req.method){case'GET':res.end(html);break;default:res.end();break;}});server.listen(8080,"127.0.0.1",()=>{console.log('Server running at http://127.0.0.1:8080/');});

実行

電子レシート発行サーバーを起動します。

$ node receipt.js

Web ブラウザーで localhost:8080を開きます。
receiptline ライブラリが動作しない IE11 でも表示 OK。
05.png

作成された SVG データ

レシートデータから生成された SVG データです。
中身はパス、画像、テキスト、Web フォント、フィルター、いろいろ入っています。

SVG
<svgwidth="384px"height="684px"viewBox="0 0 384 684"preserveAspectRatio="xMinYMin meet"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"version="1.1"><styletype="text/css"><![CDATA[@import url("https://fonts.googleapis.com/css2?family=Kosugi+Maru&display=swap");]]></style><defs><filterid="receiptlineinvert"x="0"y="0"width="100%"height="100%"><feFloodflood-color="#000"/><feCompositein="SourceGraphic"operator="xor"/></filter></defs><gfont-family="'Kosugi Maru', 'MS Gothic', 'San Francisco', 'Osaka-Mono', 'Courier New', 'Courier', monospace"fill="#000"font-size="24"dominant-baseline="text-after-edge"><gtransform="translate(48,0)"><imagexlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAAAwAgMAAADMTE88AAAACVBMVEVwAAsAAAD///9xeVj9AAAAAXRSTlMAQObYZgAAAdZJREFUSMftlsFu4zAMRMUD73sI/0c59M4Amv//lXJI2XEWaGSgAVrsxuihtqgnmjOk09r7+pcv7esYAEtMM19yrCkWxwnOgEbk1Fc5nwBpRNgCpGdAhKi/4NVYaFmD1qqlYi8ACU6Y6BRo/DaQjk3hiARv4BeB834aVXBDk1bL0lHlCEs0Qz5zP4A89FVW3rgWNwGxWrRuCVIC7Ao3HjBCamY6mt7GHSQ9/rnQVEGZIBmlBPL0Fsvoig8Mg9N6KJAAB5ASFPDYzUcJytgEFXAQzpf2/ajMCMeMjCAwMX8A9ZQjQUJQ7mZs5G4TZMcaXRJd3bKBLOZLz4gC9Q00Y8030FE1Vga5egf5put0rTwDbT4SalV6fQmyp6DZIqCONXe+Aqk/A82mlcF3RO7eQeMRZH0JElePJ3P336BNfjwtdg42CV9PHynu8ldjSO7NIhxAD/Lvo1YDZONPgdIlg26JvwT4BAmud1AZstsOkhz+Fo3pERHhdLxiMCy9z89VgcAmnaCyPfCxg2hqnn4NWr/MtWgD0Fdeqt9qLAwbOyiaNtXRXV3eDeZlfAmKlPrxK6WbD2umR02i0diyyBmTdVEmvhhR3//Mv0H/M8jwIhBWv7ve189enyEmqNlnG50wAAAAAElFTkSuQmCC"x="0"y="0"width="288"height="48"/></g><gtransform="translate(0,72)"><textx="54,78,102,126,150,174,198,210,234,258,270,294,306">柳都市星降町7丁目8番9号</text></g><gtransform="translate(0,102)"><textx="54,78,102,126,150,162,174,186,198,210,222,234,246,258,270,282,294,306,318">登録番号&#xa0;T1234567890123</text></g><gtransform="translate(0,132)"><textx="0">&#xa0;</text></g><gtransform="translate(0,162)"><textx="12,24,36,48,60,84,96,108,132,144,156,180,192,216,228,240,252,264,276,288,300,312,324,336,348,360">2020年12月16日(水)12:34&#xa0;&#xa0;#0903</text></g><gtransform="translate(48,192)"><textx="0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228,240,252,264,276">╔══════════════════════╗</text></g><gtransform="translate(48,216)"><texttransform="scale(1,1)"x="0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228,240,252,264,276">&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;</text><texttransform="scale(2,1)"x="24,48,60,84,96">&#xa0;&#xa0;</text></g><gtransform="translate(48,240)"><textx="0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228,240,252,264,276">╚══════════════════════╝</text></g><gtransform="translate(0,270)"><textx="0,12,24">166</text><textx="48,60,72,84,96,120,144,168,180,204">2021葱鏡餅&#xa0;水引</text><textx="240,252">3個</text><textx="300,312,324,336,348,360,372">¥1,620*</text></g><gtransform="translate(0,300)"><textx="0,12,24">691</text><textx="48,72,96,120,132,144,156,168,180,192,204,216">洗面器45RPM&#xa0;N02</text><textx="240,252">1個</text><textx="300,312,324,336,348,360,372">¥1,210&#xa0;</text></g><gtransform="translate(0,330)"><textx="0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228,240,252,264,276,288,300,312,324,336,348,360,372">════════════════════════════════</text></g><gtransform="translate(0,360)"><textx="0,24,48">小 計</text><textx="132,144">4点</text><textx="300,312,324,336,348,360,372">¥2,830&#xa0;</text></g><gtransform="translate(0,390)"><textx="0,12,36,60,72,84,96,120">(税率10%対象</text><textx="300,312,324,336,348,360,372">¥1,210)</text></g><gtransform="translate(0,420)"><textx="0,12,36,60,84,108,132,144,156">(内消費税等10%</text><textx="324,336,348,360,372">¥110)</text></g><gtransform="translate(0,450)"><textx="0,12,36,60,72,84,96,120">(税率&#xa0;8%対象</text><textx="300,312,324,336,348,360,372">¥1,620)</text></g><gtransform="translate(0,480)"><textx="0,12,36,60,84,108,132,144,156">(内消費税等&#xa0;8%</text><textx="324,336,348,360,372">¥120)</text></g><gtransform="translate(0,510)"><textx="0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228,240,252,264,276,288,300,312,324,336,348,360,372">════════════════════════════════</text></g><gtransform="translate(0,540)"><textx="0,24,48">合 計</text><texttransform="scale(2,1)"x="120,132,144,156,168,180">¥2,830</text></g><gtransform="translate(0,570)"><textx="0,24,48">お預り</text><texttransform="scale(2,1)"x="120,132,144,156,168,180">¥3,000</text></g><gtransform="translate(0,600)"><textx="0,24,48">お釣り</text><texttransform="scale(2,1)"x="144,156,168,180">¥170</text></g><gtransform="translate(0,630)"><textx="0,12,36,60,84,108,132,156,180,204,228,252,276">*印は軽減税率対象商品です</text></g><gtransform="translate(91,636)"><pathd="M0,0h4v48h-4zM6,0h2v48h-2zM12,0h6v48h-6zM22,0h4v48h-4zM30,0h2v48h-2zM36,0h6v48h-6zM44,0h4v48h-4zM52,0h2v48h-2zM58,0h6v48h-6zM66,0h2v48h-2zM70,0h4v48h-4zM78,0h6v48h-6zM88,0h2v48h-2zM94,0h6v48h-6zM102,0h4v48h-4zM110,0h4v48h-4zM118,0h2v48h-2zM124,0h2v48h-2zM132,0h2v48h-2zM138,0h2v48h-2zM144,0h4v48h-4zM154,0h4v48h-4zM162,0h2v48h-2zM166,0h6v48h-6zM176,0h4v48h-4zM186,0h6v48h-6zM194,0h2v48h-2zM198,0h4v48h-4z"fill="#000"/></g></g></svg>

電子レシートの背景をカスタマイズする

ソースコードの CSS を変更して、電子レシートの背景をカスタマイズします。

単色

お店のキャンペーンでよく使われるピンクレシートと黄色いレシート。

receipt.js
conststyle='float: left; padding: 24px; background: pink;';

06.png

receipt.js
conststyle='float: left; padding: 24px; background: #ff9;';

07.png

多色

サーマルロール紙にはできないグラデーション。

receipt.js
conststyle='float: left; padding: 24px; background: linear-gradient(skyblue, lightyellow);';

08.png

receipt.js
conststyle='float: left; padding: 24px; background: linear-gradient(lightgreen, snow, beige);';

09.png

透かし

「複写」「COPY」の画像をタイル状に並べます。画像は CSS に埋め込みます。
10.png

画像の Data URI 形式への変換は ReceiptLine Designer を使うと簡単です。
画像をロードして image:data:image/png;base64,に置き換えます。
11.png

receipt.js
conststyle='float: left; padding: 24px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANgAAADYAQMAAACz7r+uAAAABlBMVEXc3tv5+/j5MJA8AAADWklEQVRYw+2YPW7bMBSAqTAwMxTmBVwqR2g3G1AiH8W9gYMsCuLGSg3UW3yBwDlElwLNYMGDlza+QFsoMFqvDAy0NCpENQqRj3yCshfRmyh9En8eH98PCamllucih0+wPjT3MFPQZAh5GbQ5YvQ7tH3E2ATaAWK8Ae0MMXEAXUjEgpZpDjGLzCA0TxGTkelSIeal0tP/XSJGk9Uo1t/N0PJGi0UV478nS9MHYiL3Hw2L0fIuWpnF9t3lRQrGTps2GwQS2Fg5O3H88h765NmxzXx//tXowRcDZw18PIVJc2WrpcG5ME8tZ5cYYQKYoLZGOWkEwJpsZg2429hoYA1+mQPrxATWR9gNy0FvpzMvBcOmj3xu2It1aivfy3zYJ38pma18dUzMTP2pcuy8HwDjt1nDOW+Rxc6u8YEzjG3ayCI9YD/P4wrWYNnaZbAk7m8XLuuxpHjB8uHNO3cufFJ0SrMwv3KZr7d3p6M/U2SSLNPsy8Y9q35GivNIPydr5R4BRQoTpVcJOo+7JWjGt3mMfZE2bb5dILJnGNu+x+4mNiy5wgz+W01LTBhvc11i2qewqF1i2lxZEJXmopVBRR+7zEtZ5U2JB4piJbXksyq3sXOG0EVcB8Faaqmllv9TIGW5KMWHGUSKEksh/S3FAAg5CUpHyX7U1SzGaXMz0NFLEMyEiWwBwTGuxWUl6yw0i0p9vp7LcupUyInFephNZLnG0WFzIrsVjOajdjFMm3C3nuCrUccw381twsWHT4UaRT+8ddjbpfILxuXAydLJ2bdMMyaVW2e92T7qisZLpMu8zU2mZ0dTxNZh2jN5Fard7k7BKGLEWmsJuQbKRI7u+sCEW2CG1+Y/SkTDzSM7CsYLnE4l31gs82Pbctn6o3lIVAgm2qAzurT2Mo3ALDiLPSuZG85k36pXnJoztGuEQPRI5GSjkNq1A0mcaia1WCQPbcPj0mIPst+1D0cEIxytlJMfBqGCMmRx65TGEZdQhkxajur7LAUmhEBlP7AgDKpcQ6iGUZVLOZe/ZBV7uP+BS2PD0vkc+RQa6xddNka+iI6hXirdJkD66y7vX0UDllu6TYB5H+BU3DK0V/jGwKqFT7C7GdiWVX1ZEsZVnrZ8IWK7reYTAWC/joG1PBv5C4viMg7LEHCAAAAAAElFTkSuQmCC);';

12.png

地紋

領収書やチケットでよく見かける地紋です。小さな素片をタイル状に並べます。
13.png

conststyle='float: left; padding: 24px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADAQMAAACplL1tAAAABlBMVEX/pQD////52iT3AAAAFElEQVQI12M4l/+AYf/mCQyFdwoAJNIF3T0xRTsAAAAASUVORK5CYII=);';

14.png

また何か作ったら投稿します。ではまた!


Viewing all articles
Browse latest Browse all 9360

Trending Articles