Byka
Byka

Reputation: 87

how can we display the PDF from base 64 string in Cordova.inappbrowser in Android

My requirement is to display the pdf base64 string in cordova.InAppBrowser it's not displaying in Android

But it's displaying in iOS application. I am using the below code to display the PDF in InAppBrowser

$scope.urlString = "data:application/pdf;base64,"+encodeURI($scope.PdfString);
var ref = cordova.InAppBrowser.open($scope.urlString, '_blank',  'toolbarposition=bottom');

Does anybody know how I can display the PDF base64 string in Cordova InAppBrowser? or is there any alternative way to display.

Upvotes: 3

Views: 7001

Answers (4)

Piero Alberto
Piero Alberto

Reputation: 3943

In my case the Byka's answer worked only for Android. I edited it and now it works like charms also in iOS. My app downloads a pdf base64 encoded, converts and opens it.

The problem was open the file in iOS, solved adding the file opener2 plugin

function 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;
}

function savebase64AsPDF(folderpath, filename, content, contentType) {
    // Convert the base64 string in a Blob
    var DataBlob = b64toBlob(content, contentType);
    window.resolveLocalFileSystemURL(folderpath, function (dir) {
        dir.getFile(filename, { create: true }, function (file) {
            file.createWriter(function (fileWriter) {
                fileWriter.write(DataBlob);
                var finalPath = folderpath + filename;
                //window.open(finalPath, '_system');
                cordova.plugins.fileOpener2.open(finalPath, 'application/pdf'
                    //,
                    //{
                    //    error: function (e) {
                    //        alert('Error status: ' + e.status + ' - Error message: ' + e.message);
                    //    },
                    //    success: function () {
                    //        alert('file opened successfully');
                    //    }
                    //}
            );

            }, function () {
                alert("err");
        });
    });
}

function PrintFile(id) {
            jQuery("#large-indicator").css("display", "inline");
            $.ajax({
                type: "POST",
                contentType: "application/json",
                dataType: "json",
                url: "myurl",
                data: JSON.stringify({
                    "id": id
                }),
                success: function (Response) {
                    jQuery("#large-indicator").css("display", "none");
                    var contentType = "application/pdf";
                    var folderpath = cordova.file.externalRootDirectory;
                    if (folderpath == null)
                        folderpath = cordova.file.dataDirectory
                    var filename = id + ".pdf";
                    savebase64AsPDF(folderpath, filename, Response.value, contentType);
                },
                error: function (Response) {
                    jQuery("#large-indicator").css("display", "none");
                    var mex = Response["responseText"];
                    alert(mex);
                }
            });
}

Upvotes: 1

Ezequiel Garc&#237;a
Ezequiel Garc&#237;a

Reputation: 2776

just to complement the solution of @Byka we should install this in ionic 3

  1. ionic cordova plugin add cordova-plugin-file
  2. npm install --save @ionic-native/file
  3. ionic cordova plugin add cordova-plugin-file-opener2
  4. npm install --save @ionic-native/file-opener

Important for some reason the writeFile from file does not work so edit your index.html

you should included before your cordova.js

      <script src="build/polyfills.js"></script>

add the plugins to your app's module

import { File } from '@ionic-native/file' import { FileOpener } from '@ionic-native/file-opener'

added in providers as well

providers: [ ..... File, FileOpener ]

import { Component } from '@angular/core'
import { NavController, NavParams, Platform } from 'ionic-angular'
import { InAppBrowser } from '@ionic-native/in-app-browser'
import { File } from '@ionic-native/file'
import { FileOpener } from '@ionic-native/file-opener'

@Component({
  selector: 'page-pantalla-mi-promenal-consultas',
  templateUrl: 'pantalla-mi-promenal-consultas.html'
})
export class YourPage {
 

  constructor(
    public navCtrl: NavController,
    public navParams: NavParams,
    private platform: Platform,
    private file: File,
    private fileOpener: FileOpener
  ) {}

  getUserDataSheet() {
          const blob = this.b64toBlob(pdfString, 'application/pdf', 512)
          let pathFile = ''
          const fileName = 'myPdf.pdf'
          const contentFile = blob
          if (this.platform.is('ios')) {
            pathFile = this.file.documentsDirectory
          } else {
            pathFile = this.file.externalRootDirectory
          }
          this.file
            .writeFile(pathFile, fileName, contentFile, { replace: true })
            .then(success => {
              this.fileOpener
                .open(pathFile + fileName, 'application/pdf')
                .then(data => {
                  this.inAppBrowser.create(data, '_system')
                })
                .catch(e => console.log('Error opening file', e))
            })
            .catch(e => console.log('Error writing file', e))
        }
  }

  b64toBlob(b64Data, contentType, sliceSize = 512) {
    contentType = contentType || ''
    sliceSize = sliceSize || 512
    b64Data = b64Data.replace(/^[^,]+,/, '')
    b64Data = b64Data.replace(/\s/g, '')

    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 byteCharacters;
    return blob
  }
}

Upvotes: 1

Maheshvirus
Maheshvirus

Reputation: 7543

This is how i achieved for Android & IOS. Cheers!!

Use this plugins

<plugin name="cordova-plugin-inappbrowser" />
<plugin name="cordova-plugin-file"/>
<plugin name="cordova-plugin-file-transfer"/>
<plugin spec="https://github.com/tectronik/cordova-plugin-file-opener2-tectronik.git"/>

Working code for you.

    var blob = b64toBlob("base64 string here", 'application/pdf');
    var pathFile = "";
    var fileName ='PdfName.pdf';
    var contentFile = blob;
    if (ionic.Platform.isIOS()) {
        var pathFile = cordova.file.documentsDirectory
    } else {
        var pathFile = cordova.file.externalRootDirectory
    }

    $cordovaFile.writeFile(pathFile, fileName, contentFile, true)
        .then(function(success) {
            $scope.filePath=pathFile + fileName;
            // console.log("File saved on internal storage location," + pathFile + fileName);

        if (ionic.Platform.isAndroid()) {
            $cordovaFileOpener2.open($scope.filePath,
                'application/pdf'
                ).then(function() {
                    // file opened successfully
                    // alert(' file opened successfully')
                }, function(err) {
                    alert('An error occurred '+err);
                });
        }else{
            var ref = cordova.InAppBrowser.open(data, '_blank', 
    'location=no,toolbar=yes');
        }    
}, function(error) {

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

        b64Data = b64Data.replace(/^[^,]+,/, '');
        b64Data = b64Data.replace(/\s/g, '');

        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 byteCharacters;
        return blob;
    }

Upvotes: 0

Byka
Byka

Reputation: 87

Finally got the solution We need to have the cordova-file-plugin in our project

cordova plugin add cordova-plugin-file

var myBase64 = "JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwogIC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAvTWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0KPj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAgL1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9udAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2JqCgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJUCjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVuZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4gCjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAwMDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9vdCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G";
// To define the type of the Blob
var contentType = "application/pdf";
// if cordova.file is not available use instead :
// var folderpath = "file:///storage/emulated/0/";
var folderpath = cordova.file.externalRootDirectory;
    var filename = "helloWorld.pdf";

    savebase64AsPDF(folderpath,filename,$scope.PdfString,contentType);

function 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;
}
    function savebase64AsPDF(folderpath,filename,content,contentType){
        // Convert the base64 string in a Blob
        var DataBlob = b64toBlob(content,contentType);

        console.log("Starting to write the file :3");

        window.resolveLocalFileSystemURL(folderpath, 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(DataBlob);
                    console.log("Folder Path"+folderpath+filename);
                    var finalPath = folderpath+filename;
                     window.open(finalPath, '_system');

                }, function(){
                    alert('Unable to save file in path '+ folderpath);
                });
    		});
        });
    }

Upvotes: 3

Related Questions