pdf.js

↑ 5.6 PDF и печатные формы на клиенте · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Просмотр PDF в приложении: рендер страниц, поиск, worker.

Объяснение

pdf.js (Mozilla) — библиотека парсинга и отрисовки PDF в <canvas>; основа встроенного просмотрщика Firefox.

import * as pdfjs from "pdfjs-dist";
import workerUrl from "pdfjs-dist/build/pdf.worker.min.mjs?url";
pdfjs.GlobalWorkerOptions.workerSrc = workerUrl;                 // парсинг в Web Worker
 
const pdf = await pdfjs.getDocument({ url, withCredentials: true, cMapUrl: "/cmaps/", cMapPacked: true }).promise;   // cMaps для CJK/кириллических шрифтов
const page = await pdf.getPage(1);
const viewport = page.getViewport({ scale: 1.5 * devicePixelRatio });
canvas.width = viewport.width; canvas.height = viewport.height;
await page.render({ canvasContext: canvas.getContext("2d")!, viewport }).promise;
 
const text = await page.getTextContent();                        // текстовый слой (поиск, выделение)
pdf.numPages; await pdf.getMetadata();

Варианты интеграции:

СпособОсобенности
<iframe>/<embed>/<object> с Blob URLвстроенный просмотрщик браузера, минимум кода, разное поведение на мобильных
pdf.js (pdfjs-dist)полный контроль: canvas + текстовый слой + аннотации
pdf.js viewer (готовый web/viewer.html)готовый интерфейс (поиск, миниатюры, печать)
Обёртки (vue-pdf-embed, @tato30/vue-pdf, vue3-pdf-app)компоненты для Vue
Коммерческие SDK (PSPDFKit, Apryse)подпись, аннотации, формы

Практики: рендерить только видимые страницы (виртуализация, IntersectionObserver), кэшировать рендер, учитывать devicePixelRatio, освобождать ресурсы (page.cleanup(), pdf.destroy()), передавать Authorization при закрытых файлах (получить Blob/ArrayBuffer и открыть из данных).

Безопасность: PDF может содержать скрипты — pdf.js отключает выполнение (enableScripting: false); проверяйте источник; CSP для worker.

Нюансы и подводные камни

  • Версия worker должна совпадать с версией библиотеки.
  • Большие файлы: потоковая загрузка (rangeChunkSize), disableAutoFetch.
  • Шрифты без встроенных cMaps отображаются некорректно.
  • pdfjs-dist тяжёлый (ленивая загрузка чанка).
  • Мобильные браузеры: iframe с PDF часто показывает только первую страницу.

Практика

  1. Отобразите PDF постранично на canvas с навигацией и масштабом.
  2. Добавьте текстовый слой и поиск по документу.
  3. Загрузите защищённый PDF с токеном как Blob.

Вопросы с ответами

Связанные темы