3

I have a page that includes a download button using jsPDF. On desktop machines it downloads the page as it should. However, pdf.save() does not work on my tablet or phone.

I tried to add a special case for mobile devices to open the PDF in a new window, since mobile devices don't download things the same as desktops, with the idea being that once the PDF is open in a new window the user can choose to save it manually.

var pdf = new jsPDF('p', 'pt', 'letter');
var specialElementHandlers = {
    '#editor': function (element, renderer) {
        return true;
    }
};

html2canvas($("#pdf-area"), {
    onrendered: function (canvas) {
        $("#pdf-canvas").append(canvas);
        $("#pdf-canvas canvas").css("padding", "20px");
    }
});

var options = {
    pagesplit: true
};

function download(doctitle) {
    pdf.addHTML($("#pdf-area")[0], options, function () {
        if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
            pdf.output('dataurlnewwindow');           
        } else {
            pdf.save(doctitle);
        }        
    });
}

But the download function still does nothing on my tablet/phone. I tested it with this to make sure the pdf.output() function was working:

    pdf.addHTML($("#pdf-area")[0], options, function () {
        pdf.output('dataurlnewwindow');                
    });

and it does still work on desktop, but does nothing on mobile.

Madness
  • 2,730
  • 3
  • 20
  • 29
Erica Stockwell-Alpert
  • 4,624
  • 10
  • 63
  • 130

5 Answers5

5

jsPDF won't download files on mobile apps by this pdf.save(). I have tried and searched for this issue but could not find a complete solution in one place. I am using the file and file-opener plugin. I have developed the solution in Ionic React. Install below modules.

npm i jspdf
npm install cordova-plugin-file
npm install @ionic-native/file
npm install cordova-plugin-file-opener2
npm install @ionic-native/file-opener
ionic cap sync
  1. Go to your file and add these import statements.

import { jsPDF } from "jspdf";
import 'jspdf-autotable';
import { FileOpener } from '@ionic-native/file-opener;
import { File } from '@ionic-native/file';
import { isPlatform } from "@ionic/react";
  1. Check the pdfDownload function

const pdfDownload = async () => {
var doc = new jsPDF();
doc.setFontSize(40);
doc.text("Example jsPDF", 35, 25)
let pdfOutput = doc.output();
    if (isPlatform("android")) {
      // for Android device
      const directory = File.externalRootDirectory + 'Download/';
      const fileName = `invoice-${new Date().getTime()}.pdf`
      File.writeFile(directory, fileName, pdfOutput, true).then(succ => {
        FileOpener.showOpenWithDialog(directory + fileName, 'application/pdf')
          .then(() => console.log('File opened'))
          .catch(error => console.log('Error opening file', error));
      },
        err => {
          console.log(" writing File error : ", err)
        })
    } else if (isPlatform("ios")) {
      // for iOS device
      console.log('ios device')
      const directory = File.tempDirectory;
      const fileName = `invoice-${new Date().getTime()}.pdf`
      File.writeFile(directory, fileName, pdfOutput, true).then(success => {
        FileOpener.showOpenWithDialog(directory + fileName, 'application/pdf')
          .then(() => console.log('File opened'))
          .catch(e => console.log('Error opening file', e));
      },
        err => {
          console.log(" writing File error : ", err)
        })
    } else {
      // for desktop
      doc.save("invoice.pdf");
    }

}
Ankit Kumawat
  • 371
  • 5
  • 13
1

I had similar issue.

jsPDF won't download file on phones/ tablets / ipads using "pdf.save()".

Do it through File plugin if you are using cordova/phonegap, this will save pdf file in downloads folder (Android) - for the ios you can access pdf file through a path (which is saved somewhere in temp directory) and can send or share.

Hope this helps you.

user5091906
  • 166
  • 10
1

Here is the solution of download on mobile with jspdf

if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent))
{
     var blob = pdf.output();
     window.open(URL.createObjectURL(blob));
}
else
{
     pdf.save('filename.pdf');
}
vishuB
  • 4,173
  • 5
  • 31
  • 49
  • 1
    Gives error: `[Vue warn]: Error in v-on handler (Promise/async): "TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed."` – geoidesic Jul 13 '21 at 13:35
  • 1
    Received `Uncaught TypeError: Blob constructor: Argument 1 can't be converted to a sequence.` Solved it with this: `window.open(URL.createObjectURL(new Blob([blob])))` – bloodyKnuckles Mar 09 '22 at 23:58
1

Here is the example if you're using the Cordova platform for your development:

https://github.com/saharcasm/Cordova-jsPDF-Email

The workaround of the pdf not being downloaded in the devices is to use cordova-plugin-file.

Use the output method on the doc that will give you the raw pdf which needs to be written & saved in a file.

For example,

var doc = new JsPDF(); 
//... some work with the object
var pdfOutput = doc.output("blob"); //returns the raw object of the pdf file

The pdfOutput is then written on an actual file by using the file plugin.

Saharcasm
  • 148
  • 1
  • 8
0

The easiest way which works on both Desktop and Mobile is to use:

window.open(doc.output("bloburl"), "_blank");

Osama Sayed
  • 1,993
  • 15
  • 15