paint-brush
Como criar um aplicativo da Web de faturamento em PDF usando NodeJS e Foxit PDF SDKpor@foxitsoftware
8,204 leituras
8,204 leituras

Como criar um aplicativo da Web de faturamento em PDF usando NodeJS e Foxit PDF SDK

por Foxit Software9m2023/06/23
Read on Terminal Reader

Muito longo; Para ler

A faturação digital tornou-se uma prática comum em vários setores. Os desenvolvedores de aplicativos da Web geralmente enfrentam a tarefa de gerar e enviar faturas em PDF programaticamente. A biblioteca __PDF da Foxit oferece uma solução rápida e segura para gerar arquivos PDF. Neste tutorial, orientaremos você no processo de criação de um aplicativo da Web que permite que seu departamento de cobrança gerencie faturas não pagas com eficiência.
featured image - Como criar um aplicativo da Web de faturamento em PDF usando NodeJS e Foxit PDF SDK
Foxit Software HackerNoon profile picture
0-item
1-item


A geração de faturas de pagamento é um aspecto crucial de qualquer negócio, e o faturamento digital tornou-se uma prática comum em vários setores. Nesse contexto, os desenvolvedores de aplicativos da Web geralmente enfrentam a tarefa de gerar e enviar faturas em PDF programaticamente.


Esteja você automatizando o processo de geração e notificação de faturas ou desenvolvendo uma interface gráfica do usuário (GUI) para lembrar proativamente os clientes sobre faturas pendentes, o desafio técnico inicial está na geração de faturas em PDF. Embora você possa desenvolver um script personalizado para geração de PDF, isso seria uma tarefa significativa. Embora os serviços baseados na Web sejam convenientes, eles podem não ser adequados se você tiver acordos de confidencialidade com seus clientes, pois o envio de dados para um serviço de terceiros pela Internet pode causar problemas.


Felizmente, a Foxit Biblioteca de PDF fornece uma solução rápida e segura para gerar arquivos PDF. Ao utilizar seus Conversor de HTML para PDF , você pode converter qualquer documento HTML, incluindo faturas, em um arquivo PDF que pode ser anexado a um e-mail ou disponibilizado para os clientes fazerem o download de seu aplicativo da web.


Este tutorial irá guiá-lo através do processo de criação de um Node.js aplicativo que potencializa o Foxit PDF SDK para gerar faturas em PDF a partir de faturas em HTML em um aplicativo da web. Uma vez gerado, você utilizará Nodemailer para enviar a Fatura via SMTP para o endereço de e-mail do cliente. Você pode seguir as etapas descritas abaixo ou acesse a base de código completa no repositório GitHub da Foxit .


Construindo um aplicativo da Web para criar e enviar faturas em PDF

Neste tutorial, orientaremos você no processo de criação de um aplicativo da Web que permite que seu departamento de cobrança gerencie faturas não pagas com eficiência. Você criará vários recursos, incluindo uma ferramenta interna para acompanhamento, uma página de exibição de faturas pendentes e uma página de visualização de cada fatura. Os usuários terão a opção de enviar lembretes por e-mail aos clientes com a fatura anexada.


Para este projeto, utilizaremos o Expressar estrutura da web, CSS puro para estilizar e Nodemailer para a funcionalidade de e-mail.


Pré-requisitos:


Criando um novo aplicativo expresso

Para criar um novo aplicativo da web padrão do Express, você precisa usar o gerador de aplicativos :


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


Isso criará um aplicativo da web com um arquivo .gitignore e Guidão arquivos de modelo.

Em seguida, você precisa adicionar o pacote Nodemailer npm e instalar as dependências do Express:


 npm i nodemailer && npm i


O aplicativo padrão gerado pelo Express fornece dois arquivos de rota: /routes/index.js e /routes/users.js . Remova a rota users.js e crie um novo arquivo de rota chamado invoices.js . Adicione esta nova rota ao seu arquivo app.js e remova o usersRoute :


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


A maior parte do trabalho neste aplicativo está dentro do roteador de faturas.


Antes de criar a rota, você precisará de alguns dados que possa usar. Em um aplicativo real, você provavelmente se conectará a um banco de dados, mas, para fins de demonstração, adicione os dados da fatura a um arquivo JSON.


Crie um novo arquivo em /data/invoices.json e adicione o seguinte:


 [ { "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 } ]


As três faturas que você pode ver acima contêm dados de cliente, plano e cobrança que o ajudarão a gerar uma fatura na próxima seção.


Criando as Rotas de Faturas

O arquivo routes/invoices.js criará três novas rotas em seu aplicativo:

  • /invoices – Uma lista de todas as faturas do arquivo de dados simples acima.
  • /invoices/:id – Uma visualização da fatura para que os usuários possam ver como será a fatura antes de enviá-la ao cliente.
  • /invoices/:id/email – Um terminal que gera e envia a fatura em PDF para o e-mail de contato que está arquivado.


Abra o arquivo invoices.js e adicione o seguinte trecho de código para definir as duas primeiras rotas:


 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;


Seu aplicativo está quase pronto para teste, mas primeiro você precisa criar os dois arquivos de exibição.


Adicionando exibições e estilos

O Express separa a lógica e a apresentação em routes/ e views/ . Agora adicione dois novos arquivos ao diretório views/ : invoice-list.hbs e invoice-single.hbs .


Além disso, adicione o seguinte ao seu arquivo 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}}


