paint-brush
NodeJS と Foxit PDF SDK を使用して PDF 請求 Web アプリケーションを作成する方法@foxitsoftware
8,614 測定値
8,614 測定値

NodeJS と Foxit PDF SDK を使用して PDF 請求 Web アプリケーションを作成する方法

Foxit Software9m2023/06/23
Read on Terminal Reader

長すぎる; 読むには

デジタル請求書発行は、さまざまな業界で一般的に行われています。 Web アプリケーション開発者は、PDF 請求書をプログラムで生成して送信するというタスクに直面することがよくあります。 Foxit の __PDF ライブラリは、PDF ファイルを生成するための迅速かつ安全なソリューションを提供します。このチュートリアルでは、請求部門が未払いの請求書を効果的に管理できるようにする Web アプリケーションを構築するプロセスについて説明します。
featured image - NodeJS と Foxit PDF SDK を使用して PDF 請求 Web アプリケーションを作成する方法
Foxit Software HackerNoon profile picture
0-item
1-item


支払い請求書の作成はあらゆるビジネスにとって重要な側面であり、デジタル請求書発行はさまざまな業界で一般的な慣行となっています。これに関連して、Web アプリケーション開発者は、PDF 請求書をプログラムで生成して送信するというタスクに直面することがよくあります。


請求書の生成と通知プロセスを自動化する場合でも、未処理の請求書についてクライアントに積極的に通知するためのグラフィカル ユーザー インターフェイス (GUI) を開発する場合でも、最初の技術的な課題は PDF 請求書の生成にあります。 PDF 生成用のカスタム スクリプトを開発することもできますが、それはかなりの作業になります。 Web ベースのサービスは便利ですが、インターネット経由でサードパーティのサービスにデータを送信すると懸念が生じる可能性があるため、クライアントと機密保持契約を結んでいる場合には適さない可能性があります。


幸いなことに、Foxit はPDFライブラリPDF ファイルを生成するための迅速かつ安全なソリューションを提供します。それらを活用することで、 HTMLからPDFへのコンバーターでは、請求書などの HTML ドキュメントを PDF ファイルに変換して、電子メールに添付したり、クライアントが Web アプリケーションからダウンロードできるようにしたりできます。


このチュートリアルでは、 Node.jsを活用するアプリケーションFoxit PDF SDK Web アプリ内で HTML 請求書から PDF 請求書を生成します。生成したら、それを利用しますノードメーラーSMTP 経由でクライアントの電子メール アドレスに請求書を送信します。以下に概説する手順に従うことも、 Foxit の GitHub リポジトリにある完全なコードベースにアクセスします


PDF 請求書を作成および送信するための Web アプリケーションの構築

このチュートリアルでは、請求部門が未払いの請求書を効果的に管理できるようにする Web アプリケーションを構築するプロセスを説明します。フォローアップ用の内部ツール、未処理の請求書を表示するページ、各請求書のプレビュー ページなど、さまざまな機能を作成します。ユーザーは、請求書を添付してクライアントに電子メールによるリマインダーを送信するオプションを利用できます。


このプロジェクトでは、特急ウェブフレームワーク、純粋なCSSスタイリングに、そしてノードメーラー電子メール機能用。


前提条件:


新しい Express アプリの作成

新しいボイラープレート Express Web アプリケーションを作成するには、アプリ ジェネレーターを使用する必要があります。


 npx express-generator --git --view=hbs


これにより、 .gitignoreファイルを含む Web アプリが作成されます。ハンドルバーテンプレートファイル。

次に、Nodemailer npm パッケージを追加し、Express の依存関係をインストールする必要があります。


 npm i nodemailer && npm i


Express によって生成されるデフォルト アプリケーションには、 /routes/index.jsおよび/routes/users.jsという 2 つのルート ファイルが提供されます。 users.jsルートを削除し、 invoices.jsという新しいルート ファイルを作成します。この新しいルートをapp.jsファイルに追加し、 usersRouteを削除します。


 ... var indexRouter = require('./routes/index'); var invoicesRouter = require('./routes/invoices'); var app = express(); ... app.use('/', indexRouter); app.use('/invoices', invoicesRouter); ...


このアプリケーションの作業の大部分は、請求書ルーター内で行われます。


ルートを作成する前に、使用できるデータが必要になります。実際のアプリケーションでは、データベースに接続することになるでしょうが、デモの目的では、請求書データを JSON ファイルに追加します。


