View Any PDF in WebViewer
Having extolled the virtues of Juan Antonio's base64 extension in previous posts (Create PDF, Upload any File) I set about seeing what could be done about viewing PDFs from assets and the sdcard using a similar method.
I did some hunting around on the internet and found a javascript library called PDFJS, which allowed for offline/closed system rendering of PDFs, thus no reliance on an internet connection or built-in pdf plugins in browsers. After some testing and trial and error, I have come up with a solution that allows such viewing
The workflow:
create a suitable html file with webviewstring capabilities
select a pdf file from either assets or sdcard
convert the pdf to a base64 string
modify the string for use with javascript and feed this to the webviewstring
view the pdf in an AI2 app
In my example there is a bit more to it than that. PDFJS can only render one page at a time, so one must have a way of changing pages, which I did by getting the number of pages from the html page once the pdf was initially rendered, then sending that value back to the app, controlling the page display from there. Also, scaling needed controlling in order to be able to zoom in and out of the pdf
BLOCKS
I will show all the blocks below but need to show the important ones that actually do the work for the display of the pdf.
First off the base64 conversion
and then the call to show the html
and now all the blocks used in the example aia project
VIDEO
HTML
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>SHOWPDF</title>
<script src='pdf.js'></script>
<style>
#the-canvas { border:1px solid black; }
body {background-color: #404448;}
</style>
</head>
<body>
<canvas id="the-canvas"></canvas>
</body>
<script>
//gets the webviewstring and converts to a list
var wvList = window.AppInventor.getWebViewString().split(" || ");
//sets the variable with the base64 string and convert to blob
var pdfData = atob(wvList[2]);
var pdfjsLib = window['pdfjs-dist/build/pdf'];
pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdf.worker.js';
var loadingTask = pdfjsLib.getDocument({data: pdfData});
loadingTask.promise.then(function(pdf) {
//sets the page number from the webviewstring list
var pageNumber = parseInt(wvList[0]);
pdf.getPage(pageNumber).then(function(page) {
//sets the scale value from the webviewstring list
var scale = parseFloat(wvList[1]);
//returns the number of pages in the pdf to the app
window.AppInventor.setWebViewString(pdf.numPages);
var viewport = page.getViewport({scale: 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
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
});
});
}, function (reason) {
alert(reason);
});
</script>
</html>
CREDITS:
Juan Antonio for the base64 extension
Taifun for the File and Tools extensions