Главная » Статьи » Как создать на JavaScript средство просмотра PDF

Как создать на JavaScript средство просмотра PDF

Как создать на JavaScript средство просмотра PDF

От автора: формат Portable Document Format, или сокращенно PDF, идеально подходит для обмена документами, содержащими много точно отформатированного текста и изображений, особенно если нам нужно иметь возможность распечатать или просмотреть их в автономном режиме. Хотя большинство современных браузеров могут отображать файлы PDF, они делают это с помощью средства просмотра PDF, которое запускается на независимой вкладке или окне, заставляя пользователей покидать ваш веб-сайт.

PDF.js — это JavaScript-библиотека с открытым исходным кодом, которая позволяет парсировать и отображать PDF-файлы прямо на веб-страницах. В этом руководстве я покажу вам, как использовать ее, чтобы создать на JavaScript с нуля полноценное пользовательское средство просмотра PDF.

1. Создание пользовательского интерфейса

Давайте начнем с создания новой веб-страницы и добавления к ней стандартного HTML5-кода.

<!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.

<div id="my_pdf_viewer"></div>

В основе нашего JavaScript PDF Viewer будет элемент HTML5 canvas. Мы будем визуализировать страницы файлов PDF внутри него. Поэтому добавьте следующий код внутри элемента div.

<div id="canvas_container"> <canvas id="pdf_renderer"></canvas>
</div>

Для простоты в любой момент времени мы будем отображать только одну страницу внутри холста. Однако мы позволим пользователям переходить на предыдущую или следующую страницу нажатием кнопки. Кроме того, чтобы отобразить номер текущей страницы и позволить пользователям переходить на любую страницу, в нашем интерфейсе будет поле ввода.

<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>

Для поддержки операций масштабирования добавьте в интерфейс еще две кнопки: одну для увеличения и одну для уменьшения.

<div id="zoom_controls"> <button id="zoom_in">+</button> <button id="zoom_out">-</button>
</div>

2. Получение PDF.js

Теперь, когда пользовательский интерфейс для нашего JavaScript PDF Viewer готов, давайте добавим на веб-страницу PDF.js. Поскольку последняя версия библиотеки доступна на CDNJS, мы можем сделать это, просто добавив следующие строки в конец веб-страницы.

<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, текущий индекс страницы и текущий уровень масштабирования.

<script> var myState = { pdf: null, currentPage: 1, zoom: 1 } // more code here
</script>

На этом этапе мы можем загрузить файл PDF, вызвав метод getDocument() объекта pdfjsLib , который выполняется асинхронно.

