динамически генерировать PDF с помощью пакета html-pdf - PullRequest
0 голосов
/ 13 ноября 2018

Я использую пакет npm html-pdf

Я пытался динамически генерировать счета. В конце концов он создает файлы PDF, но вместо сохранения значений в PDF он сохраняет код ejs. Кто-нибудь знает, что пошло не так?

Вы можете проверить скриншот ниже вывода PDF с переменными ejs:

https://i.stack.imgur.com/LPjN7.png

Теперь позвольте мне объяснить мое приложение для узла:

Я использую две ejs страницы. Один из них - home.ejs, откуда мы публикуем входные значения, которые необходимо заполнить в PDF. Вторая страница - crm.ejs, где находится мой шаблон счета. В crm.ejs я использую функцию window.onload, поэтому, когда все загружается в мой шаблон crm.ejs. Затем он будет генерировать PDF. Но все же это только сохранить ejs переменных.

Теперь вот код

app.js

var express = require("express");
var app = express();
var webshot = require('webshot');
var fs = require('fs');
var pdf = require('html-pdf');
var html = fs.readFileSync('views/crm.ejs', 'utf8');
var options = { format: 'a4' };
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended:true}));

app.locals.pdf = require("html-pdf");
app.locals.html = fs.readFileSync('views/crm.ejs', 'utf8');
app.locals.options =  { format: 'a4' };
app.locals.fs = require("fs");
app.use(express.static("public"));

app.get("/",function(req,res){
    res.render("home.ejs");
});

app.post("/crm",function(req,res){
    // res.render("crm.ejs");
    console.log(req.body);
    var details = req.body;
    res.render("crm.ejs",{details:details});
});

app.listen(process.env.PORT,process.env.IP,function(){
    console.log("Server started successfully!!");
}); 

home.ejs:

 <form action="/crm" method="post">
    <label>First Name</label>
    <input type="text" name="fname"><br />

    <label>Last Name</label>
    <input type="text" name="lname"><br />

    <label>Email</label>
    <input type="text" name="email"><br />

    <label>Phone number</label>
    <input type="text" name="phone"><br />

    <label>Address</label>
    <textarea name="address"></textarea><br />

    <button>Save</button>

</form>

crm.ejs:

<html>
<head>
<title>BillBook</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<style>
    #billbook{
       height:845px;
        width:595px;
        background-repeat: no-repeat;
        background-size: 595px 845px;
        border:1px solid red;
        /*margin:0px auto;*/
        margin:0px !important;
    }

    table{
       width: 92% !important;

            margin: 0px auto;
            color:#7f7f7f;
              border-radius: 0px 0px 6px 6px;
    -moz-border-radius: 6px 6px 6px 6px;
    -webkit-border-radius: 6px 6px 6px 6px;
  border-width: 0.5px !important;
  border-style: solid !important;
  border-color: #f3f3f3 !important;
    }
    tr{
        border:1px solid #f3f3f3;
    }
    td{
        border:1px solid #f3f3f3;
           padding: 5px 0px 5px 6px;
            font-size:12px;  
    }
</style>
</head>
<body bgcolor="#FFFFFF" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
    <!--<img src="../images/final.jpg" width="595" height="842" alt="">-->  
    <section id="billbook">
        <table style=" margin-top: 175px !important;">
            <tr>
                <td width="59%" style="padding-left:7px;">Name :<span><%= details.fname + " " +details.lname; %></span></td>
                <td class="text-center">INVOICE</td>
            </tr>
            <tr>
                <td>Address :<%= details.address %></td>
                <td>GSTIN   :   <span  style="padding-left:40px;">547etbdjh787jfh</span></td>
            </tr>

            <tr>
                <td></td>
                <td>Invoice No :</td>
            </tr>

             <tr>
                <td>Phone Number :<%= details.phone%></td>
                <td>Invoice Date :</td>
            </tr>

        </table>

        <table style="margin-top:11px;">
            <tr class="text-center">
                <td width="6.5%">SNo</td>
                <td width="39.5%">Description</td>
                <td width="13%">HSN</td>
                <td width="9.5%">Qty</td>
                <td width="15.5%">Rate</td>
                <td width="16%">Amount</td>
            </tr>

            <tr style="height:242px">
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>

            <tr>
                <td colspan="3"  rowspan="2">Rupees In Words : yrtyrtyrty ryrty rty rtyrtyrty ryrty</td>
                <td colspan="2" class="text-center">Taxable Value :</td>
                <td>&nbsp;</td>
            </tr>
            <tr>
                <td colspan="2" style="padding-left:30px;">SGST................%</td>
                <!--<td></td>-->
                <td>&nbsp;</td>
            </tr>

            <tr>
                <td colspan="3" rowspan="3">Terms and Conditions:</td>
                <td colspan="2" style="padding-left:30px;">SGST................%</td>
                <!--<td></td>-->
                <td>&nbsp;</td>
            </tr>

            <tr>
                <td colspan="2" style="padding-left:30px;">SGST................%</td>
                <!--<td></td>-->
                <td>&nbsp;</td>
            </tr>

            <tr>
                <td colspan="2" style="padding-left:30px;">Grand Total</td>
                <!--<td></td>-->
                <td>&nbsp;</td>
            </tr>
        </table>
    </section>     
</body>

<script>
     window.onload = function(){
        <%=
             pdf.create(html, options).toFile('public/pdf/businesscard.pdf', function(err, res) {
          if (err) {
               console.log(err);
          }
          else{console.log(res);}

        });         
        %>
    }
</script>
</html>

1 Ответ

0 голосов
/ 14 ноября 2018

Вам необходимо выполнить рендеринг на сервере, поэтому удалите скрипт window.onload и добавьте этот маленький кусочек магии к вашему app.js

app.post("/crm",function(req,res){
  console.log(req.body);
  var details = req.body;

  res.render("crm.ejs", { details: details }, function (err, html) {
    pdf.create(html, options).toFile('./public/pdf/businesscard.pdf', function (err, res) {
      if (err) {
        console.log(err);
      }
      else { console.log(res); }
    });

    res.send(html);
  });
});

Чтобы понять код, вам нужно подуматьответа вашего сервера в следующей последовательности:

  • визуализирует ejs в html строку
  • , создает pdf из строки html и сохраняет его влокальный диск
  • отправляет строку html как ответ браузеру

Вызов res.render с обратным вызовом позволяет вашему представлению быть преобразованным в строку без отправкив браузер.Это позволяет вам позвонить pdf.create в обратном вызове и затем вручную отправить ответ с res.send

Это снимок экрана с визитной карточкой, которую я смог создать, используя ваш код (что неплохо дляпуть):

card

...