作为网络开发人员,我们一直在寻找改善用户体验的新方法。这就是为什么我很高兴与您分享一个名为pdfjs查看器的新jQuery插件。
该插件基于mozilla的pdf.js库,为用户提供了一种直接在web浏览器中查看pdf文档的简单方法。
在本教程中,我将向您展示如何安装和使用pdfjs查看器jQuery插件,以及它的一些功能。所以让我们开始吧!
1.在文档中加载必要的jQuery和pdf.js库。
<script src="/path/to/cdn/jquery.min.js"></script> <script src="/path/to/cdn/pdf.min.js"></script>
2.加载可选材料图标。
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet">
3.加载pdfjs查看器插件的文件。
<!-- Core --> <script src="/js/pdfjs-viewer.js"></script> <link rel="stylesheet" href="/css/pdfjs-viewer.css"> <!-- Optional Toolbar Stylesheet --> <link rel="stylesheet" href="/css/pdftoolbar.css">
4.初始化pdf.js库。
// Let's initialize the PDFjs library var pdfjsLib = window['pdfjs-dist/build/pdf']; // The workerSrc property shall be specified. pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.worker.min.js';
5.在您指定的HTML元素中创建PDF查看器。
<div class="pdfjs-viewer"> ... </div>
var pdfViewer = new PDFjsViewer($('.pdfjs-viewer'));
// load a PDF file
pdfViewer.loadDocument('test.pdf');
<!-- Or Using pdf-document attribute --> <div id="viewer" class="pdfjs-viewer" pdf-document="test.pdf" initial-zoom="fit"> ... </div>
let pdfViewer = document.getElementById("viewer");
5.在PDF查看器中添加自定义工具栏。
<div class="row col-6 offset-md-3 pdfviewer p-0 row h-100">
<div class="pdfjs-toolbar text-center row m-0 p-0">
<div class="col-12 col-lg-6 my-1">
<button class="btn btn-secondary btn-sm btn-first" onclick="pdfViewer.first()"><i class="material-icons-outlined">skip_previous</i></button>
<button class="btn btn-secondary btn-sm btn-prev" onclick="pdfViewer.prev(); return false;"><i class="material-icons-outlined">navigate_before</i></button>
<span class="pageno"></span>
<button class="btn btn-secondary btn-sm btn-next" onclick="pdfViewer.next(); return false;"><i class="material-icons-outlined">navigate_next</i></button>
<button class="btn btn-secondary btn-sm btn-last" onclick="pdfViewer.last()"><i class="material-icons-outlined">skip_next</i></button>
</div>
<div class="col-12 col-lg-6 my-1">
<button class="btn btn-secondary btn-sm" onclick="pdfViewer.setZoom('out')"><i class="material-icons-outlined">zoom_out</i></button>
<span class="zoomval">100%</span>
<button class="btn btn-secondary btn-sm" onclick="pdfViewer.setZoom('in')"><i class="material-icons-outlined">zoom_in</i></button>
<button class="btn btn-secondary btn-sm ms-3" onclick="pdfViewer.setZoom('width')"><i class="material-icons-outlined">swap_horiz</i></button>
<button class="btn btn-secondary btn-sm" onclick="pdfViewer.setZoom('height')"><i class="material-icons-outlined">swap_vert</i></button>
<button class="btn btn-secondary btn-sm" onclick="pdfViewer.setZoom('fit')"><i class="material-icons-outlined">fit_screen</i></button>
</div>
</div>
<div class="pdfjs-viewer h-100" pdf-document="test.pdf" initial-zoom="fit" on-document-ready="pdfViewer = this.pdfViewer;">
</div>
</div>
var pdfViewer;
6.这个例子展示了如何创建一个支持缩略图的全屏PDF查看器。
<div class="pdfviewer">
<div class="pdfjs-toolbar">
<button class="pushed" onclick="togglethumbs(this);"><i class="material-icons-outlined">view_sidebar</i></button>
<div class="v-sep"></div>
<button onclick="pdfViewer.prev();"><i class="material-icons-outlined">arrow_upward</i></button>
<div class="v-sep"></div>
<button onclick="pdfViewer.next();"><i class="material-icons-outlined">arrow_downward</i></button>
<input id="pageno" class="pageno" type="number" class="form-control form-control-sm d-inline w-auto" value="1" min="1" max="1000" onchange="pdfViewer.scrollToPage(parseInt(this.value))">
<span id="pagecount" class="pageno"></span>
<div class="divider"></div>
<button onclick="pdfViewer.setZoom('in')"><i class="material-icons-outlined">add</i></button>
<div class="v-sep"></div>
<button onclick="pdfViewer.setZoom('out')"><i class="material-icons-outlined">remove</i></button>
<div class="dropdown">
<div class="dropdown-value" onclick="this.parentNode.classList.toggle('show');">
<span class="zoomval">100%</span>
<i class="material-icons-outlined">
keyboard_arrow_down
</i>
</div>
<div class="dropdown-content" onclick="this.parentNode.classList.toggle('show');">
<a href="#" onclick='pdfViewer.setZoom("width"); return false;'>Adjust width</a>
<a href="#" onclick='pdfViewer.setZoom("height"); return false;'>Adjust height</a>
<a href="#" onclick='pdfViewer.setZoom("fit"); return false;'>Fit page</a>
<a href="#" onclick='pdfViewer.setZoom(0.5); return false;'>50%</a>
<a href="#" onclick='pdfViewer.setZoom(0.75); return false;'>75%</a>
<a href="#" onclick='pdfViewer.setZoom(1); return false;'>100%</a>
<a href="#" onclick='pdfViewer.setZoom(1.25); return false;'>125%</a>
<a href="#" onclick='pdfViewer.setZoom(1.5); return false;'>150%</a>
<a href="#" onclick='pdfViewer.setZoom(2); return false;'>200%</a>
<a href="#" onclick='pdfViewer.setZoom(3); return false;'>300%</a>
<a href="#" onclick='pdfViewer.setZoom(4); return false;'>400%</a>
</div>
</div>
<button id="hideselected" onclick="hideselected();"><i class="material-icons-outlined">block</i></button>
<div class="divider"></div>
<label class="button" for="opendoc"><i class="material-icons-outlined">file_open</i></label>
<input id="opendoc" type="file" accept="application/pdf">
<a id="filedownload" class="button"><i class="material-icons-outlined">file_download</i></a>
<div class="dropdown dropdown-right">
<div onclick="this.parentNode.classList.toggle('show');">
<button><i class="material-icons-outlined">keyboard_double_arrow_right</i></button>
</div>
<div class="dropdown-content" onclick="this.parentNode.classList.toggle('show');">
<a href="#" onclick='pdfViewer.scrollToPage(1); return false;'><i class="material-icons-outlined">vertical_align_top</i>First page</a>
<a href="#" onclick='pdfViewer.scrollToPage(pdfViewer.pdf.numPages); return false;'><i class="material-icons-outlined">vertical_align_bottom</i>Last page</a>
<div class="h-sep"></div>
<a href="#" onclick='pdfViewer.rotate(-90, true); pdfThumbnails.rotate(-90, true).then(() => pdfThumbnails.setZoom("fit"));'><i class="material-icons-outlined">rotate_90_degrees_ccw</i>Rotate countrary clockwise</a>
<a href="#" onclick='pdfViewer.rotate(90, true); pdfThumbnails.rotate(90, true).then(() => pdfThumbnails.setZoom("fit"));'><i class="material-icons-outlined">rotate_90_degrees_cw</i>Rotate clockwise</a>
<div class="h-sep"></div>
<a href="#" onclick='document.querySelector(".pdfjs-viewer").classList.remove("horizontal-scroll"); pdfViewer.refreshAll();'><i class="material-icons-outlined">more_vert</i>Vertical scroll</a>
<a href="#" onclick='setHorizontal()'><i class="material-icons-outlined">more_horiz</i>Horizontal scroll</a>
</div>
</div>
</div>
<div class="pdfviewer-container">
<div class="thumbnails pdfjs-viewer">
</div>
<div class="maindoc pdfjs-viewer">
<div class="pdfpage placeholder">
<p class="my-auto mx-auto">Cargue un fichero</p>
</div>
</div>
</div>
</div>
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const PDFFILE = urlParams.get('doc')??"test.pdf";
function dataURItoBinArray(data) {
// taken from: https://stackoverflow.com/a/11954337/14699733
var binary = atob(data);
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Uint8Array(array);
}
/** Function to load a PDF file using the input=file API */
document.querySelector("#opendoc").addEventListener("change", function(e) {
let file = e.target;
let reader = new FileReader();
reader.onload = async function() {
await pdfViewer.loadDocument({data: dataURItoBinArray(reader.result.replace(/^data:.*;base64,/,""))});
await pdfThumbnails.loadDocument({data: dataURItoBinArray(reader.result.replace(/^data:.*;base64,/,""))}).then(() => pdfThumbnails.setZoom("fit"));
}
if (file.files.length > 0) {
reader.readAsDataURL(file.files[0]);
document.querySelector('#filedownload').download = document.querySelector('#opendoc').files[0].name;
}
});
/** Sets the document in horizontal scroll by changing the class for the pages container and refreshing the document
* so that the pages may be displayed in horizontal scroll if they were not visible before */
function setHorizontal() {
document.querySelector(".maindoc").classList.add("horizontal-scroll");
pdfViewer.refreshAll();
}
/** Toggles the visibility of the thumbnails */
function togglethumbs(el) {
if (el.classList.contains('pushed')) {
el.classList.remove('pushed');
document.querySelector('.thumbnails').classList.add('hide');
} else {
el.classList.add('pushed');
document.querySelector('.thumbnails').classList.remove('hide');
}
}
/** Toggles hiding the current page */
function hideselected() {
let $selected = pdfThumbnails.$container.find('.selected');
let i = $selected.data('page');
$selected.toggleClass('hidden');
pdfViewer.$container.find('.pdfpage[data-page="' + i + '"]').toggleClass('hidden');
pdfViewer.scrollToPage(i);
}
/** Now create the PDFjsViewer object in the DIV */
let pdfViewer = new PDFjsViewer($('.maindoc'), {
zoomValues: [ 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4 ],
/** Update the zoom value in the toolbar */
onZoomChange: function(zoom) {
zoom = parseInt(zoom * 10000) / 100;
$('.zoomval').text(zoom + '%');
},
/** Update the active page */
onActivePageChanged: function(page) {
let pageno = $(page).data('page');
let pagetotal = this.getPageCount();
if (! $(page).hasClass('hidden')) {
pdfThumbnails.setActivePage(pageno);
$('#pageno').val(pageno);
$('#pageno').attr('max', pagetotal);
$('#pagecount').text('de ' + pagetotal);
}
},
/** zoom to fit when the document is loaded and create the object if wanted to be downloaded */
onDocumentReady: function () {
pdfViewer.setZoom('fit');
pdfViewer.pdf.getData().then(function(data) {
document.querySelector('#filedownload').href = URL.createObjectURL(new Blob([data], {type: 'application/pdf'}));
document.querySelector('#filedownload').target = '_blank';
});
}
});
/** Load the initial PDF file */
pdfViewer.loadDocument(PDFFILE).then(function() {
document.querySelector('#filedownload').download = PDFFILE;
});
/** Create the thumbnails */
let pdfThumbnails = new PDFjsViewer($('.thumbnails'), {
zoomFillArea: 0.7,
onNewPage: function(page, i) {
$('<div class="numbering">').text(i).appendTo(page);
page.on('click', function() {
pdfThumbnails.setActivePage(page.data('page'));
if (!pdfViewer.isPageVisible(page.data('page'))) {
pdfViewer.scrollToPage(page.data('page'));
}
})
},
onDocumentReady: function() {
this.setZoom('fit');
}
});
pdfThumbnails.setActivePage = function(pageno) {
this.$container.find('.pdfpage').removeClass('selected');
let $npage = this.$container.find('.pdfpage[data-page="' + pageno + '"]').addClass('selected');
$('#hideselected').removeClass('pushed');
if ($npage.hasClass('hidden'))
$('#hideselected').addClass('pushed');
if (!this.isPageVisible(pageno)) {
this.scrollToPage(pageno);
}
}.bind(pdfThumbnails);
pdfThumbnails.loadDocument(PDFFILE);
7.所有默认选项和回调。
let pdfViewer = new PDFjsViewer($('.pdfpages'), {
// Fraction of the area of the page that has to be visible to be considered that it is visible
visibleThreshold: 0.5,
// Number of pages to load appart from the currently visible one (to enable fast scrolling)
extraPagesToLoad: 3,
// The class used for each page (the div that wraps the content of the page)
pageClass: "pdfpage",
// The class used for the content of each page (the div that contains the page)
contentClass: "content-wrapper",
// Posible zoom values to iterate over using "in" and "out"
zoomValues: [ 0.25, 0.5, 0.75, 1, 1.25, 1.50, 2, 4, 8 ],
// Percentage of the container that will be filled with the page
zoomFillArea: 0.95,
// Function called when a document has been loaded and its structure has been created
onDocumentReady: () => {},
// Function called when a new page is created (it is binded to the object, and receives a jQuery object as parameter)
onNewPage: (page, i) => {},
// Function called when a page is rendered
onPageRender: (page, i) => {},
// Function called when the zoom level changes (it receives the zoom level)
onZoomChange: (zoomlevel) => {},
// Function called whenever the active page is changed (the active page is the one that is shown in the viewer)
onActivePageChanged: (page, i) => {},
// Function called to get the content of an empty page
emptyContent: () => $('<div class="loader"></div>'),
// Function called to obtain a page that shows an error when the document could not be loaded (returns a jQuery object)
errorPage: () => {
$(`<div class="placeholder"></div>`).addClass(this.settings.pageClass).append($(`<p class="m-auto"></p>`).text("could not load document"))
},
});
8.API方法。
// load a PDF file and returns a promise // the document can be either an url or a bin array. pdfViewer.loadDocument(document); // force re-init pdfViewer.forceViewerInitialization(); // refresh all pages pdfViewer.refreshAll(); // get the active page pdfViewer.getActivePage(); // go to the first page pdfViewer.first(); // go to the last page pdfViewer.last(); // go to the next page pdfViewer.next(); // back to the previous page pdfViewer.prev(); // get the number of pages pdfViewer.getPageCount(); // retrieve all the pages of the document pdfViewer.getPages(); // go to a specific page pdfViewer.scrollToPage(i); // check if the page is visible isPageVisible(i); // set zoom level // it is possible to use a float value which represents a fraction or a keyword 'in', 'out', 'width', 'height' or 'fit' pdfViewer.setZoom(zoom); // get the current zoom level pdfViewer.getZoom(); // rotate the pages pdfViewer.rotate(deg, accumulate = false);
2023-03-28