pdfjsLib.getDocument('./my_document.pdf').then((pdf) => { // more code here });

Обратите внимание, что метод getDocument() внутренне использует объект XMLHttpRequest для загрузки файла PDF. Это означает, что файл должен присутствовать либо на вашем собственном веб-сервере, либо на сервере, который разрешает запросы из разных источников.

Если у вас нет удобного PDF-файла, вы можете получить тот, который использую я, здесь. После того, как файл PDF был успешно загружен, мы можем обновить свойство pdf объекта состояния.

myState.pdf = pdf;

Наконец, добавьте вызов функции с именем render(), чтобы наша программа просмотра PDF автоматически отображала первую страницу файла PDF. Мы определим функцию на следующем шаге.

render();

4. Рендеринг страницы

Вызвав метод getPage() объекта pdf и передав ему номер страницы, мы можем получить ссылку на любую страницу в файле PDF. А пока давайте передадим ему свойство currentPage объекта состояния. Этот метод также возвращает promise, поэтому нам понадобится функция обратного вызова для обработки его результата.

Соответственно, создайте новую функцию с именем render() , содержащую следующий код:

function render() { myState.pdf.getPage(myState.currentPage).then((page) => { // more code here });
}

Чтобы фактически отобразить страницу, нам нужно вызвать метод render() объекта page, доступного внутри обратного вызова. В качестве аргументов метод ожидает 2D-контекст нашего холста и объект PageViewport, который мы можем получить, вызвав метод getViewport(). Поскольку метод getViewport() ожидает желаемый уровень масштабирования в качестве аргумента, мы должны передать ему свойство zoom объекта состояния.

var canvas = document.getElementById("pdf_renderer");
var ctx = canvas.getContext('2d'); var viewport = page.getViewport(myState.zoom);

Размеры области просмотра зависят от исходного размера страницы и уровня масштабирования. Чтобы убедиться, что все окно просмотра отображается на холсте, мы должны теперь изменить размер холста, чтобы он соответствовал размеру окна просмотра:

canvas.width = viewport.width;
canvas.height = viewport.height;

На этом этапе мы можем продолжить и визуализировать страницу.

page.render({ canvasContext: ctx, viewport: viewport
});

Если вы попытаетесь открыть веб-страницу в браузере, вы сможете увидеть первую страницу вашего PDF-файла.

Возможно, вы заметили, что размер нашего средства просмотра PDF в настоящее время зависит от размера отображаемой страницы и уровня масштабирования. Это не идеально, потому что мы не хотим, чтобы макет веб-страницы был затронут, когда пользователи взаимодействуют с программой просмотра PDF.

Чтобы исправить это, все, что нам нужно сделать, это задать для элемента div, инкапсулирующего наш холст, фиксированную ширину и высоту и установить для его свойства overflow значение auto. Это свойство при необходимости добавляет к элементу div полосы прокрутки, позволяя пользователям прокручивать контент как по горизонтали, так и по вертикали. Добавьте следующий код в тег head веб-страницы:

<style> #canvas_container { width: 800px; height: 450px; overflow: auto; }
</style>

Вы, конечно, можете изменять ширину и высоту или даже использовать медиа-запросы, чтобы они соответствовали вашим требованиям. При желании вы можете включить следующие правила CSS, чтобы элемент div выглядел лучше:

#canvas_container { background: #333; text-align: center; border: solid 3px;
}

Если вы обновите сейчас веб-страницу, вы должны увидеть что-то вроде этого:

5. Изменение текущей страницы

Наш JavaScript PDF Viewer в настоящее время способен отображать только первую страницу любого PDF-файла, переданного ему. Чтобы разрешить пользователям изменять отображаемые страницы, теперь нам нужно добавить обработчики события клика к кнопкам go_previous и go_next , которые мы создали ранее.

Внутри прослушивателя события кнопки go_previous нам нужно уменьшить значения свойство currentPage объекта состояния, но не меньше 1. После этого мы можем просто снова вызвать функцию render(), чтобы отобразить новую страницу.

Кроме того, нам нужно обновить значение текстового поля current_page , чтобы оно отображало новый номер страницы. Следующий код показывает, как это сделать:

document.getElementById('go_previous') .addEventListener('click', (e) => { if(myState.pdf == null || myState.currentPage == 1) return; myState.currentPage -= 1; document.getElementById("current_page") .value = myState.currentPage; render(); });

Точно так же внутри прослушивателя кнопки события go_next нам нужно увеличить значения свойства currentPage , не допуская, чтобы оно превышало количество страниц, присутствующих в файле PDF, которое мы можем определить, используя свойство numPages объекта _pdfInfo.

document.getElementById('go_next') .addEventListener('click', (e) => { if(myState.pdf == null || myState.currentPage > myState.pdf ._pdfInfo.numPages) return; myState.currentPage += 1; document.getElementById("current_page") .value = myState.currentPage; render(); });

Наконец, нам нужно добавить прослушиватель событий нажатия клавиши в текстовое поле current_page , чтобы пользователи могли напрямую переходить на любую страницу по своему желанию, просто набрав номер страницы и нажав клавишу Enter. Внутри прослушивателя событий мы должны обеспечить, чтобы число, введенное пользователем, было больше нуля и меньше или равно значению свойства numPages.

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 на 0.5.

document.getElementById('zoom_in') .addEventListener('click', (e) => { if(myState.pdf == null) return; myState.zoom += 0.5; render(); });

А внутри прослушивателя события клика для кнопки zoom_out давайте уменьшим значение свойства zoom на 0.5.

document.getElementById('zoom_out') .addEventListener('click', (e) => { if(myState.pdf == null) return; myState.zoom -= 0.5; render(); });

Вы можете добавлять верхние и нижние границы к свойству zoom , но это не обязательно. Наше средство просмотра PDF готово. Если вы снова обновите веб-страницу, то сможете просматривать все страницы, содержащиеся в файле PDF, а также увеличивать или уменьшать их.

Заключение

Теперь вы знаете, как использовать PDF.js для создания пользовательского JavaScript средства просмотра PDF. С его помощью вы можете уверенно предлагать удобное взаимодействие с пользователем, демонстрируя брошюры, официальные документы, формы и другие документы своей организации, которые обычно предназначены для распространения в печатном виде. Вы можете узнать больше о PDF.js в официальном репозитории на GitHub.