Base64 в PDF Cordova Ionic v2 - PullRequest
       39

Base64 в PDF Cordova Ionic v2

1 голос
/ 07 марта 2019

Я хочу скачать файл PDF в приложении Cordova. Я получаю строку base64, которая является тем PDF.

Я попробовал следующий код, используя cordova-plugin-file и 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;
}

Кажется, это работает хорошо, но когда открыватель пытается открыть PDF-файл, он терпит неудачу, и размер PDF-файла равен 0B. ( ТОЛЬКО В АНДРОИДЕ )

Что я делаю не так?

PD: это пример кода: https://ourcodeworld.com/articles/read/230/how-to-save-a-pdf-from-a-base64-string-on-the-device-with-cordova

ДОБАВЛЕНО:

Также я попробовал решение, объясненное в этом посте: https://stackoverflow.com/a/49137874/8228843

В этих случаях в android, только в android, функция file.writeFile ничего не делала. Обещание не сработало, и код then () не был выполнен, равно как и код catch (). Важно отметить, что нет ошибок ни в консоли, ни в logcat.

Код решения в посте пояснил:

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});
}
...