Как сохранить табличный документ в PDF и распечатать его в мобильном приложении 1С?

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

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

Проблема формирования корректного пути к файлу

Одной из первых трудностей, с которой сталкиваются разработчики, является синтаксическая ошибка при указании пути сохранения. Рассмотрим ситуацию: при попытке записи файла стандартным методом ТабДок.Записать() система может выдать ошибку или просто не создать файл. Выясним причину на примере кода, который часто приводит к неудаче:


// Ошибочный вариант
ВрФайл = "file://" + КаталогДокументов() + "print.pdf";
ТабДок.Записать(ВрФайл, ТипФайлаТабличногоДокумента.PDF);

Проанализируем этот фрагмент. В мобильной платформе 1С метод Записать() ожидает в качестве первого параметра физический путь к файлу в файловой системе устройства, а не URI (Uniform Resource Identifier). Добавление префикса file:// делает путь невалидным для операционной системы. Разберем правильный способ формирования пути:


// Рабочий вариант
ВрФайл = КаталогДокументов() + "print.pdf";
ТабДок.Записать(ВрФайл, ТипФайлаТабличногоДокумента.PDF);

Важный нюанс: использование функции КаталогДокументов() оправдано, если файл должен быть доступен пользователю или другим приложениям. Однако, если PDF нужен только на время печати, рекомендуется использовать КаталогВременныхФайлов(), чтобы не забивать память устройства лишними данными, которые автоматически не удаляются.

Интеграция с внешними приложениями для печати через Intent

Если мобильное приложение 1С не видит принтер напрямую (например, используется специфическая «китайская» модель без драйверов AirPrint или Mopria), оптимальным решением будет передача сформированного PDF во внешнее приложение, такое как PrintHand. Для этого воспользуемся механизмом Intent в Android. Рассмотрим, как это реализовать программно:

  1. Сначала формируем и сохраняем табличный документ в PDF, как было описано выше.
  2. Затем вызываем стандартное действие Android VIEW, указывая тип данных (MIME-type).

// Пример вызова внешней печати
ИмяФайла = КаталогДокументов() + "print.pdf";
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);

ЗапускПриложения = Новый ЗапускПриложенияМобильногоУстройства("android.intent.action.VIEW");
ЗапускПриложения.Данные = "file://" + ИмяФайла; // Здесь префикс file:// нужен для Android Intent
ЗапускПриложения.Тип = "application/pdf";
ЗапускПриложения.Запустить(Истина);

В этом случае операционная система предложит пользователю выбрать приложение, способное открыть PDF. Выбрав сервис печати (например, PrintHand), пользователь сможет отправить документ на принтер.

Работа с FileUriExposedException на новых версиях Android

Проанализируем современную ситуацию с безопасностью Android (версии 7.0 и выше). Попытка передать прямой путь через file:// в стороннее приложение приведет к ошибке безопасности FileUriExposedException. Система блокирует доступ внешних программ к внутренней папке приложения 1С. Чтобы решить эту задачу, необходимо использовать защищенные ссылки content://.

В мобильной платформе 1С для этого предусмотрен специальный метод ПолучитьContentUriФайла(). Рассмотрим актуальный алгоритм работы:


ПутьКФайлу = КаталогВременныхФайлов() + "invoice.pdf";
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);

#Если МобильноеПриложениеКлиент Тогда
    // Преобразуем путь в безопасный URI для Android
    БезопасныйПуть = СредстваМобильногоПриложения.ПолучитьContentUriФайла(ПутьКФайлу);
    
    ЗапускПриложения = Новый ЗапускПриложенияМобильногоУстройства("android.intent.action.VIEW");
    ЗапускПриложения.Данные = БезопасныйПуть;
    ЗапускПриложения.Тип = "application/pdf";
    // Разрешаем внешнему приложению читать наш файл
    ЗапускПриложения.ДополнительныеДанные.Добавить("android.intent.extra.STREAM", БезопасныйПуть); 
    
    ЗапускПриложения.Запустить(Ложь);
#КонецЕсли

Настройка параметров страницы для корректного отображения

Перед тем как вызвать метод Записать(), крайне важно убедиться, что табличный документ подготовлен к мобильному выводу. Шрифты в мобильных ОС ограничены, а размеры экранов и бумаги могут сильно варьироваться. Разберем основные настройки ТабличныйДокумент, которые помогут избежать «съезжания» верстки:

1. Автомасштабирование. Обязательно устанавливайте Автомасштаб = Истина. Это позволит 1С автоматически подогнать ширину колонок под размер листа PDF, что критично для узких чековых лент или формата A4.

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

3. Шрифты. Рекомендуется использовать стандартные шрифты (Arial, Times New Roman), так как при отсутствии шрифта в системе 1С заменит его на стандартный мобильный шрифт, что может изменить размеры текста и привести к обрезанию слов.


ТабДок.Автомасштаб = Истина;
ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
ТабДок.ПолеСверху = 5;
ТабДок.ПолеСнизу = 5;
ТабДок.ПолеСлева = 5;
ТабДок.ПолеСправа = 5;

Использование встроенных средств печати (для версий 8.3.10+)

Выясним, когда можно обойтись без сохранения в PDF. В современных версиях мобильной платформы появился метод ТабличныйДокумент.Напечатать(). Этот метод вызывает системный диалог печати (Android Print Framework или iOS AirPrint). Если принтер поддерживает современные протоколы или на устройстве установлен плагин печати от производителя (HP, Samsung, Canon), то это самый простой и надежный способ.


// Прямой вызов системной печати
ТабДок.Напечатать(Истина); // Истина - показывать диалог настроек

Однако, как показывает практика (и сообщение автора в теме), на специфическом оборудовании («китайские» принтеры) этот метод может приводить к зависанию приложения. В таких случаях возврат к схеме «PDF + внешнее приложение через Intent» остается единственным рабочим вариантом.

Оптимизация изображений в печатных формах

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

Альтернатива: Прямая печать ESC/POS

Если ваша задача — печать чеков на мобильном термопринтере, использование PDF может быть избыточным. Для таких целей программисты часто используют прямую отправку байт-кодов на языке ESC/POS через Bluetooth-сокет. Это позволяет избежать проблем со шрифтами и масштабированием, так как команды управляют принтером напрямую на низком уровне. В 1С это реализуется через объект ПоследовательностьBytes и запись в поток, открытый через системные средства мобильной платформы.

Подводя итог, можно сказать, что связка ТабДок.Записать(Путь, PDF) и последующий вызов Intent — это универсальный «костыль», который выручает в 90% случаев при работе с нестандартным оборудованием в мобильной среде 1С.

← На главную