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

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

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

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

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

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

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

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

Вся страница

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

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

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

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

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

Статья

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

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

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

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

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

Если случайно удалили что-то важное, можно нажать 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, где люди просят сделать документацию, но Мозилла не хочет этого делать. Что ж, имеют право, по крайней мере за библиотеку спасибо.

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

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

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

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

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

Что дальше

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

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

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


Внимание!

Официальный сайт бота по ссылке ниже.

Официальный сайт