Формат Portable Document Format, или сокращенно PDF, идеально подходит для публикации документов, содержащих много точно отформатированного текста и изображений, особенно если они могут быть напечатаны или прочитаны в автономном режиме. Хотя большинство современных браузеров могут отображать файлы PDF, они делают это с помощью средства просмотра PDF, которое запускается на независимой вкладке или в окне, заставляя пользователей покидать ваш веб-сайт.
PDF.js — это библиотека JavaScript с открытым исходным кодом, которая позволяет вам анализировать и отображать файлы PDF прямо на ваших веб-страницах. В этом уроке я покажу вам, как использовать его для создания полноценного пользовательского JavaScript PDF viewer с нуля.
1. Создание пользовательского интерфейса
Давайте начнем с создания новой веб-страницы и добавления к ней обычного шаблонного кода HTML5.
01
02
03
04
05
06
07
08
09
10
11
12
|
<!doctype html>
<html lang=»en»>
<head>
<meta charset=»utf-8″>
<meta name=»viewport» content=»width=device-width, initial-scale=1″>
<title>My PDF Viewer</title>
</head>
<body>
</body>
</html>
|
Затем внутри <body>
создайте элемент <div>
который может служить контейнером для нашего средства просмотра PDF.
1
2
3
|
<div id=»my_pdf_viewer»>
</div>
|
В основе нашего средства просмотра PDF для JavaScript будет элемент HTML5 <canvas>
. Мы будем рендерить страницы наших файлов PDF внутри него. Поэтому добавьте следующий код внутри элемента <div>
.
1
2
3
|
<div id=»canvas_container»>
<canvas id=»pdf_renderer»></canvas>
</div>
|
Для простоты в любой момент времени мы будем отображать только одну страницу внутри холста. Однако мы позволим пользователям переключаться на предыдущую или следующую страницу нажатием кнопки. Кроме того, чтобы отобразить номер текущей страницы и позволить пользователям переходить на любую страницу, которую они хотят, в нашем интерфейсе будет поле ввода.
1
2
3
4
5
|
<div id=»navigation_controls»>
<button id=»go_previous»>Previous</button>
<input id=»current_page» value=»1″ type=»number»/>
<button id=»go_next»>Next</button>
</div>
|
Для поддержки операций масштабирования добавьте в интерфейс еще две кнопки: одну для увеличения и одну для уменьшения.
1
2
3
4
|
<div id=»zoom_controls»>
<button id=»zoom_in»>+</button>
<button id=»zoom_out»>-</button>
</div>
|
2. Получение PDF.js
Теперь, когда готовый пользовательский интерфейс для нашего средства просмотра PDF JavaScript готов, давайте добавим PDF.js на нашу веб-страницу. Поскольку последняя версия библиотеки доступна на CDNJS , мы можем сделать это, просто добавив следующие строки в конец веб-страницы.
1
2
3
|
<script
src=»https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.0.943/pdf.min.js»>
</script>
|
Если вы предпочитаете использовать локальную копию библиотеки, вы можете скачать ее из репозитория pdfjs-dist .
3. Загрузка файла PDF
Прежде чем мы начнем загружать файл PDF, давайте создадим простой объект JavaScript для хранения состояния нашего средства просмотра PDF. Внутри него будет три элемента: ссылка на сам файл PDF, текущий индекс страницы и текущий уровень масштабирования.
1
2
3
4
5
6
7
8
9
|
<script>
var myState = {
pdf: null,
currentPage: 1,
zoom: 1
}
// more code here
</script>
|
На этом этапе мы можем загрузить наш файл PDF, вызвав метод getDocument()
объекта pdfjsLib
, который работает асинхронно.
1
2
3
4
5
|
pdfjsLib.getDocument(‘./my_document.pdf’).then((pdf) => {
// more code here
});
|
Обратите внимание, что метод getDocument()
внутренне использует объект XMLHttpRequest
для загрузки файла PDF. Это означает, что файл должен присутствовать либо на вашем веб-сервере, либо на сервере, который разрешает запросы из разных источников.
Если у вас нет удобного PDF-файла, вы можете получить тот, который я использую здесь .
После успешной загрузки PDF-файла мы можем обновить свойство pdf
нашего объекта состояния.
1
|
myState.pdf = pdf;
|
Наконец, добавьте вызов функции с именем render()
чтобы наша программа просмотра PDF автоматически отображала первую страницу файла PDF. Мы определим функцию на следующем шаге.
1
|
render();
|
4. Рендеринг страницы
Вызвав метод getPage()
объекта pdf
и передав ему номер страницы, мы можем получить ссылку на любую страницу в файле PDF. А сейчас давайте передадим ему свойство currentPage
нашего объекта состояния. Этот метод также возвращает обещание, поэтому нам понадобится функция обратного вызова для обработки его результата.
Соответственно, создайте новую функцию с именем render()
содержащую следующий код:
1
2
3
4
5
6
7
|
function render() {
myState.pdf.getPage(myState.currentPage).then((page) => {
// more code here
});
}
|
Чтобы действительно отобразить страницу, мы должны вызвать метод render()
объекта page
доступного внутри обратного вызова. В качестве аргументов метод ожидает двухмерный контекст нашего холста и объект PageViewport
, который мы можем получить, вызвав метод getViewport()
. Поскольку метод getViewport()
ожидает желаемый уровень масштабирования в качестве аргумента, мы должны передать ему свойство zoom
нашего объекта состояния.
1
2
3
4
|
var canvas = document.getElementById(«pdf_renderer»);
var ctx = canvas.getContext(‘2d’);
var viewport = page.getViewport(myState.zoom);
|
Размеры области просмотра зависят от исходного размера страницы и уровня масштабирования. Чтобы убедиться, что весь видовой экран отображается на нашем холсте, мы должны теперь изменить размер нашего холста, чтобы он соответствовал размеру видового экрана. Вот как:
1
2
|
canvas.width = viewport.width;
canvas.height = viewport.height;
|
На этом этапе мы можем продолжить и визуализировать страницу.
1
2
3
4
|
page.render({
canvasContext: ctx,
viewport: viewport
});
|
Если вы попытаетесь открыть веб-страницу в браузере, теперь вы сможете увидеть первую страницу вашего PDF-файла.
Возможно, вы заметили, что размер нашего средства просмотра PDF в настоящее время зависит от размера отображаемой страницы и уровня масштабирования. Это не идеально, потому что мы не хотим, чтобы макет нашей веб-страницы был затронут, пока пользователи взаимодействуют с программой просмотра PDF.
Чтобы это исправить, все, что нам нужно сделать, это задать фиксированную ширину и высоту для элемента <div>
инкапсулирующего наш холст, и установить его свойство CSS overflow
на auto
. Это свойство при необходимости добавляет полосы прокрутки к элементу <div>
, позволяя пользователям прокручивать как по горизонтали, так и по вертикали.
Добавьте следующий код в <head>
веб-страницы:
1
2
3
4
5
6
7
|
<style>
#canvas_container {
width: 800px;
height: 450px;
overflow: auto;
}
</style>
|
Вы, конечно, можете изменять ширину и высоту или даже использовать медиа-запросы, чтобы элемент <div>
соответствовал вашим требованиям.
При желании вы можете включить следующие правила CSS, чтобы элемент <div>
выглядел более отчетливо:
1
2
3
4
5
|
#canvas_container {
background: #333;
text-align: center;
border: solid 3px;
}
|
Если вы обновите веб-страницу сейчас, вы должны увидеть что-то вроде этого на вашем экране:
5. Изменение текущей страницы
Наш JavaScript Viewer в настоящее время способен отображать только первую страницу любого PDF-файла, данного ему. Чтобы позволить пользователям изменять отображаемую страницу, теперь мы должны добавить прослушиватели событий click к go_previous
и go_next
мы создали ранее.
Внутри прослушивателя go_previous
кнопки go_previous
мы должны go_previous
нашего объекта состояния, убедившись, что оно не падает ниже 1
. После этого мы можем просто снова вызвать функцию render()
чтобы отобразить новую страницу.
Кроме того, мы должны обновить значение текстового поля current_page
чтобы оно отображало новый номер страницы. Следующий код показывает вам, как:
1
2
3
4
5
6
7
8
9
|
document.getElementById(‘go_previous’)
.addEventListener(‘click’, (e) => {
if(myState.pdf == null
||
myState.currentPage -= 1;
document.getElementById(«current_page»)
.value = myState.currentPage;
render();
});
|
Точно так же внутри слушателя go_next
кнопки go_next
мы должны go_next
, не go_next
, чтобы оно превышало количество страниц, присутствующих в файле PDF, которое мы можем определить с numPages
свойства _pdfInfo
объекта _pdfInfo
.
01
02
03
04
05
06
07
08
09
10
11
12
|
document.getElementById(‘go_next’)
.addEventListener(‘click’, (e) => {
if(myState.pdf == null
||
._pdfInfo.numPages)
return;
myState.currentPage += 1;
document.getElementById(«current_page»)
.value = myState.currentPage;
render();
});
|
Наконец, мы должны добавить прослушиватель событий нажатия клавиши в текстовое поле current_page
чтобы пользователи могли напрямую переходить на любую страницу по своему желанию, просто набрав номер страницы и нажав клавишу Enter . Внутри прослушивателя событий нам нужно убедиться, что число, введенное пользователем, больше нуля и меньше или равно numPages
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
document.getElementById(‘current_page’)
.addEventListener(‘keypress’, (e) => {
if(myState.pdf == null) return;
// Get key code
var code = (e.keyCode ? e.keyCode : e.which);
// If key code matches that of the Enter key
if(code == 13) {
var desiredPage =
document.getElementById(‘current_page’)
.valueAsNumber;
if(desiredPage >= 1
&& desiredPage <= myState.pdf
._pdfInfo.numPages) {
myState.currentPage = desiredPage;
document.getElementById(«current_page»)
.value = desiredPage;
render();
}
}
});
|
Теперь наша программа просмотра PDF может отображать любую страницу файла PDF.
6. Изменение уровня масштабирования
Поскольку наша функция render()
уже использует свойство zoom
объекта состояния при рендеринге страницы, регулировать уровень масштабирования так же просто, как увеличивать или уменьшать свойство и вызывать функцию.
Внутри слушателя события zoom_in
кнопки zoom_in
давайте zoom_in
свойство zoom
на 0.5
.
1
2
3
4
5
6
|
document.getElementById(‘zoom_in’)
.addEventListener(‘click’, (e) => {
if(myState.pdf == null) return;
myState.zoom += 0.5;
render();
});
|
А внутри слушателя события zoom_out
кнопки zoom_out
давайте zoom_out
свойство zoom
на 0.5
.
1
2
3
4
5
6
|
document.getElementById(‘zoom_out’)
.addEventListener(‘click’, (e) => {
if(myState.pdf == null) return;
myState.zoom -= 0.5;
render();
});
|
Вы можете добавить верхнюю и нижнюю границы в свойство zoom
, но они не обязательны.
Наш просмотрщик PDF готов. Если вы обновите веб-страницу снова, вы сможете просматривать все страницы, присутствующие в файле PDF, а также увеличивать или уменьшать их.
Вывод
Теперь вы знаете, как использовать PDF.js для создания пользовательского JavaScript PDF Viewer для вашего сайта. С его помощью вы можете уверенно предлагать удобное взаимодействие с пользователем, демонстрируя брошюры, официальные документы, формы и другие документы своей организации, которые обычно предназначены для распространения в печатном виде.
Вы можете узнать больше о PDF.js на официальном репозитории GitHub .