Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downloaded PDF looks empty although it contains some data

I'm trying to implement a PDF file download functionality with JavaScript.
As a response to a POST request I get a PDF file, in Chrome DevTools console it looks like (the oResult data container, fragment):

"%PDF-1.4↵%����↵4 0 obj↵<>stream↵x��

Now I'm trying to initialize the download process:

let blob = new Blob([oResult], {type: "application/pdf"});

let link = document.createElement('a');

link.href = window.URL.createObjectURL(blob);
link.download = "tstPDF";

link.click();

As a result, upon a click on a button I get tstPDF.pdf, it contains the correct number of pages, but the PDF itself is empty, no content is displayed, although it is 6 KB.

When I test the Java server-side module, which generates the PDF, everything is working fine, it sends InputStream through ServletOutputStream. Thus I assume that the issue is somewhere on a client side, perhaps something with MIME, BLOB, encoding, or similar.

Do you have any idea why the generated PDF doesn't display any data?

like image 208
Mike Avatar asked Aug 23 '18 08:08

Mike


People also ask

Why does my PDF document appear blank?

This error occurs when an object in the PDF document is incomplete, or when an object is missing a key element. Frequently, the error occurs when the Web server does not download enough of the object to make it usable.

How do you fix a blank PDF?

In Adobe Acrobat Reader, use Edit > Preferences > Internet > "Display PDF in browser" option to force PDF file to open in Acrobat Reader rather than in the browser. If the PDF is blank when opened in the browser, opening that in Acrobat Reader should fix this problem.

Why is my PDF showing up blank in Chrome?

Instead of opening the PDF file, Chrome PDF Viewer might display a black screen similar to the one that appears when a PDF is loading. If this is the case, you might have a poor internet connection, or there is an incompatible third-party extension. Before changing Chrome's settings, check your internet connection.

Why are PDFs blank on my iPhone?

If you're trying to open a PDF on an iPad or iPhone and it appears blank, you need to set Adobe Reader as your default for opening PDF files on your device. 💡Tip: Select the Preview icon to quickly preview PDFs without downloading them.


1 Answers

I solved the issue. The problem was in a way the data is delivered from the server to the client. It is critical to assure that the server sends the data in Base64 encoding, otherwise the client side can't deserialize the PDF string back to the binary format. Below, you can find the full solution.

Server-side:

OutputStream pdfStream = PDFGenerator.pdfGenerate(data);

String pdfFileName = "test_pdf";

// represent PDF as byteArray for further serialization
byte[] byteArray = ((java.io.ByteArrayOutputStream) pdfStream).toByteArray();

// serialize PDF to Base64
byte[] encodedBytes = java.util.Base64.getEncoder().encode(byteArray);

response.reset();
response.addHeader("Pragma", "public");
response.addHeader("Cache-Control", "max-age=0");
response.setHeader("Content-disposition", "attachment;filename=" + pdfFileName);
response.setContentType("application/pdf");

// avoid "byte shaving" by specifying precise length of transferred data
response.setContentLength(encodedBytes.length);

// send to output stream
ServletOutputStream servletOutputStream = response.getOutputStream();

servletOutputStream.write(encodedBytes);
servletOutputStream.flush();
servletOutputStream.close();

Client side:

let binaryString = window.atob(data);

let binaryLen = binaryString.length;

let bytes = new Uint8Array(binaryLen);

for (let i = 0; i < binaryLen; i++) {
    let ascii = binaryString.charCodeAt(i);
    bytes[i] = ascii;
}

let blob = new Blob([bytes], {type: "application/pdf"});

let link = document.createElement('a');

link.href = window.URL.createObjectURL(blob);
link.download = pdfFileName;

link.click();

Reference topics:

  • How to convert a PDF generating in response.outputStream to a Base64 encoding

  • Download File from Bytes in JavaScript

like image 55
Mike Avatar answered Sep 21 '22 13:09

Mike