下载的 PDF 虽然包含一些数据,但看起来是空的 [英] Downloaded PDF looks empty although it contains some data

查看:66
本文介绍了下载的 PDF 虽然包含一些数据,但看起来是空的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 JavaScript 实现 PDF 文件下载功能.
作为对 POST 请求的响应,我得到一个 PDF 文件,在 Chrome DevTools 控制台中它看起来像(oResult 数据容器,片段):

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

"%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();

结果,点击一个按钮我得到tstPDF.pdf,它包含正确的页数,但PDF本身是空的,没有显示任何内容,虽然它是6知识库.

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.

当我测试生成 PDF 的 Java 服务器端模块时,一切正常,它通过 ServletOutputStream 发送 InputStream.因此,我假设问题出在客户端的某个地方,可能是 MIMEBLOBencoding 或类似的问题.

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.

您知道为什么生成的 PDF 不显示任何数据吗?

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

推荐答案

我解决了这个问题.问题在于数据从服务器传送到客户端的方式.确保服务器以 Base64 编码发送数据至关重要,否则客户端无法将 PDF 字符串反序列化回二进制格式.您可以在下面找到完整的解决方案.

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.

服务器端:

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();

客户端:

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();

参考主题:

在 JavaScript 中从字节下载文件

这篇关于下载的 PDF 虽然包含一些数据,但看起来是空的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