Многие разработчики и администраторы систем на базе «1С:Предприятие 8.3» сталкиваются с коварной проблемой: при ручном сохранении печатной формы через меню «Файл — Сохранить» документ PDF выглядит идеально, но стоит запустить программное сохранение (например, для отправки счета по почте или выгрузки архива), как правый край текста оказывается обрезанным. Ситуация осложняется тем, что ошибка может проявляться «плавающим» образом: то работать нормально, то портить верстку даже в рамках одного сеанса.
В этой статье мы подробно разберем причины возникновения этого эффекта, проанализируем внутренние механизмы платформы и выработаем комплекс мер по устранению проблемы.
Первым делом проанализируем ситуацию: почему ручное сохранение работает, а программное — нет? Разгадка кроется в контексте выполнения операции. Когда пользователь нажимает кнопку «Сохранить» в интерфейсе, формирование PDF происходит на стороне тонкого клиента. В этом случае 1С использует графические ресурсы локальной станции пользователя (библиотеки GDI+, шрифты, настройки монитора).
Программное сохранение в большинстве современных конфигураций (особенно в «Бухгалтерии предприятия 3.0») происходит на стороне сервера в фоновом задании. Серверный сеанс «не видит» графическую оболочку и работает в изолированном окружении. Именно здесь возникает критическая ошибка расчета ширины колонок, известная в баг-трекере 1С под номером 10230477.
Суть данной ошибки заключается в том, что при выполнении метода Записать() для объекта ТабличныйДокумент на стороне сервера, платформа может некорректно вычислять метрики шрифтов. Если на сервере выполняется несколько параллельных потоков генерации документов, кэш графической подсистемы начинает выдавать неверные значения. В результате 1С «думает», что текст помещается в ячейку, но при итоговой отрисовке в PDF символы оказываются чуть шире, и край документа обрезается.
Рассмотрим, какие факторы усугубляют эту проблему:
ragent, нет установленного принтера, расчеты производятся по «дефолтным» (часто некорректным) параметрам.Проанализируем шаги, которые необходимо предпринять системному администратору для стабилизации работы сервера 1С. Выполним следующие действия:
C:\Windows\System32\config\systemprofile\DesktopC:\Windows\SysWOW64\config\systemprofile\Desktop (для 64-битных систем)Если настройка сервера не помогла полностью, перейдем к модификации программного кода. Посмотрим на пример стандартного сохранения документа:
// Пример программного сохранения
ТабДок = Новый ТабличныйДокумент;
// ... формирование печатной формы ...
ТабДок.АвтоМасштаб = Истина;
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);
Как мы выяснили, свойство АвтоМасштаб иногда игнорируется платформой при записи в PDF на сервере. Разберем «мягкий» способ решения: принудительное уменьшение масштаба на несколько процентов. Это даст необходимый запас пространства, чтобы текст не обрезался.
// Применяем обходной путь (workaround)
ТабДок.АвтоМасштаб = Ложь; // Отключаем автостандарт
ТабДок.МасштабПечати = 97; // Устанавливаем 97% вместо 100%
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);
Также проанализируем свойство ячеек макета. Опытным путем установлено, что если в макете для проблемных колонок установлено свойство РазмещениеТекста в значение Авто, риск обрезания выше. Рекомендуется в макете конфигурации явно установить значение Переносить. Это заставит алгоритм 1С более тщательно просчитывать границы блока.
Поскольку проблема часто связана с переполнением или порчей кэша метрик шрифтов внутри процесса rphost, временным решением является «мягкий» перезапуск кластера. Рассмотрим, как это сделать правильно:
Не обязательно полностью останавливать службу 1С, прерывая работу всех пользователей. Можно настроить в консоли администрирования кластера параметры перезапуска рабочих процессов. Установите Выключать через и Интервал перезапуска, чтобы процессы rphost обновлялись автоматически раз в сутки. Это очистит накопившиеся ошибки в памяти, связанные с генерацией PDF.
Если специфика бизнес-процесса позволяет, рассмотрим вариант переноса сохранения на сторону клиента. Вместо того чтобы формировать файл в фоновом задании на сервере, мы можем вернуть сформированный ТабличныйДокумент на форму и вызвать диалог сохранения там:
&НаКлиенте
Процедура СохранитьДокумент(Команда)
// Получаем сформированный документ с сервера
ТабДок = ПолучитьПечатнуюФормуНаСервере();
// Вызываем стандартный диалог сохранения
ТабДок.Показать(); // Или сразу Записать() в контексте клиента
КонецПроцедуры
Этот метод гарантированно решает проблему обрезания краев, так как задействует локальные графические ресурсы пользователя, а не ограниченные ресурсы сервера.
Подводя итог, отметим, что обрезание PDF в 1С — это комплексная проблема, сочетающая в себе баги платформы и особенности настройки Windows Server. Для стабильного результата мы рекомендуем комбинировать настройку виртуального принтера на сервере с небольшим уменьшением МасштабПечати в коде (до 95-98%). Это обеспечит визуальную целостность документов даже при возникновении микроскопических погрешностей в расчете ширины шрифтов.