0

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"});
};
Jeffrey penner
  • 155
  • 1
  • 4
  • 17

2 Answers2

1

Print.js is now supporting base64 PDF print.

Try this:

printJS({
  printable: your_base64_data_string,
  type: 'pdf'
  base64: true
})

The documentation has been updated with an example printing a base64 PDF document. http://printjs.crabbly.com#pdf

crabbly
  • 5,106
  • 1
  • 23
  • 46
  • I tried this as well a little while ago as I went through a couple of blogs. I think something might be wrong with the way I import printJS because it doesn't print anything – Jeffrey penner May 16 '19 at 14:37
  • @Jeffreypenner I just updated the answer with a link for an example in the docs. It should work as expected. Make sure you are running its latest version: `npm update print-js` – crabbly May 20 '19 at 17:03
0

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)
      }
    },
Jeffrey penner
  • 155
  • 1
  • 4
  • 17