PDF.JS:使用 ArrayBuffer 或 Blob 而不是 URL 呈现 PDF [英] PDF.JS: Render PDF using an ArrayBuffer or Blob instead of URL
问题描述
我知道一个与此类似的问题:Pdf.js:使用 base64 文件源而不是 url 呈现 pdf 文件.Codetoffel 很好地回答了这个问题,但我的问题不同,我的 PDF 是通过对 Web API 的 RESTful 调用检索的执行.让我解释一下...
I know of a similar question to this one: Pdf.js: rendering a pdf file using a base64 file source instead of url. That question was awesomely answered by Codetoffel but my question is different in that my PDF is retrieved via a RESTful call to my Web API implementation. Let me explain...
首先,这是使用 PDF.JS 通过 URL 打开 PDF 的基本方法:
First, here's a basic way to use PDF.JS to open a PDF via a URL:
PDFJS.getDocument("/api/path/to/my.pdf").then(function (pdf) {
pdf.getPage(1).then(function (page) {
var scale = 1;
var viewport = page.getViewport(scale);
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({canvasContext: context, viewport: viewport});
});
});
这很好用,但我使用 Angular 及其 $resource
服务通过我的 RESTful Web API 请求 PDF.我确实知道 PDF.JS 允许我用一个 DocumentInitParams
对象(定义为 这里.使用 DocumentInitParams 对象的工作方式如下:
This works great, but I am using Angular and its $resource
service to make the request for the PDF via my RESTful Web API. I do know that PDF.JS allows me to replace passing the URL as a string in the PDFJS.getDocument method (above) with a DocumentInitParams
object, which is defined here. Using the DocumentInitParams object works as follows:
var docInitParams = {
url: "/api/path/to/my.pdf",
httpHeaders: getSecurityHeaders(), //as needed
withCredentials: true
};
PDFJS.getDocument(docInitParams).then(function (pdf) {
...
});
这也有效,但它通过要求我构建 api URL 来解决我的 Angular $resource
.但这没关系,因为 PDFJS 允许我直接给它 PDF 数据,而不是给它一个 PDF 的 URL,如下所示:
This also works, but it works around my Angular $resource
by requiring me to construct the api URL. But that's OK because PDFJS allows me to give it the PDF data directly, instead of giving it a URL to the PDF, as follows:
var myPdf = myService.$getPdf({ Id: 123 });
//It's an Angular $resource, so there is a promise to be fulfilled...
myPdf.$promise.then(function() {
var docInitParams = {
data: myPdf
};
PDFJS.getDocument(docInitParams).then(function (pdf) {
...
});
});
这是我似乎无法开始工作的地方.我可以告诉 myService.$gtPdf
方法将数据作为 blob
或作为 arraybuffer
返回,但两者都不起作用.我也尝试将 arraybuffer 返回的数据转换为 Uint8Array
,但无济于事.
This is the one I can't seem to get to work. I can tell the myService.$gtPdf
method to return the data as a blob
or as an arraybuffer
but neither works. I've tried to convert the arraybuffer returned data to an Uint8Array
too, but to no avail.
我不知道还能尝试什么,真的可以使用小费.
I'm not sure what else to try and could really use a tip.
如何获取从我的服务返回的数据以使用 PDFJS?
提前致谢.
推荐答案
您不是将响应数据传递给 PDF.js,而是资源的一个实例:
You're not passing the response data to PDF.js, but an instance of the resource:
var myPdf = myService.$getPdf({ Id: 123 });
myPdf.$promise.then(function() {
var docInitParams = {
data: myPdf
您还没有显示 $getPdf
的代码,但我想它相当于
You haven't shown your code for $getPdf
, but I guess that it is something equivalent to
var myService = $resource('/foo', {}, {$getPdf:{responseType: 'arraybuffer'}});
var myPdf = myService.$getPdf();
默认情况下,AngularJS $resource
将响应视为一个对象(从 JSON 反序列化)并将对象中的任何属性复制到资源实例(myPdf
在上一个片段).
By default, an AngularJS $resource
treats the response as an object (deserialized from JSON) and copies any properties from the object to the resource instance (myPdf
in the previous snippet).
显然,由于您的响应是一个数组缓冲区(或 Blob、类型化数组或其他任何内容),因此这是行不通的.获得所需响应的方法之一是使用 transformResponse
将响应对象包装在一个对象中:
Obviously, since your response is an array buffer (or Blob, typed array or whatever), this is not going to work. One of the ways to get the desired response is to use transformResponse
to wrap the response object in an object:
var myService = $resource('/foo', {}, {
$getPdf: {
responseType: 'arraybuffer',
transformResponse: function(data, headersGetter) {
// Stores the ArrayBuffer object in a property called "data"
return { data : data };
}
}
});
var myPdf = myService.$getPdf();
myPdf.$promise.then(function() {
var docInitParams = {
data: myPdf.data
};
PDFJS.getDocument(docInitParams).then(function (pdf) {
// ...
});
});
或者只是以下(避免不必要的局部变量):
Or simply the following (avoided unnecessary local variables):
myService.$getPdf().$promise.then(function(myPdf) {
PDFJS.getDocument({
data: myPdf.data
}).then(function (pdf) {
// ...
});
});
这篇关于PDF.JS:使用 ArrayBuffer 或 Blob 而不是 URL 呈现 PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!