how to export json data to pdf file with specify format with Nodejs?
Asked Answered
N

5

13

I am a beginner with nodejs. And I am writing a program, which convert text data from json file to pdf file: This is my input file (input.json)

{

"Info":

    {
    "Company": "ABC",
    "Team": "JsonNode"
    },
    "Number of members": 4,
    "Time to finish": "1 day"
}

And I want to convert it to a .pdf (report.pdf) file with following style.

  1. Info

    1.1 Company

    ABC

    1.2 Team

    JsonNode

  2. Number of members 4
  3. Time to finish 1 day

My problems are:

1: How to change style from input.json file to style of report.pdf.

2: How to convert from .json format to .pdf format.

Could anyone help me.

Thanks in advance!

Nedra answered 5/10, 2015 at 4:38 Comment(1)
There are a lot of html to pdf services. I suggest you use one of those and convert your json to formatted html. Then you can send your html/json output to their service and it will return a pdf fileVacuole
P
9

I think you have to make html template and then render your json into html template.

 <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<table> 
<tr>Company</tr>
{{info.Company}}
<tr>Team</tr>
{{info.Team}}
</table>
</body>
</html>

Now On your js file you have to give path of your template and also create a folder in order to store your pdf file.

     var pdf = require('html-pdf');
 var options = {format: 'Letter'};
exports.Topdf = function (req, res) {
 var info = {

 "Company": "ABC",
 "Team": "JsonNode",
 "Number of members": 4,
"Time to finish": "1 day"
}
res.render('path to your tempalate', {
    info: info,
}, function (err, HTML) {
    pdf.create(HTML, options).toFile('./downloads/employee.pdf', function (err, result) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        }
    })
  })
 }

Try with this hope it works.