/data/invoices.jsonに新しいファイルを作成し、以下を追加します。


 [ { "id": "47427759-9362-4f8e-bfe4-2d3733534e83", "customer": "Bins and Sons", "contact_name": "Verne McKim", "contact_email": "[email protected]", "address": "3 Burning Wood Street", "city_state": "Memphis, TN 38118", "plan_id": "41595-5514", "plan_name": "Starter", "subtotal": 499.99, "fee": 50.00, "total": 549.99 }, { "id": "1afdd2fa-6353-437c-a923-e43baac506f4", customer": "Koepp Group", "contact_name": "Junia Pretious", "contact_email": "[email protected]", "address": "7170 Fairfield Hill", "city_state": "Los Angeles, CA 90026", "plan_id": "43419-355", "plan_name": "Professional", "amount": 999.99, "fee": 50.00, "total": 1049.99 }, { "id": "59c216f8-7471-4ec2-a527-ab3641dc49aa", "customer": "Lynch-Bednar", "contact_name": "Evelin Stollenberg", "contact_email": "[email protected]", "address": "9951 Erie Place", "city_state": "Chicago, IL 60605", "plan_id": "63323-714", "plan_name": "Starter", "amount": 499.99, "fee": 50.00, "total": 549.99 } ]


上に表示されている 3 つの請求書には、顧客、プラン、請求データが含まれており、次のセクションで請求書を生成するのに役立ちます。


請求書ルートの作成

routes/invoices.jsファイルは、アプリケーション内に 3 つの新しいルートを作成します。

  • /invoices – 上記のフラット データ ファイルからのすべての請求書のリスト。
  • /invoices/:id – ユーザーがクライアントに送信する前に請求書がどのようになるかを確認できる請求書のプレビュー。
  • /invoices/:id/email – PDF 請求書を生成し、ファイル上の連絡先メールアドレスに送信するエンドポイント。


invoices.jsファイルを開き、次のコード スニペットを追加して最初の 2 つのルートを定義します。


 const express = require('express'); const router = express.Router(); const invoices = require('../data/invoices.json'); // Import exec to run the Foxit HTML to PDF executable const { exec } = require('child_process'); // Import nodemailer to send emails const nodemailer = require('nodemailer'); router.get('/', function(req, res) { res.render('invoice-list', { invoices: invoices, // Accepts errors and successes as query string arguments success: req.query['success'], error: req.query['error'], }); }); router.get('/:id', function(req, res) { const invoice = invoices.find(invoice => invoice.id === req.params['id']); // If the invoice doesn't exist, redirect the user back to the list page if (!invoice) { res.redirect('/invoices'); } // Make the date format pretty const date = new Date().toLocaleDateString("en", { year:"numeric", day:"2-digit", month:"2-digit", }); res.render('invoice-single', { invoice, date }); }); router.get('/:id/email', function(req, res) { // Coming soon. }); module.exports = router;


アプリケーションはほぼテストの準備が整いましたが、最初に 2 つのビュー ファイルを作成する必要があります。


ビューとスタイルの追加

Express は、ロジックとプレゼンテーションをroutes/views/に分離します。次に、2 つの新しいファイルinvoice-list.hbsinvoice-single.hbsviews/ディレクトリに追加します。


また、 invoice-list.hbsファイルに以下を追加します。


 <h1><a href="/invoices">Unpaid Invoices</a></h1> {{#if success}} <p class="success"><strong>Success!</strong> The invoice has been sent to the client.</p> {{/if}} {{#if error}} <p class="error"><strong>Whoops!</strong> Something went wrong and your invoice could not be sent.</p> {{/if}} {{#each invoices}} <h3>{{this.customer}}</h3> <p>ID: {{this.id}} <br/> <a href="/invoices/{{this.id}}">View</a> | <a href="/invoices/{{this.id}}/email">Email Reminder</a> </p> {{/each}}


invoice invoice-single.hbsファイルを開き、これを追加します。


 <div class="pure-g"> <div class="pure-u-1-2"> <h1>Invoice</h1> </div> <div class="pure-u-1-2" style="text-align: right;"> <p class="muted">Issued on {{ date }}</p> </div> </div> <div class="pure-g"> <div class="pure-u-1-2"> <h3>Provider</h3> <p> <strong>Tiller, Inc.</strong><br/> 1255 S. Clark<br/> Chicago, IL 60608 </p> </div> <div class="pure-u-1-2" style="text-align: right;"> <h3>Billed to</h3> <p> <strong>{{invoice.customer}}</strong><br/> {{invoice.contact_name}}<br/> {{invoice.address}}<br/> {{invoice.city_state}} </p> </div> </div> <table class="pure-table pure-table-horizontal"> <thead> <tr> <th>ID</th> <th>Plan Name</th> <th class="text-right">Amount</th> </tr> </thead> <tbody> <tr> <td>{{invoice.plan_id}}</td> <td>{{invoice.plan_name}}</td> <td class="text-right">${{invoice.subtotal}}</td> </tr> <tr> <td></td> <td class="text-right">Subtotal:</td> <td class="text-right">${{invoice.subtotal}}</td> </tr> <tr> <td></td> <td class="text-right">Taxes and Fees:</td> <td class="text-right">${{invoice.fee}}</td> </tr> <tr class="bold"> <td></td> <td class="text-right">Total:</td> <td class="text-right">${{invoice.total}}</td> </tr> </tbody> </table> <div class="footer"> <p>Please make checks payable to <strong>Tiller, Inc</strong>. Invoices are due 30 days after date issued.</p> <p>Thank you for your business!</p> </div>


アプリケーションのスタイルシートにスタイルを追加し、純粋なCSSモジュール視覚的に魅力的な外観を得るには、 views/layout.hbsファイルを開いて、その内容を次のコード スニペットに置き換えてください。これにより Pure がインポートされ、単一列のグリッド レイアウトが作成されます。


 <!DOCTYPE html> <html> <head> <title>{{title}}</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://unpkg.com/[email protected]/build/pure-min.css" integrity="sha384-cg6SkqEOCV1NbJoCu11+bm0NvBRc8IYLRGXkmNrqUBfTjmMYwNKPWBTIKyw9mHNJ" crossorigin="anonymous"> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <div class="container"> <div class="pure-g"> <div class="pure-u-1"> {{{body}}} </div> </div> </div> </body> </html>


アプリケーションのpublic/style.css fileを開き、次の CSS コード スニペットを追加します。


 body { background-color: #f7f7f7; color: #333333; } a { color: #156d6a; } h1 a, h2 a, h3 a { text-decoration: none; } table { width: 100%; } .container { background-color: #ffffff; max-width: 700px; margin: 0 auto; padding: 30px; } .muted { color: #999999; } .bold { font-weight: bold; } .text-right { text-align: right; } .footer p { margin-top: 30px; } .success { background-color: #c0f5f3; color: #0d928d; padding: 10px; } .error { background-color: #f5c0c0; color: #792525; padding: 10px; }


必須ではありませんが、Foxit は PDF を生成するときに HTML ドキュメントからすべてのスタイルをキャプチャするため、請求書にスタイルを追加すると、プロフェッショナルな外観が向上します。

これで、アプリケーションをテストする準備が整いました。コマンド ライン インターフェイスでrun npm 、Web ブラウザを開いてlocalhost:3000/invoicesにアクセスしてください。次のような請求書のリストが表示されます。


「表示」をクリックして各請求書をプレビューします。



最後の 2 つのステップでは、Foxit__ HTML to PDF ツール__ を利用して PDF 請求書を生成します。請求書が生成されたら、送信する前に Nodemailer を使用して請求書を電子メールに添付します。


Foxit で PDF を生成する

Foxit の SDK は、HTML ドキュメントまたは URL から PDF ファイルを生成する機能など、PDF の作成と操作のためのさまざまな機能を提供します。 HTML を PDF 実行ファイルにダウンロードしてコンパイルするプロセスが利用可能ですここ。コマンド ラインからデモを正常に実行したら、次の手順に進むことができます。


ノードのchild_processライブラリには、コマンドライン関数を実行できるexec()という関数が含まれています。このメソッドは、Foxit から C++ 実行可能ファイルを実行する場合に便利です。 HTML to PDF 実行可能ファイルを実行するには、次のコードで/:id/emailルートを更新してください。


 ... router.get('/:id/email', function(req, res) { // Set the executable path and output folder const htmlToPdfPath = '/path/to/foxit/html2pdf'; const outputFolder = __dirname + '/../invoices/'; // Get the invoice const invoice = invoices.find(invoice => invoice.id === req.params['id']); if (!invoice) { res.redirect('/invoices?error=1'); } // Convert the HTML to PDF exec( `${htmlToPdfPath} -html /invoices/${req.params['id']} -o ${outputFolder}${req.params['id']}.pdf`, (err, stdout, stderr) => { if (err || stderr) { console.error(err, stderr); res.redirect('/invoices?error=1'); } else { // For now: log the output file path console.log(`PDF generated and saved to ${outputFolder}${req.params['id']}.pdf`); res.redirect('/invoices?success=1'); } }); });


このコードを実行する前に、 htmlToPdfPath変数を更新して、 htmltopdf実行可能ファイルへの正しいパスを反映していることを確認してください。


請求書のリマインダーをメールで送信するには、請求書のリストに戻り、特定の請求書の [リマインダーをメールで送信] をクリックしてください。このアクションにより、Node アプリがhtmltopdf実行可能ファイルを呼び出すようになります。次に、実行可能ファイルは、Express によって提供される HTML ドキュメントの請求書を PDF ファイルに変換します。作成された PDF ファイルは、Web アプリケーションのinvoices/ディレクトリにあります。


PDF 請求書を生成できるようになったので、最後のステップはこれらの請求書を顧客に送信することです。

Nodemailer を使用した電子メールの送信

ノードメーラーは、さまざまな電子メール トランスポート層にアクセスできる便利なインターフェイスを提供します。 SMTP は最も一般的に使用されるオプションの 1 つですが、代わりに Amazon SES やサーバーのsendmailコマンドなどのサービスを利用することもできます。


Nodemailer をテストするには、ストリームトランスポートのJSONオプションを使用すると、メッセージをコンソールに記録できます。メッセージを設定し、Nodemailer を使用して送信するには、 /invoices/:id/emailルートの「PDF generated and save to…」 console.logステートメントのすぐ下に次のコード スニペットを追加します。


 ... // Construct the message const message = { from: '[email protected]', to: invoice.contact_email, subject: 'Reminder: Your Invoice from Tiller, Inc. is Due', html: `<p>Hey ${invoice.contact_name},</p><p>I just wanted to remind you that your invoice for last month's services is now due. I've attached it here for your convenience.</p><p>Thanks for your business!</p>`, attachments: [ { filename: 'invoice.pdf', path: `${outputFolder}${req.params['id']}.pdf`, } ] }; // Use mailer to send invoice nodemailer .createTransport({jsonTransport: true}) .sendMail(message, function (err, info) { if (err) { res.redirect('/invoices?error=1'); } else { console.log(info.message); res.redirect('/invoices?success=1'); } }); ...


Node アプリケーションを更新し、いずれかの請求書の [電子メール リマインダー] をクリックしてください。今回は、コンソールに JSON として表示される完全な電子メール データ オブジェクトを観察します。


 { "from": { "address": "[email protected]", "name": "" }, "to": [ { "address": "[email protected]", "name": "" } ], "subject": "Reminder: Your Invoice from Tiller, Inc. is Due", "html": "<p>Hey Junia Pretious,</p><p>I just wanted to remind you that your invoice for last month's services is now due. I've attached it here for your convenience.</p><p>Thanks for your business!</p>", "attachments": [ { "content": "JVBERi0xLjMKJcTl8uXrp...", "filename": "invoice.pdf", "contentType": "application/pdf", "encoding": "base64" } ], "headers": {}, "messageId": "<[email protected]>" }


attachments.content文字列は、エンコードされた PDF ファイルを表します。簡潔にするために、上の例では省略しています。


実際のメールを使用してメールをテストするにはSMTPサーバー、使用できますメールトラップ。 Mailtrap のアカウントを持っていると仮定して、 createTransport({jsonTransport: true})呼び出しを次のコード スニペットに置き換えます。


 createTransport({ host: "smtp.mailtrap.io", port: 2525, auth: { user: "<YOUR_MAILTRAP_USERID>", pass: "<YOUR_MAILTRAP_PASS>" } })


請求書を電子メールで送信すると、Mailtrap は出力をキャプチャし、PDF 添付ファイルをダウンロードするオプションを提供します。 Mailtrap アカウントにアクセスすると、次の例のような電子メールが表示されます。



アプリを実稼働環境にデプロイする準備ができたら、Mailtrap SMTP 資格情報を実稼働メール サーバーに置き換えます。当社の Web アプリケーションは、請求チームからのリクエストに応じて PDF 請求書を生成し、クライアントに自動的に送信する機能を提供するようになりました。


請求書をオンラインで表示し、PDF として送信するためのソリューションが必要な場合、当社のアプリケーションは信頼できる基盤を提供します。 Foxit の HTML to PDF ツールは PDF を生成するための便利で効率的なオプションですが、他のさまざまなソリューションも提供していることに注意することが重要です。彼らと一緒に複数のプラットフォームで利用可能なソフトウェア開発キット (SDK) , Foxit は、PDF 機能を Web、モバイル、またはデスクトップ アプリケーションに統合する場合に理想的な選択肢として際立っています。


ここでも公開されています。