katzer / cordova-plugin-printer

Print HTML documents
Apache License 2.0
310 stars 284 forks source link

Printing base64 data in Android crashes app #272

Open skdavies opened 3 years ago

skdavies commented 3 years ago

I am trying to print baes64 data on Android. On iOS, it functions perfectly. On Android, when I try to call the plugin to print, my app crashes. This has happened on all Android phones I have tested with. Has anybody else seen this? Any solutions?

gecsafunk commented 3 years ago

same here...

Asagiqianmu commented 3 years ago

I have the same problem. Do you have a solution? Large pictures can't be printed, small pictures can.

skdavies commented 3 years ago

I used this plugin instead....

cordova-print-pdf-plugin

Far less features but it works for what I need

mahen23 commented 2 years ago

This is not an issue related to the plugin but how base64 is handled in general. There is usually a limit on how many bytes of base64 is stored. This might be why on other platforms / smaller image sizes its fine.

pradipchitrakar commented 1 year ago

One alternative you can do is try saving the base64 string to a file and then try to pass path of the file to this print function. This has worked for me. You would need cordova-plugin-file.

nicoguevara commented 1 year ago

@pradipchitrakar could you send that bit of code how you did it?

pradipchitrakar commented 1 year ago

@pradipchitrakar could you send that bit of code how you did it?

const tempFile = 'invoice.pdf'; this.file.createFile(this.file.cacheDirectory, tempFile, true).then(_ => { this.file.writeFile( this.file.cacheDirectory, tempFile, pdfBlob, {replace: true}).then(() => { this.loaderService.hideLoader(); this.printer.print(this.file.cacheDirectory + tempFile); } ).catch((err) => { //handle error }); });

You would need to convert base64 string to blob and pass it to this.file.writeFile. Here is a function to convert base64 to blob: call it like this: b64toBlob(pdfBase64String, 'application/pdf');

`b64toBlob(b64Data: string, contentType: string, sliceSize?: number) { contentType = contentType || ''; sliceSize = sliceSize || 512;

const byteCharacters = 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});

}`

nicoguevara commented 1 year ago

not work for me.

martinneumann commented 12 months ago

I'm having the same issue. Looking into PrintContent.java, I found out that the MIME type is not found correctly from some base64 PDFs. If I set it to application/pdf manually in the Java file, the preview and printing works. It's line 105 where the switch case fails.

No solution yet, but it's possible we have to encode MIME type into the base64 in case that didn't happen during conversion to base64.

DaanPepping commented 11 months ago

@martinneumann good spot, i ran into the same issue and fixed it the same way. seems like base64 PDF support isn't actually implemented. so i modified the function allowing you to pass an optional MIME type manually. i would like to pull this via npm though instead of needing to keep a modified cordova plugin in my repo...