我试图通过以下方式从我的JavaFX-WebView中调用JavaScript方法:
JSObject win = (JSObject)getEngine().executeScript("window");
win.call("showPDF", myPDFFile /*typeof java.io.File*/);
此调用的结果是:
无效的参数对象:需要.data,.range或.url
这是JavaScript-Part(不是我),它会引发错误:
var source;
if (typeof src === 'string') {
source = { url: src };
} else if (isArrayBuffer(src)) {
source = { data: src };
} else if (src instanceof PDFDataRangeTransport) {
source = { range: src };
} else {
if (typeof src !== 'object') {
error('Invalid parameter in getDocument, need either Uint8Array, ' +
'string or a parameter object');
}
if (!src.url && !src.data && !src.range) {
error('Invalid parameter object: need either .data, .range or .url');
}
}
isArrayBuffer
的实施:
function isArrayBuffer(v) {
return typeof v === 'object' && v !== null && v.byteLength !== undefined;
}
所以我的问题是:
可以使用哪种类型的(java)对象,以便此调用可以起作用?
win.call("showPDF", ???);
编辑1:
无法使用字符串,因为它将被视为URL
我想提交类似 ByteArray (我的具体文件),但使用byte[]
(而不是java.io.File
)会导致相同的错误。
以下是JS函数的一些注释:
https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L234
这是加载PDF并与之交互的主要入口点 注意:如果使用URL来获取PDF数据标准XMLHttpRequest(XHR)
使用,这意味着它必须遵循任何XHR所具有的相同原始规则 例如没有CORS的跨域请求
@param {string | TypedArray | DocumentInitParameters | PDFDataRangeTransport} src
可以是PDF所在的URL,类型数组(Uint8Array)
已经填充了数据或参数对象。
我必须使用什么数据类型(在JAVA中),因此它将是JAVASCRIPT中的(例如) TypedArray(Uint8Array)?
编辑2:
我在尝试Aarons的建议:
String encoded = Base64.getEncoder().encodeToString(Files.readAllBytes(myPDFFile.toPath()));
engine.executeScript("var src = _base64ToArrayBuffer('"+encoded+"'); showPDF(src);");
这会导致一个新问题:
错误:无效的PDF二进制数据:数据属性中应该是类型化数组,字符串或类数组对象。
此处抛出此(新)错误(稍后几行):https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L291
console.log(_base64ToArrayBuffer(encoded))
返回:[object ArrayBuffer]
解决方案:
我设法做了这项工作(在亚伦的帮助下):
pdfViewer.html
<!doctype html>
<html>
<head>
<script src="web/compatibility.js"></script>
<script src="build/pdf.js"></script>
<script>
function _base64ToBinaryString(base64) {
var binary_string = window.atob(base64);
return binary_string;
}
function showPDF(pdfFile) {
console.log('calling showPDF...');
'use strict';
PDFJS.disableWorker = true; /* IMPORTANT TO DISABLE! */
PDFJS.workerSrc = 'build/pdf.worker.js';
console.log('TRYING TO GET DOCUMENT FROM BINARY DATA...');
PDFJS.getDocument({data: pdfFile}).then(function(pdf)
{
console.log('PDF LOADED.');
console.log('TRYING TO GET PAGE 1...');
pdf.getPage(1).then(function(page) {
console.log('PAGE 1 LOADED.');
var scale = 1.0;
var viewport = page.getViewport(scale);
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
console.log('RENDERING PAGE 1...');
page.render(renderContext);
});
});
};
</script>
</head>
<body>
<canvas id="the-canvas" style="border:1px solid black;"/>
</body>
</html>
将上述HTML页面加载到WebView后, 以下Java代码用于将PDF文件加载到页面:
String encoded = Base64.getEncoder().encodeToString(Files.readAllBytes(myPdfFile.toPath()));
webEngine.executeScript("var src = _base64ToBinaryString('"+encoded+"'); showPDF(src);");
答案 0 :(得分:0)
尝试myPDFFile.getURI().getURL().toString()
,因为该方法接受字符串形式的网址。由于WebKit在本地运行,您应该能够阅读file://
URL。
如果您想尝试ArrayBuffer
,那么您可以在https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
这意味着您需要创建FileReader
,传递URL,处理异步事件。如果你对JavaScript了解得很好,我只推荐这个。
不幸的是,这些示例都是为了处理网页中的文件,而不是将数据传递到页面中。
[编辑] 以下是如何将Base64编码的字符串转换为ArrayBuffer
的示例:Convert base64 string to ArrayBuffer
因此,您需要将文件加载到Java byte[]
数组中。然后将数组转换为Base64编码的Java String。然后,您可以将其粘贴到动态JavaScript中:
String encoded = ...byte[] -> Base64...
getEngine().executeScript("var src = _base64ToArrayBuffer('"+encoded+"'); showPDF(src);");