Abra o arquivo invoice-single.hbs e adicione isto:


 <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>


Para adicionar estilos à folha de estilo do seu aplicativo e incorporar o Módulo CSS puro para uma aparência visualmente atraente, abra o arquivo views/layout.hbs e substitua seu conteúdo pelo trecho de código a seguir. Isso importará Pure e criará um layout de grade de coluna única:


 <!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>


Abra public/style.css file de seu aplicativo e adicione o seguinte trecho de código 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; }


Embora não seja obrigatório, adicionar estilos às suas faturas pode melhorar sua aparência profissional, pois o Foxit captura todo o estilo do seu documento HTML ao gerar PDFs.

Agora, você está pronto para testar seu aplicativo. run npm start em sua interface de linha de comando e abra seu navegador da Web em localhost:3000/invoices Você verá uma lista de faturas semelhante à seguinte:


Clique em “Visualizar” para visualizar cada fatura.



Nas duas etapas finais, você utilizará a ferramenta Foxit__ HTML para PDF __ para gerar faturas em PDF. Assim que as faturas forem geradas, você irá anexá-las a um e-mail usando o Nodemailer antes de enviá-las.


Gerando PDFs com Foxit

O SDK da Foxit oferece uma variedade de funcionalidades para criação e manipulação de PDF, incluindo a capacidade de gerar um arquivo PDF a partir de um documento HTML ou URL. O processo de download e compilação do executável HTML para PDF está disponível aqui . Depois de executar com sucesso a demonstração na linha de comando, você pode prosseguir com as próximas etapas.


A biblioteca child_process do Node inclui uma função chamada exec() que permite executar funções de linha de comando. Este método é útil para executar executáveis C++ da Foxit. Para executar o executável HTML para PDF, atualize sua rota /:id/email com o seguinte código:


 ... 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'); } }); });


Antes de executar este código, certifique-se de atualizar a variável htmlToPdfPath para refletir o caminho correto para seu executável htmltopdf .


Para enviar um lembrete por e-mail para uma fatura, volte à sua lista de faturas e clique em “Lembrete por e-mail” para qualquer fatura específica. Essa ação acionará o aplicativo Node para chamar o executável htmltopdf . O executável, por sua vez, converterá a fatura do documento HTML servido pelo Express em um arquivo PDF. Você pode localizar o arquivo PDF resultante no diretório invoices/ de seu aplicativo da web.


Agora que você pode gerar faturas em PDF, a etapa final é enviar essas faturas para seus clientes.

Enviando e-mails com Nodemailer

Nodemailer oferece uma interface conveniente que permite acessar várias camadas de transporte de e-mail. O SMTP é uma das opções mais usadas, mas você também pode utilizar serviços como o Amazon SES ou o comando sendmail do seu servidor como alternativas.


Para testar o Nodemailer, você pode utilizar o opção JSON do transporte de fluxo , que permite registrar a mensagem em seu console. Para configurar sua mensagem e enviá-la usando o Nodemailer, adicione o seguinte trecho de código logo abaixo da instrução “PDF gerado e salvo em…” console.log em sua rota /invoices/:id/email :


 ... // 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'); } }); ...


Atualize seu aplicativo Node e clique em “Email Reminder” para qualquer uma das faturas. Desta vez, você observará o objeto de dados de email completo exibido como JSON em seu console.


 { "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]>" }


A string attachments.content representa o arquivo PDF codificado. Por uma questão de brevidade, trunquei-o no exemplo acima.


Para testar o e-mail usando um real servidor SMTP , você pode usar Mailtrap . Supondo que você tenha uma conta no Mailtrap, substitua a chamada createTransport({jsonTransport: true}) pelo seguinte trecho de código:


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


Ao enviar a fatura por e-mail, o Mailtrap capturará a saída e fornecerá a você a opção de baixar o anexo em PDF. Ao acessar sua conta Mailtrap, você encontrará um e-mail semelhante ao exemplo abaixo:



Quando estiver pronto para implantar seu aplicativo na produção, substitua as credenciais Mailtrap SMTP por um servidor de e-mail de produção. Nosso aplicativo da web agora oferece a capacidade de gerar e enviar automaticamente faturas em PDF para clientes mediante solicitação de nossa equipe de cobrança.


Se você precisar de uma solução para apresentar faturas online e enviá-las como PDFs, nosso aplicativo oferece uma base confiável. Embora a ferramenta HTML para PDF da Foxit seja uma opção conveniente e eficiente para gerar PDFs, é importante observar que eles também oferecem várias outras soluções. Com seus kits de desenvolvimento de software (SDKs) disponíveis para várias plataformas , o Foxit se destaca como a escolha ideal ao integrar a funcionalidade PDF em seus aplicativos da Web, dispositivos móveis ou desktop.


Publicado também aqui .