FOREST
FOREST

Reputation: 338

how to convert a buffer to pdf on front end

I used Puppeteer to generate a buffer with pdf information and send it to frontend. Here is the backend api:

exports.getPDF = async (req, res) => {
    const { content } = req.query;
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.setContent(`
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>HTML to PDF Example</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
      </head>
      <body>
        ${content}
      </body>
      </html>
      `);
    const buffer = await page.pdf();
    await browser.close();
    
    return res.apiResponse(buffer);
};

Then I tried to convert the buffer to pdf file and open it but failed, It said failed to load PDF document.

What I've done on front end:

await dispatch({
    type: 'resume/fetchResumePDF',
    payload: {
        content: resumeContent
    }
});
console.log(this.props.resumePDF);

const file = new Blob(this.props.resumePDF.data, {
    type: 'application/pdf'
});
const getFile = file && window.URL.createObjectURL(file);
window.open(getFile, "_blank");

The console.log buffer is as below:

enter image description here

Upvotes: 2

Views: 18660

Answers (3)

Shani Kehati
Shani Kehati

Reputation: 550

As mentioned here, if you're using Axios.get() on the front-end, make sure to add the { responseType: 'blob' } option:

const res = await axios.get("/api/pdf-route", 
    { responseType: 'blob' } // <----- ***
);


More info:

My back-end returns a Buffer (using "@react-pdf/renderer" package and it's renderToBuffer function)

const pdf = /* <the return value of renderToBuffer> */;
res.setHeader('Content-Type', 'application/pdf');
return res.send(pdf);

And my front-end:

const { data } = await axios.get("/api/student/pdf", 
    { responseType: 'blob' }
);

downloadPdf(data, "myFileName.pdf");

function downloadPdf(pdfBlob: Blob, filename: string) {
    const pdfBlob = new Blob([pdfBlob], { type: 'application/pdf' });
    const downloadUrl = URL.createObjectURL(pdfBlob);
    const link = document.createElement("a");
    link.href = downloadUrl;
    link.download = filename;
    link.click();
    URL.revokeObjectURL(downloadUrl);
}

Upvotes: 0

Nilebac
Nilebac

Reputation: 321

This worked for me when creating a new Blob. I was able to use Shankar's code this way.

new Blob([new Uint8Array(this.props.resumePDF.data).buffer]);

// e.g. pass the array - new Blob([new Uint8Array([1,2,3,4]).buffer]);
const url = window.URL.createObjectURL(new Blob([new Uint8Array(this.props.resumePDF.data).buffer]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'yourcoolpdf.pdf');
document.body.appendChild(link);
link.click();

Upvotes: 8

Shankar Regmi
Shankar Regmi

Reputation: 874

On the frontend, you can create ObjectURL that can be downloaded using

const url = window.URL.createObjectURL(new Blob([this.props.resumePDF]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'yourcoolpdf.pdf');
document.body.appendChild(link);
link.click();

Upvotes: 0

Related Questions