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


  • administrators

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

Log in to reply
 

Looks like your connection to jsreport forum was lost, please wait while we try to reconnect.