node.jsvue.jswebsocketprintjs

I'm sending a generated pdf from my server to the client as a base64 pdf string. I'm trying to print it on the client side using printJS


I'm generating a report using fluentreports on my server and sending the base64 pdf string to the client on the callback. On the client once he/she receives the base64 string, I am required to print out this pdf string as a pdf which I am trying to accomplish using printJS. I also tried pdfMake but neither one wanted to work. If I console.log the base64 string and click on it, the pdf opens beautifully in the next tab but once I try to print it using printJS or pdfMake it opens a new tab and automatically closes it without doing anything. Is there any other way I could accomplish this? I've tried a lot of things already from reading up on other peoples' issues online and haven't gotten anywhere. Is there any library out there that can create a PDF document using a base64 pdf string so that I can use printJS to print out the document?

Function on the client that sends info to the server and receives back the pdf string:

submit: function () {
      this.$Socket.emit('addrepair', {
        CustomerID: this.$route.params.Customer.CustomerID,
        Problem: this.problem,
        BrandID: this.brand,
        TypeID: this.type,
        Model: this.model,
        ColorID: this.color,
        Warranty: this.convertbool(this.warranty),
        Purchased: this.convertbool(this.purchase),
        RushService: this.convertbool(this.rush),
        DateReceived: this.datereceived,
        UserID: this.UserID
      }, (data) => {
        if(data.authenticated==true)
        {
          //window.open(data.pdf)
          //pdfMake.createPdf(this.convertDataURIToBinary(data.pdf)).print()
          console.log(data.pdf)
          printJS({printable: data.pdf, type: 'pdf'})
          this.jobdialog=true
        }
      })

Function on the server that serves the pdf base64 string:

socket.on('addrepair', (data, callbackfn) => {
    let query="INSERT INTO repair(CustomerID, Problem, BrandID, Model, ColorID, Warranty, Purchased, RushService, DateReceived, TypeID, UserID) VALUES (" + data.CustomerID + ", \'" + data.Problem + "\', " + data.BrandID + ", \'" + data.Model + "\', " + data.ColorID + ", " + data.Warranty + ", " + data.Purchased + ", " + data.RushService + ", \'" + data.DateReceived + "\', " + data.TypeID + ", " + data.UserID + ");"
    con.query(query, function(err) {
      if(err) {
        throw err
      }
      else
      {
        query="SELECT RepairID, FirstName, LastName, Address, PhoneNumber, RushService, Purchased, DateReceived, Problem, Model, (SELECT Type from types WHERE repair.TypeID=types.TypeID) as Type, (SELECT Color from colors WHERE repair.ColorID=colors.ColorID) as Color, (SELECT Brand from brands WHERE repair.BrandID=brands.BrandID) as Brand, Warranty from repair INNER JOIN customer ON repair.CustomerID=customer.CustomerID WHERE repair.RepairID=(SELECT LAST_INSERT_ID())"
        con.query(query, function(err, rows) {
          if(err) {
            throw err
          }
          else
          {
            var options = {
              data: rows
            }
            //var myreport = new Report("buffer", options)
            var myreport=new Report.Report("buffer", options)
              .data(rows)
              .pageHeader(repairheaderFunction)
              .detail(repairdetailFunction)
              .pageFooter(repairfooterFunction)
            myreport.render(function (err, data) {
              callbackfn({authenticated: true, pdf: 'data:application/pdf;base64,' + data.toString('base64')})
            })
            //callbackfn({authenticated: true, data: rows})
          }
        })
      }
    })
  })

var repairheaderFunction = function(Report, data) {

};

var repairdetailFunction = function(Report, data) {
  Report.print("#" + data.RepairID, {fontSize: 22, bold: true, underline:true, align: "center"});
  Report.newLine(2);
  Report.print('First Name: ' + data.FirstName + "\n")
  Report.print('Last Name: ' + data.LastName + "\n")
  Report.print('Address: ' + data.Address + "\n")
  Report.print('Phone Number: ' + data.PhoneNumber + "\n")
  Report.print('Brand: ' + data.Brand + "\n")
  Report.print('Model: ' + data.Model + "\n")
  Report.print('Color: ' + data.Color + "\n")
  Report.print('Problem: ' + data.Problem + "\n")
  Report.print('Date Received: ' + data.DateReceived.slice(15) + "\n")
  /*.text('Last Name: [LastName]\n')
  .text('Address: [Address]\n')
  .text('Phone Number: [PhoneNumber]\n')
  .text('Brand: [Brand]\n')
  .text('Model: [Model]\n')
  .text('Color: [Color]\n')
  .text('Problem: [Problem]\n')
  .text('Date Received: [DateReceived]', 1.75, 0, 1, 0.25, {
      pattern: 'M/D/YY'
  })*/
};

var repairfooterFunction = function(Report) {
  Report.line(Report.currentX(), Report.maxY()-18, Report.maxX(), Report.maxY()-18);
  Report.pageNumber({text: "Page {0} of {1}", footer: true, align: "right"});
  Report.print("Printed: "+(new Date().toLocaleDateString()), {y: Report.maxY()-14, align: "left"});
};

Solution

  • Was able to get this to work after a lot of playing around with the code and thinking of possible solutions. Generates the iframe, pulls up the print dialog using the autoprint property of the report and then deletes the iframe once the focus is on the document again using the 'mousemove' event The code is below:

    printIframe: function(url) {
          var proxyIframe = document.createElement('iframe');
          var body = document.getElementsByTagName('body')[0];
          body.appendChild(proxyIframe);
          proxyIframe.style.width = '100%';
          proxyIframe.style.height = '100%';
          proxyIframe.id='iframe'
          proxyIframe.style.display = 'none';
    
          var contentWindow = proxyIframe.contentWindow;
          contentWindow.document.open();
    
          // Set dimensions according to your needs.
          // You may need to calculate the dynamically after the content has loaded
          contentWindow.document.write('<iframe src="' + url + '" width="1000" height="1800" frameborder="0" marginheight="0" marginwidth="0">');
          contentWindow.document.close();
          var x=0
          var func=function (event) {
            if(x===0)
            {
              body.removeChild(proxyIframe)
              ++x
            }
            else
            {
              document.removeEventListener('mousemove', func)
            }
          }
          contentWindow.document.body.onload=() => {
            contentWindow.document.body.focus()
            setTimeout(()=>{
              document.addEventListener('mousemove', func)
            }, 5000)
          }
        },