Как исправить некорректное масштабирование и размытие PDF в поле HTML документа 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто при разработке в 1С возникает задача отобразить PDF-документ прямо на форме, не прибегая к использованию сторонних программ-просмотрщиков, установленных на компьютере пользователя. Одним из популярных решений является использование поля HTML-документа и популярной JavaScript-библиотеки PDF.js. Однако разработчики сталкиваются с неприятной проблемой: при рендеринге документа смазываются шрифты, а масштаб отображения не соответствует исходному файлу. Давайте разберем по шагам, почему это происходит и как мы можем это исправить.

Анализируем причину размытия шрифтов

Главная причина нечеткого отображения и "мыльных" шрифтов заключается в механизме работы самой библиотеки PDF.js. Для вывода страницы документа библиотека использует HTML-элемент canvas (холст). По умолчанию размер этого холста в пикселях строго совпадает с его физическим размером на экране.

Проблема проявляется, если у пользователя в операционной системе Windows установлен масштаб экрана больше 100% (например, 125% или 150%), либо используется современный монитор с высокой плотностью пикселей (High-DPI или Retina). В таких случаях браузерный движок внутри 1С искусственно растягивает изображение на холсте, из-за чего оно теряет четкость и масштабируется некорректно. Выясним, как мы можем адаптировать наш код под такие экраны.

Использование нативных средств платформы 1С (начиная с 8.3.21)

Прежде чем погружаться в дебри JavaScript, рассмотрим самый правильный и надежный путь. Начиная с версии платформы 1С Предприятие 8.3.21, разработчикам доступен встроенный объект ДокументPDF. Если конфигурация и сервер позволяют обновиться, настоятельно рекомендуем использовать именно его.

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

Решение проблемы средствами JavaScript и PDF.js

Если обновление платформы пока невозможно (например, используется версия 8.3.17), проанализируем ситуацию и исправим код рендеринга. Чтобы шрифты были четкими на любых мониторах, нам необходимо отрисовать холст в увеличенном (внутреннем) разрешении, а затем сжать его до нужных визуальных размеров с помощью CSS-стилей.

Для этого в JavaScript существует специальный параметр window.devicePixelRatio, который возвращает коэффициент масштабирования экрана. Посмотрим на пример модифицированной функции рендеринга страницы:


function handlePages(page) { 
    var scale = 1;
    var viewport = page.getViewport({scale: scale});
    
    var canvas = document.createElement("canvas");
    var context = canvas.getContext('2d');
    
    // Получаем коэффициент масштабирования экрана пользователя
    var outputScale = window.devicePixelRatio || 1;
    
    // Увеличиваем физическое разрешение холста на этот коэффициент
    canvas.width = Math.floor(viewport.width * outputScale);
    canvas.height = Math.floor(viewport.height * outputScale);
    
    // Визуальный размер холста оставляем оригинальным, задавая его через CSS
    canvas.style.width = Math.floor(viewport.width) + "px";
    canvas.style.height = Math.floor(viewport.height) + "px";
    canvas.style.display = "block";
    
    // Передаем матрицу трансформации в контекст рендеринга PDF.js
    var transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
    
    var renderContext = {
        canvasContext: context,
        transform: transform,
        viewport: viewport
    };
    
    var renderTask = page.render(renderContext);
    document.body.appendChild(canvas);
    
    currPage++;
    if (thePDF !== null && currPage <= numPages) {
        thePDF.getPage(currPage).then(handlePages);
    }
}

В этом коде мы умножаем ширину и высоту элемента canvas на коэффициент масштабирования экрана, но визуальный размер в браузере (через стили) оставляем прежним. В результате библиотека отрисовывает больше пикселей, и текст выглядит идеально резко.

Альтернативный способ: принудительное увеличение масштаба рендера

Если первый способ по каким-то причинам (например, из-за специфики старых движков) не дает нужного результата, рассмотрим "грубый", но рабочий метод. Мы можем принудительно заставить PDF.js рендерить страницу в двойном или тройном масштабе.

Для этого переменную scale изначально задаем больше единицы (например, var scale = 2;). Библиотека отрендерит страницу в очень высоком качестве. А чтобы эта огромная картинка поместилась в экран Поля HTML документа, мы задаем холсту жесткие ограничения в CSS:


var scale = 2; // Принудительно увеличиваем качество
var viewport = page.getViewport({scale: scale});
var canvas = document.createElement("canvas");
canvas.width = viewport.width;
canvas.height = viewport.height;
// Заставляем браузер сжать качественную картинку до ширины экрана
canvas.style.width = "100%"; 

Браузер сам сожмет изображение высокого разрешения, и текст останется отлично читаемым, а проблема со смазыванием исчезнет.

Особенности архитектуры 1С: Локальные скрипты и версия движка

Разберем еще несколько важных архитектурных моментов при работе с Полем HTML-документа в 1С.

  1. Отказ от внешних CDN. В исходных примерах кода скрипты библиотеки загружаются с внешних ресурсов. Для корпоративных систем это плохая практика. Если у пользователя на рабочем месте нет выхода в интернет или доступ к CDN заблокирован службой безопасности, PDF-документ просто не откроется. Рекомендуем скачать файлы скриптов библиотеки, сохранить их в конфигурации (например, как общие макеты с типом "Двоичные данные" или "Текстовый документ") и подставлять их код напрямую при формировании HTML-строки.
  2. Проблема движков WebKit и IE. В версии платформы 1С 8.3.17 Поле HTML-документа по умолчанию пытается использовать движок WebKit, но в зависимости от настроек ОС иногда происходит откат к старому движку Internet Explorer (Trident). Версии PDF.js 2.x.x не поддерживают IE 11. Если код выполняется на старом движке, возникнет синтаксическая ошибка JavaScript, и пользователь увидит белый экран. В таких случаях мы рекомендуем использовать специальные "legacy" (устаревшие) сборки PDF.js (например, линейки 1.9), которые адаптированы под старые стандарты ECMAScript.

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

← На главную