html2canvas

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

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

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

Скриншот DOM в изображение/PDF: возможности и ограничения подхода.

Объяснение

html2canvas «перерисовывает» DOM в <canvas>, читая вычисленные стили (не делает настоящий снимок экрана).

import html2canvas from "html2canvas";
import { jsPDF } from "jspdf";
 
const el = document.getElementById("report")!;
const canvas = await html2canvas(el, { scale: 2, useCORS: true, backgroundColor: "#fff", logging: false, windowWidth: el.scrollWidth });
const img = canvas.toDataURL("image/png");                                       // PNG-изображение
 
const pdf = new jsPDF("p", "mm", "a4");
const w = 210, h = (canvas.height * w) / canvas.width;
pdf.addImage(img, "PNG", 0, 0, w, h);                                             // страница-картинка (без выделяемого текста)
pdf.save("report.pdf");

Многостраничность: разрезать canvas на страницы по высоте A4 и добавлять addPage(); либо использовать pdf.html(el, {...}).

Ограничения:

ПроблемаКомментарий
Результат — растртекст не выделяется, размер файла большой
CSS-поддержка частичнаяbackdrop-filter, некоторые transform, filter, шрифты, position: sticky отображаются некорректно
CORSизображения с чужих доменов «пачкают» canvas (нужны useCORS и заголовки)
Производительностьбольшие DOM/scale: 2 тяжёлые, ограничения размера canvas
Шрифтывеб-шрифты должны быть загружены до захвата
Разбиение страницразрывы посреди строк/таблиц
Точностьотличается от отображения в браузере

Альтернативы: dom-to-image-more/html-to-image (SVG foreignObject), @media print + печать/«Сохранить как PDF» (векторно, текст сохраняется), серверный рендер в Chromium (Playwright/Puppeteer) — идеальная точность, pdfmake/jsPDF-таблицы для структурированных документов.

Выбор: для быстрых «снимков» блоков (график, подпись, превью) — html2canvas; для документов — печать или серверная генерация.

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

  • Перед захватом дождитесь загрузки шрифтов и изображений (document.fonts.ready).
  • Скрытые элементы и прокручиваемые контейнеры: временно раскрывайте (overflow: visible).
  • Чувствительные данные в скриншоте — вопросы безопасности.
  • Ограничения размера canvas в браузерах (особенно мобильных).

Практика

  1. Сделайте скриншот блока с графиком и сохраните как PNG.
  2. Разбейте длинный отчёт на несколько страниц PDF.
  3. Сравните качество с печатью через @media print.

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

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