PDFJS和PDF编码
PDFJS and PDF encoding
我们正在实施 PDFJS 以在网站上呈现 pdf 文件。
当尝试将 PDFdocument/Viewer 作为 arrayBuffer 启动时,我们会遇到各种错误并且文件不会呈现。
从 url(DEFAULT_URL 变量)在查看器中打开同一文件时,文件呈现良好。
然而,有些文件确实呈现为流。在记事本中比较这些文件显示它们具有不同的 encoding/characters.
这段代码用于在查看器中打开文件:
function rawStringToBuffer( str ) {
var idx, len = str.length, arr = new Array( len );
for ( idx = 0 ; idx < len ; ++idx ) {
arr[ idx ] = str.charCodeAt(idx) & 0xFF;
}
return new Uint8Array( arr ).buffer;
}
function readSingleFile(e) {
var file = e.target.files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
var uint8array = rawStringToBuffer(contents);
pdfjsframe.contentWindow.PDFViewerApplication.open(uint8array,0);
};
reader.readAsText(file);
}
test.pdf helloworld pdf 上面的代码没有渲染。
test2.pdf helloworld pdf 用上面的代码渲染。
该行为不依赖于浏览器。内部版本是 b15f335。
查看器的代码或默认配置是否有问题,导致查看器无法呈现test.pdf?
我认为您的字符串转换例程 rawStringToBuffer()
没有达到您的要求。您正在以文本形式读取文件,它将 UTF-8 转换为 UTF-16。但是rawStringToBuffer()
只是取每个UTF-16字符的低位字节,丢弃高位字节,这不是逆变换。这将适用于 7 位 ASCII 数据,但不适用于其他字符。将字符串转换为 UTF-8 的最佳方法是使用 TextEncoder API(并非所有浏览器都支持,但 polyfill 可用)。
但是,不需要将数据从 UTF-8 转换回来。只需使用 FileReader.readAsArrayBuffer()
而不是 readAsText()
即可直接生成 ArrayBuffer
。
这是一个(未经测试的)替换函数:
function readSingleFile(e) {
var file = e.target.files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
pdfjsframe.contentWindow.PDFViewerApplication.open(contents, 0);
};
reader.readAsArrayBuffer(file);
}
我们正在实施 PDFJS 以在网站上呈现 pdf 文件。
当尝试将 PDFdocument/Viewer 作为 arrayBuffer 启动时,我们会遇到各种错误并且文件不会呈现。 从 url(DEFAULT_URL 变量)在查看器中打开同一文件时,文件呈现良好。
然而,有些文件确实呈现为流。在记事本中比较这些文件显示它们具有不同的 encoding/characters.
这段代码用于在查看器中打开文件:
function rawStringToBuffer( str ) {
var idx, len = str.length, arr = new Array( len );
for ( idx = 0 ; idx < len ; ++idx ) {
arr[ idx ] = str.charCodeAt(idx) & 0xFF;
}
return new Uint8Array( arr ).buffer;
}
function readSingleFile(e) {
var file = e.target.files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
var uint8array = rawStringToBuffer(contents);
pdfjsframe.contentWindow.PDFViewerApplication.open(uint8array,0);
};
reader.readAsText(file);
}
test.pdf helloworld pdf 上面的代码没有渲染。
test2.pdf helloworld pdf 用上面的代码渲染。
该行为不依赖于浏览器。内部版本是 b15f335。
查看器的代码或默认配置是否有问题,导致查看器无法呈现test.pdf?
我认为您的字符串转换例程 rawStringToBuffer()
没有达到您的要求。您正在以文本形式读取文件,它将 UTF-8 转换为 UTF-16。但是rawStringToBuffer()
只是取每个UTF-16字符的低位字节,丢弃高位字节,这不是逆变换。这将适用于 7 位 ASCII 数据,但不适用于其他字符。将字符串转换为 UTF-8 的最佳方法是使用 TextEncoder API(并非所有浏览器都支持,但 polyfill 可用)。
但是,不需要将数据从 UTF-8 转换回来。只需使用 FileReader.readAsArrayBuffer()
而不是 readAsText()
即可直接生成 ArrayBuffer
。
这是一个(未经测试的)替换函数:
function readSingleFile(e) {
var file = e.target.files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
pdfjsframe.contentWindow.PDFViewerApplication.open(contents, 0);
};
reader.readAsArrayBuffer(file);
}