Is it possible to use jsreportonline api in node and save pdf instead of triggering download
-
Hi All,
I now have a google function that triggers a download to the browser. I'm looking if it is possible to instead create a function that downloads and stores the pdf file on google cloud storage.
- Is this possible with jsreportonline or do i need to run my own server?
- Can i use jsreport-client in combination with jsreportonline server and how do i authenticate etc?
- Or can i just adjust my existing code so that instead of triggering a browser download i get a stream that i can save to disk or something?
I'm now doing this which is working bu i rather save the pdf on the server without triggering the download:
export const generatePdf = async (req: any, res: any) => { try { const data = { template: { shortid: 'XXX' }, data: {test: 'test'}, options: {'Content-Disposition': `attachment; filename=test.pdf`} }; const options = { method: 'POST', headers: { 'Authorization': 'Basic xxxxxxx', 'Content-Type': 'application/json', }, uri: 'https://xxx.jsreportonline.net/api/report', json: data }; request(options).pipe(res); } catch(err) { console.log(`Error creating pdf ${err} `) return res.sendStatus(500) } }
Thanks,
Mark
-
hi!
Is this possible with jsreportonline or do i need to run my own server?
yes, this is possible with both jsreportonline and your own server
Can i use jsreport-client in combination with jsreportonline server and how do i authenticate etc?
yes, you can use jsreport nodejs client with jsreportonline too, using it will look something like this:
// instead of "https://bjrmatos9.jsreportonline.net/" put here the URL of your jsreportonline account, and your credentials const client = require('jsreport-client')('https://bjrmatos9.jsreportonline.net/', 'admin', 'password') client.render({ ...your options here... }).then((response) => { // response is a stream, you can use it and save it to disk response.pipe(fs.createWriteStream('/some/path/to/store.pdf')) }).catch((err) => console.error(err))
Or can i just adjust my existing code so that instead of triggering a browser download i get a stream that i can save to disk or something?
i think you just need to change this part of your code
request(options).pipe(res);
to this
request(options).pipe(fs.createWriteStream('/some/path/to/store.pdf'))
of course if this is your production code, make sure to add correct error handling when handling the streams
-
Thanks a lot!
For anyone who want to try it on firebase
import * as functions from 'firebase-functions' import * as admin from 'firebase-admin' admin.initializeApp() import * as express from 'express' import * as path from 'path' import * as jsreport from 'jsreport-client' const app = express() const jsreportAdmin = functions.config().jsreport.admin; const jsreportPassword = functions.config().jsreport.password; const client = new jsreport('https://xxxxx.jsreportonline.net/', jsreportAdmin, jsreportPassword); const generatePdf = async () => { const response = await client.render({ template: { shortid: 'xxxxx' }, data: { name: 'dasdasd'}, }) const metadata = { contentType: 'application/pdf' }; const bucket = admin.storage().bucket(); const fileName = `test.pdf`; const filePath = path.join(path.dirname('/test'), fileName); // Create upload stream const uploadStream = bucket.file(filePath).createWriteStream({metadata}); response.pipe(uploadStream); return new Promise((resolve, reject) => uploadStream.on('finish', resolve).on('error', reject)); } app.get('/generate', async (req, res) => { try { await generatePdf(); return res.status(200).json({}); } catch (error) { console.error(error); return res.sendStatus(500); } }); exports.app = functions.https.onRequest(app);