Pratt answered 5/10, 2015 at 5:1 Comment(7)
@Vishnu: Yes, I already corrected it , but it still didn't workNedra
I meet this issue: res.render('./template.html', { ^ TypeError: Cannot read property 'render' of undefinedNedra
Hi @MariyaJames . I did as your guide, but maybe having something abnormal with my method: I use your .js code and save it as (test.js) then I make another .js file (test1.js) with content as follow: var test = require("./test.js"); test.topdf(); After that I run test1.js file. "node test1.js". the issue above still happens, Could you please give me a suggestion in more detail. and how did you run the .js code?Nedra
app.get('/', test.topdf()); As i told you if you are using express you have to call function using routes. as i shown here. Then only you will have req,res object. Try to expressjs.com/guide/routing.htmlPratt
Thank you very much. I did same way as ur guide I code work well !Nedra
Hi, How to pass the api url to get the report instead of hard codePlovdiv
hi @MariyaJames I tried your answer but info not populating in html the output : Company {{info.Company}} Team {{info.Team}}Leontine
J
2

You have to create the layout using html as,

<ul>
 <li>Info: </li>
 <ul>
  <li>Company: {{info.Company}}</li>
  <li>Team: {{info.Team}}</li>
 </ul>
 <li>Number of members: {{info.numberofmembers}}</li>
 <li>Time to finish: {{info.timetofinish}}</li>
<ul>

Now you have to store this html in a variable say "layout". Then create the pdf as,

function generatePdf(layout, file) {
console.log('generating pdf');

var wkhtmltopdf = require('wkhtmltopdf');

wkhtmltopdf(html, {
    output: file,
    "viewport-size": "1280x1024",
    "page-width": "400",
    "page-height": "600"
});
}

Where file is the path where you want to save your file.

Joesphjoete answered 5/10, 2015 at 6:11 Comment(5)
Thank you very much @Akshay Kumar. But I have some more questions: 1: How to declare variable "layout" and use it in .js file? 2: How to html layout use data from .json file ( when I change the content of json file, content of html also auto change follow it)? 3: How to creat a stype exactly same as style in my report.pdf file ( which was post in question above)? I only work with C/C++ before, I have just used nodejs,html two days ago so could you please answer more detail and complete your code will more useful to me.Nedra
In .js just declare the variable asJoesphjoete
In .js just declare the variable as var = "<ul><li>Info: </li<ul><li>Company: {{info.Company}}</li><li>Team: {{info.Team}}</li></ul> <li>Number of members: {{info.numberofmembers}}</li> <li>Time to finish: {{info.timetofinish}}</li><ul>". Read about parsing json data and construct the html as a string. For the numbering on points you can use "<ol>" tags in place of "<ul>" tags.Joesphjoete
When I run .js file. I didn't see log "generating pdf"(no error log also). It mean it doesn't go into function generatePdf. Do you know what is problem here?Nedra
Let us continue this discussion in chat.Joesphjoete
O
2

I was able to solve this question by converting JSON to PDF directly without converting to HTML first by using jsPDF.

Code:

jsonData = {
    "Info":{
       "Company":"ABC",
       "Team":"JsonNode"
    },
    "Number of members":4,
    "Time to finish":"1 day"
 }

var pdf2 = new jsPDF();
var i = 1;
var row = 1;
for(data in jsonData){
    var j = 1;
    if(typeof(jsonData[data]) === 'object' && jsonData[data] !== null){
        for(innerData in jsonData[data])
        {
            pdf2.text(i + ". " + data, 10, 20 + (row*10));
            if(jsonData[data][innerData] !== undefined){
                row = row+1;
                pdf2.text(i + "." + j+ innerData, 10, 20 + (row*10));
                row = row+1;
                pdf2.text(jsonData[data][innerData], 10, 20 + (row*10));
                j=j+1;
            }
            row = row+1;
        }
    }
    else {
        pdf2.text(i + ". " + data + " " + jsonData[data].toString(), 10, 20 + (row*10));
    }
    row=row+1;
    i = i+1;
}
pdf2.save('Stackoverflow.pdf');

To install jsPDF: npm install jspdf --save.

Reference: https://www.npmjs.com/package/jspdf

Hope this helps someone! :)

Snapshot of generated PDF: enter image description here

Olly answered 7/10, 2022 at 10:40 Comment(0)
S
0

There are many solutions saying first convert into html and then to pdf but instead one can directly generate pdf using "pdfmake" or "pdfkit" library. I've used it and its very good library. pdfkit is the parent library over which pdfmake has been made. pdfmake is very simple library compared to pdfkit (this is what I feel). pdfmake lacks some features like bookmarks and toc(table of content header) linkage to respective page.

pdfmake: https://pdfmake.github.io/docs/

pdfkit: http://pdfkit.org/docs/getting_started.html

Showker answered 6/3, 2019 at 11:28 Comment(0)
U
-1

const pdfStream = (renderedDocument) => {
    pdf.create(renderedDocument, options).toStream((err, pdfDoc) => {
        if (err) {
            console.log(
                `failed to render PDF, err: ${err}`
            );
            res.status(res.statusCode).json({
                status: "failed",
                data: err,
                message: "something broke failed generate pdf",
                user_message: "Failed to generate pdf",
                url: req.url,
                method: req.method,
                code: res.statusCode,
            });
            return;
        }
        // Make sure the browser knows this is a PDF.
        res.set("content-type", "application/pdf");
        pdfDoc.pipe(res);
        // once we are done reading end the response
        pdfDoc.on("end", () => {
            // done reading
            return res.end();
        });
    });
};

await res.render(templatePath, dataToPrinted, (err, htmlRender) => {
    if (err) {
        console.log(
            `failed to render PDF, err: ${err}`
        );
        res.status(res.statusCode).json({
            status: "failed",
            data: err.message,
            message: "something broke failed render advance docs",
            user_message: "Something isn’t working",
            url: req.url,
            method: req.method,
            code: res.statusCode,
        });
        return;
    }
    pdfStream(htmlRender);
});
Undertake answered 14/7 at 4:24 Comment(1)
Thank you for posting this answer. While this code may answer the question, might you please edit your post to add an explanation as to why/how it works? This can help future readers learn and apply your answer. You are also more likely to get positive feedback (upvotes) when you include an explanation.Grecian

© 2022 - 2024 — McMap. All rights reserved.