nfont
nfont

Reputation: 99

Base64 to PDF Cordova Ionic v2

I want to download a PDF file in cordova app. I recive a base64 string that is that PDF.

I tried the next code using cordova-plugin-file and cordova-plugin-file-opener2:

openPDF(invoice) {
    this.saveAndOpenPdf(invoice['base64'], 'invoice.pdf');
}

saveAndOpenPdf(pdf: string, filename: string) {
    const load = this.loadingCtrl.create({
        content: this.translate.instant("app.loading"),
        dismissOnPageChange: true
    });
    load.present();
    var writeDirectory = this.platform.is('ios') ? this.file.dataDirectory : this.file.externalRootDirectory;
    console.log(writeDirectory);
    var self = this;
    this.checkPermissions()
        .then(() => {
            var res = this.b64toBlob(pdf, 'aplication/pdf', 512);
            console.log(res);
            ( < any > window).resolveLocalFileSystemURL(writeDirectory, function(dir) {
                console.log("Access to the directory granted succesfully");
                dir.getFile(filename, {
                    create: true
                }, function(file) {
                    console.log("File created succesfully.");
                    file.createWriter(function(fileWriter) {
                        console.log("Writing content to file");
                        fileWriter.write(res);
                        self.opener.open(writeDirectory + filename, 'application/pdf').then(() => {
                                load.dismiss();
                            })
                            .catch((err) => {
                                console.error(err);
                                console.log('Error opening pdf file');
                                load.dismiss();
                            });

                    }, function() {
                        load.dismiss();
                        alert('Unable to save file in path ' + writeDirectory);
                    });
                });
            });
        }).catch((error) => {
            load.dismiss();
            console.log(error);
        });
}

b64toBlob(b64Data, contentType, sliceSize) {
    contentType = contentType || '';
    sliceSize = sliceSize || 512;

    var byteCharacters = atob(b64Data);
    var byteArrays = [];

    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        var slice = byteCharacters.slice(offset, offset + sliceSize);

        var byteNumbers = new Array(slice.length);
        for (var i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        var byteArray = new Uint8Array(byteNumbers);

        byteArrays.push(byteArray);
    }

    var blob = new Blob(byteArrays, {
        type: contentType
    });
    return blob;
}

It seems that works well but when the opener try to open the PDF it fails and PDF size is 0B. (ONLY IN ANDROID)

What am I doing wrong?

PD: This is the example code: https://ourcodeworld.com/articles/read/230/how-to-save-a-pdf-from-a-base64-string-on-the-device-with-cordova

ADDED:

Also I tried the solution explained in this post: https://stackoverflow.com/a/49137874/8228843

In those cases, in android, only in android, the file.writeFile function did nothing. The promise did not work and the then () code was not executed, nor was it the catch () code. It is important to note that there is no error either in the console or in the logcat.

Code of solution in the post explained:

saveAndOpenPdf(pdf: string, filename: string) {
  const writeDirectory = this.platform.is('ios') ? this.file.dataDirectory : this.file.externalDataDirectory;
  this.file.writeFile(writeDirectory, filename, this.convertBase64ToBlob(pdf, 'data:application/pdf;base64'), {replace: true})
    .then(() => {
        this.loading.dismiss();
        this.opener.open(writeDirectory + filename, 'application/pdf')
            .catch(() => {
                console.log('Error opening pdf file');
                this.loading.dismiss();
            });
    })
    .catch(() => {
        console.error('Error writing pdf file');
        this.loading.dismiss();
    });
}

convertBaseb64ToBlob(b64Data, contentType): Blob {
    contentType = contentType || '';
    const sliceSize = 512;
    b64Data = b64Data.replace(/^[^,]+,/, '');
    b64Data = b64Data.replace(/\s/g, '');
    const byteCharacters = window.atob(b64Data);
    const byteArrays = [];
    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
         const slice = byteCharacters.slice(offset, offset + sliceSize);
         const byteNumbers = new Array(slice.length);
         for (let i = 0; i < slice.length; i++) {
             byteNumbers[i] = slice.charCodeAt(i);
         }
         const byteArray = new Uint8Array(byteNumbers);
         byteArrays.push(byteArray);
    }
   return new Blob(byteArrays, {type: contentType});
}

Upvotes: 1

Views: 1104

Answers (0)

Related Questions