- PVSM.RU - https://www.pvsm.ru -

Как написать конвертер веб-страниц в PDF и не сойти с ума

Как написать конвертер веб-страниц в PDF и не сойти с ума - 1

Вам когда-нибудь хотелось сохранить статью в PDF без лишних деталей, только в виде текста? Или сохранить только определённый элемент страницы? И чтобы всё это было на одной длинной странице, без разрывов?

Мне тоже. Поэтому, я решил написать своё решение и оформить его в виде браузерного расширения.

Чем же плох стандартный CTRL+P?

При сохранении в PDF я хочу видеть документ ровно в том виде, в котором он представлен на экране. Иметь возможность переходить по ссылкам из PDF и чтобы весь документ был на одном длинном листе, без разрывов.

CTRL+P этого не даёт, он хорош только для печати на бумаге на принтере. Т.е. ровно для той функции, для которой изначально задумывался. А всё, что я перечислил он не умеет.

Какие режимы есть в расширении

Вся страница

Как написать конвертер веб-страниц в PDF и не сойти с ума - 2

Сохраняет всю страницу ровно в том виде в котором она представлена на экране.

Текст остаётся выделяемым, а ссылки кликабельными. Это не картинка с распознанным текстом OCR, а настоящий PDF с текстом и кликабельными ссылками.

Экспорт элемента страницы

Как написать конвертер веб-страниц в PDF и не сойти с ума - 3

В этом режиме можно выбрать определённый элемент страницы и экспортировать только его. Это очень удобно, когда нужно сохранить только статью, только блок кода или любой другой элемент. 

Я часто использую этот режим, когда отправляю Гугл-формы и хочу сохранить заполненные данные, чтобы потом не забыть что отправил.

Статья

Как написать конвертер веб-страниц в PDF и не сойти с ума - 4

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

В этом режиме я предусмотрел перенос текста на новую строку в блоках кода, а также раскрытие тегов <details>, чтобы весь текст статьи попадал в PDF.

Удаление элементов

Как написать конвертер веб-страниц в PDF и не сойти с ума - 5

При включении режима, можно выбрать любой элемент на странице, кликнуть по нему и удалить его.

Например, можно удалить сайдбары, меню, рекламу и т.д.

Если случайно удалили что-то важное, можно нажать CTRL+Z и откатить изменения обратно.

Экспорт чатов с ChatGPT, DeepSeek и Gemini

Раз ИИ компании не хотят внедрять функцию экспорта чата в PDF, я сделал это в своём расширении. Почему нет? Очень удобно - в один клик можно сохранить текущий открытый диалог.

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

Макет можно настроить по размеру экрана или под стандартные размеры типа A4, A5 и т.д.

Как не сойти с ума

Различные варианты вёрстки

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

Атомарный CSS

Из-за повального внедрения атомарных css фреймворков типа Tailwind, сложно выделить отдельные элементы для экспорта на определённых сайтах. 

Например, чтобы сделать экспорт диалога с ChatGPT, пришлось повозиться и писать хитрые селекторы, чтобы выбрать элемент с диалогом. 

На Claude Code я вообще отказался от этой затеи именно из-за вёрстки. Проще всего было с Gemini, там классы назывались человеческим языком.

Lazy-loading

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

Если у вас есть идеи как прогружать подобные элементы более изящным способом - буду рад советам в комментариях.

Восстановление стилей страницы

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

Страницу нельзя перезагружать, потому что если вы заполнили длинную форму и хотите её сохранить в PDF, а в процессе у вас перезагрузится страница, то вашему гневу не будет предела, я знаю о чём говорю - сам через это проходил.

Отсутствие документации

Рендеринг готового PDF - это отдельная песня. Нет нормальных библиотек для этой задачи. Есть всем известный PDF.js от Mozilla, в котором есть PDFViewer. Круто! Если бы не одно “но”. Полное отсутствие  документации. Приходится разбираться по исходникам и обсуждениям в issue.

На Гитхабе много issue и discussions, где люди просят [1] сделать документацию, но Мозилла не хочет этого делать. Что ж, имеют право, по крайней мере за библиотеку спасибо.

Что под капотом

Вот библиотеки, которые я использую:

  • WXT.dev [2] - фреймворк для написания расширения. Это лучшее на мой взгляд решение на данный момент. Быстрый HMR. Запуск отдельного браузера для тестирования, скорость разработки.

  • PDFViewer [3] для рендеринга PDF. Это жесть, но нормальных альтернатив нет.

  • Chrome Debugger [4] для преобразования страницы в PDF. На первый взгляд странное решение, но оно даёт наивысшее качество конечного PDF.

Что дальше

Я добавляю интеграции с крупными сайтами. Например, недавно я добавил возможность сохранять посты на Пикабу и Реддит в один клик.

Помимо расширения [5], я так же сделал веб-сервис [6] для сохранения страниц в PDF. В нём нет такого широкого функционала как в расширении, но зато можно сохранять страницы с телефона.

Расширение и сервис бесплатные для пользователей из России.

Автор: borzab

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/pdf/445741

Ссылки в тексте:

[1] просят: https://github.com/mozilla/pdf.js/discussions/18344

[2] WXT.dev: https://WXT.dev

[3] PDFViewer: https://mozilla.github.io/pdf.js/getting_started/

[4] Chrome Debugger: https://chromedevtools.github.io/devtools-protocol/tot/Page/

[5] расширения: https://chromewebstore.google.com/detail/web-to-pdf/pamnlaoeobcmhkliljfaofekeddpmfoh?utm_source=habr

[6] веб-сервис: https://webtopdf.space/ru?utm_source=habr#demo

[7] Источник: https://habr.com/ru/articles/1003174/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1003174