Перейти к основному содержимому

Создание табличного документа из MXL-шаблона и экспорт в PDF

Создание табличного документа из MXL-шаблона

Если вы ранее создали макет табличного документа в «1С:Предприятии» и выгрузили шаблон в формате MXL, то вы можете импортировать его в «1С:Шина» для дальнейшей работы: заполнения полей, экспорта в различные форматы, вывода на экран. В общем случае, для того чтобы получить необходимую область макета табличного документа, присвоить в нее параметры и вывести значение данных параметров, необходимо выполнить следующие шаги:

  1. Прочитайте табличный документ из макета:

    исп ПотокМакета = Ресурс{ПФ_MXL_СчетНаОплату.mxl}.ОткрытьПотокЧтения()
    знч МакетПечати = ТабличныйДокумент.Прочитать(ПотокМакета, Истина)
  2. Получите из макета необходимую область:

    пер ОбластьЗаголовок = МакетПечати.ПолучитьОбласть("Заголовок")
  3. Создайте пустой табличный документ и присвойте для удобства объект для записи табличного документа в переменную (в примере — Писатель):

    пер ИтоговыйДокумент = новый ТабличныйДокумент()
    знч Писатель = ИтоговыйДокумент.Запись
  4. Получите выводимую область табличного документа из текущей области и установите в нее необходимые параметры:

    пер ВыводимаяОбластьЗаголовок = ОбластьЗаголовок.ВВыводимуюОбласть().УстановитьПараметры(
    {"ПредставлениеДокумента": "Счет на оплату № 12000018 от 18 ноября 2022 г."}
    )
  5. Выведите область с установленными параметрами в табличный документ:

    Писатель.ВывестиВертикально(ВыводимаяОбластьЗаголовок)

Итоговый документ будет содержаться в переменной ИтоговыйДокумент.

Экспорт документа в PDF

После того как вы вывели в документ все необходимые области с установленными параметрами, вы можете экспортировать документ в PDF. Для этого следует выполнить следующие шаги:

  1. Экспортируйте полученный документ в нужный формат:

    пер БайтыТаблицы = ИтоговыйДокумент.ЭкспортироватьВБайты(ФорматЭкспортаТабличногоДокумента.Pdf)
  2. Создайте двоичный объект из байтов:

    пер СвойстваДвоичногоОбъекта = новый ДвоичныйОбъект.Свойства("ВыгрузкаЗадач").Временные()
    знч ДвоичныйОбъект = ОбъектноеХранилище.ЗагрузитьИзБайт(Байты = БайтыТаблицы,
    Свойства = СвойстваДвоичногоОбъекта)
  3. Вызовите сохранение файла на клиенте:

    ВыгрузкаФайлов.НачатьВыгрузку(ДвоичныйОбъект.Ссылка, "СчетОплаты.pdf")

Пример создания табличного документа из MXL-шаблона и экспорта его в PDF

Далее рассмотрим пример целиком. Предположим, есть шаблон табличного документа, который представляет из себя шаблон счета на оплату и выглядит следующим образом:

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

Приступим к выполнению примера. Создайте новый проект в «1С:Шине». Создайте подсистему и назовите ее ВыводДокумента. Скачайте логотип и MXL-шаблон табличного документа. Добавьте в проект Ресурсы и поместите MXL-шаблон документа, а также логотип в ресурсы проекта:

Создайте новый элемент проекта Общий модуль, назовите его ПечатьДокумента. В этом модуле будет осуществляться чтение шаблона табличного документа, а также заполнение всех необходимых полей. Напишите следующий код:

// Создание структур для удобства работы с данными
@ВПроекте
структура Товар
пер НомерСтроки: Число
пер ПредставлениеНоменклатуры: Строка
пер ПредставлениеКодаНоменклатуры: Строка
пер Количество: Число
пер Цена: Число
пер Сумма: Число
пер СтавкаНДС: Число
пер СуммаНДС: Число
;

@ВПроекте
структура ДанныеПечати
пер БанкПолучателяПредставление: Строка
пер БИКБанкаПолучателя: Строка
пер СчетБанкаПолучателяПредставление: Строка
пер ИНН: Строка
пер КПП: Строка
пер СчетПолучателяПредставление: Строка
пер ПредставлениеПоставщика: Строка
пер ПредставлениеПоставщикаПолное: Строка
пер ПредставлениеДокумента: Строка
пер ПредставлениеПокупателя: Строка
пер Всего: Строка
пер ЗаголовокНДС: Строка
пер ВсегоНДС: Строка
пер РасшифровкаПодписиРуководителя: Строка
пер РасшифровкаПодписиГлавногоБухгалтера: Строка
пер Ответственный: Строка
пер Логотип: Байты?
пер Товары: Массив<Товар> = []
;

// Получение ссылки на итоговый табличный документ
@ВПроекте @НаСервере
@ДоступноСКлиента
статический метод ПолучитьСчет(): ДвоичныйОбъект.Ссылка
знч ТабДок = Печать(ДанныеПечати())
пер БайтыТаблицы = ТабДок.ЭкспортироватьВБайты(ФорматЭкспортаТабличногоДокумента.Pdf)

пер СвойстваДвоичногоОбъекта = новый ДвоичныйОбъект.Свойства("ВыгрузкаЗадач").Временные()
знч ДвоичныйОбъект = ОбъектноеХранилище.ЗагрузитьИзБайт(Байты = БайтыТаблицы, Свойства = СвойстваДвоичногоОбъекта)
возврат ДвоичныйОбъект.Ссылка
;

// Формирование итогового табличного документа
@ВПроекте @НаСервере
статический метод Печать(ДанныеПечати: ДанныеПечати): ТабличныйДокумент
исп ПотокМакета = Ресурс{ПФ_MXL_СчетНаОплату.mxl}.ОткрытьПотокЧтения()
знч МакетПечати = ТабличныйДокумент.Прочитать(ПотокМакета, Истина)

пер ОбластьОтступЗаголовка = МакетПечати.ПолучитьОбласть("ОтступЗаголовка")
пер ОбластьЗаголовокСчетаСЛоготипом = МакетПечати.ПолучитьОбласть("ЗаголовокСчетаСЛоготипом")
пер ОбластьЗаголовок = МакетПечати.ПолучитьОбласть("Заголовок")
пер ОбластьПоставщик = МакетПечати.ПолучитьОбласть("Поставщик")
пер ОбластьПокупатель = МакетПечати.ПолучитьОбласть("Покупатель")
пер ОбластьШапкаТаблицы = МакетПечати.ПолучитьОбласть("ШапкаТаблицы")
пер ОбластьНомерСтраницы = МакетПечати.ПолучитьОбласть("НомерСтраницы")
пер ОбластьСтрока = МакетПечати.ПолучитьОбласть("Строка")
пер ОбластьПодвалТаблицы = МакетПечати.ПолучитьОбласть("ПодвалТаблицы")
пер ОбластьИтого = МакетПечати.ПолучитьОбласть("Итого")
пер ОбластьПодписиБезФаксимиле = МакетПечати.ПолучитьОбласть("ПодписиБезФаксимиле")
пер ОбластьОтветственный = МакетПечати.ПолучитьОбласть("Ответственный")

пер ОбластиПроверкиВывода = новый Массив<ОбластьТабличногоДокумента>()
ОбластиПроверкиВывода.ДобавитьВсе([ОбластьПодвалТаблицы, ОбластьИтого, ОбластьПодписиБезФаксимиле, ОбластьОтветственный])

пер ИтоговыйДокумент = новый ТабличныйДокумент()
знч Писатель = ИтоговыйДокумент.Запись

пер ВыводимаяОбластьОтступЗаголовка = ОбластьОтступЗаголовка.ВВыводимуюОбласть()
Писатель.ВывестиВертикально(ВыводимаяОбластьОтступЗаголовка)

/////////////

знч ОбластьЗаголовокСчетаСЛоготипомПараметры = {
"БанкПолучателяПредставление": ДанныеПечати.БанкПолучателяПредставление,
"ИНН": ДанныеПечати.ИНН,
"КПП": ДанныеПечати.КПП,
"ПредставлениеПоставщика": ДанныеПечати.ПредставлениеПоставщика,
"БИКБанкаПолучателя": ДанныеПечати.БИКБанкаПолучателя,
"СчетБанкаПолучателяПредставление": ДанныеПечати.СчетБанкаПолучателяПредставление,
"СчетПолучателяПредставление": ДанныеПечати.СчетПолучателяПредставление
}

пер ДанныеВыводаЛоготипа = новый ДанныеВыводаИзображенияТабличногоДокумента("Логотип")
ДанныеВыводаЛоготипа.ДанныеИзображения = ДанныеПечати.Логотип

пер ВыводимаяОбластьЗаголовокСчетаСЛоготипом = ОбластьЗаголовокСчетаСЛоготипом.ВВыводимуюОбласть()
.УстановитьПараметры(ОбластьЗаголовокСчетаСЛоготипомПараметры)
.УстановитьДанныеРисунков([ДанныеВыводаЛоготипа])
Писатель.ВывестиВертикально(ВыводимаяОбластьЗаголовокСчетаСЛоготипом)

///////////////

пер ВыводимаяОбластьЗаголовок = ОбластьЗаголовок.ВВыводимуюОбласть()
.УстановитьПараметры({"ПредставлениеДокумента": ДанныеПечати.ПредставлениеДокумента})
Писатель.ВывестиВертикально(ВыводимаяОбластьЗаголовок)

///////////////

пер ВыводимаяОбластьПоставщик = ОбластьПоставщик.ВВыводимуюОбласть()
.УстановитьПараметры({"ПредставлениеПоставщикаПолное": ДанныеПечати.ПредставлениеПоставщикаПолное})
Писатель.ВывестиВертикально(ВыводимаяОбластьПоставщик)

//////////////

пер ВыводимаяОбластьПокупатель = ОбластьПокупатель.ВВыводимуюОбласть()
.УстановитьПараметры({"ПредставлениеПолучателя": ДанныеПечати.ПредставлениеПокупателя})
Писатель.ВывестиВертикально(ВыводимаяОбластьПокупатель)

//////////////

пер ВыводимаяОбластьШапкаТаблицы = ОбластьШапкаТаблицы.ВВыводимуюОбласть()
Писатель.ВывестиВертикально(ВыводимаяОбластьШапкаТаблицы)


// Заполнение информации о товарах
пер НомерСтраницы = 1

для СтрокаТовара из ДанныеПечати.Товары
если не СтрокаПомещается(Писатель, ОбластьСтрока, ОбластиПроверкиВывода)
знч ПараметрыНомераСтраницы = {
"ПредставлениеДокумента": ДанныеПечати.ПредставлениеДокумента,
"ПредставлениеСтраницы": "Страница №" + НомерСтраницы
}

пер ВыводимаяОбластьНомерСтраницы = ОбластьНомерСтраницы.ВВыводимуюОбласть()
.УстановитьПараметры(ПараметрыНомераСтраницы)
Писатель.ВывестиВертикально(ВыводимаяОбластьНомерСтраницы)

НомерСтраницы += 1
Писатель.ВывестиГоризонтальныйРазрывСтраницы()

Писатель.ВывестиВертикально(ВыводимаяОбластьШапкаТаблицы)
;

пер ПараметрыТовара = {
"НомерСтроки": СтрокаТовара.НомерСтроки.ВСтроку(),
"ПредставлениеНоменклатуры": СтрокаТовара.ПредставлениеНоменклатуры.ВСтроку(),
"ПредставлениеКодаНоменклатуры": СтрокаТовара.ПредставлениеКодаНоменклатуры.ВСтроку(),
"Количество": СтрокаТовара.Количество.ВСтроку(),
"ЕдиницаИзмерения": "",
"Цена": СтрокаТовара.Цена.ВСтроку(),
"Сумма": СтрокаТовара.Сумма.ВСтроку()
}

пер ВыводимаяОбластьСтрока = ОбластьСтрока.ВВыводимуюОбласть()
.УстановитьПараметры(ПараметрыТовара)
Писатель.ВывестиВертикально(ВыводимаяОбластьСтрока)
;

пер ВыводимаяОбластьПодвалТаблицы = ОбластьПодвалТаблицы.ВВыводимуюОбласть()
Писатель.ВывестиВертикально(ВыводимаяОбластьПодвалТаблицы)

//////////////

знч ИтогоПараметры = {
"ЗаголовокНДС": ДанныеПечати.ЗаголовокНДС,
"ВсегоНДС": ДанныеПечати.ВсегоНДС,
"Всего": ДанныеПечати.Всего
}

пер ВыводимаяОбластьИтого = ОбластьИтого.ВВыводимуюОбласть()
.УстановитьПараметры(ИтогоПараметры)
Писатель.ВывестиВертикально(ВыводимаяОбластьИтого)

//////////////

знч ПодписьПараметры = {
"РасшифровкаПодписиРуководителя": ДанныеПечати.РасшифровкаПодписиРуководителя,
"РасшифровкаПодписиГлавногоБухгалтера": ДанныеПечати.РасшифровкаПодписиГлавногоБухгалтера
}

пер ВыводимаяОбластьПодписиБезФаксимиле = ОбластьПодписиБезФаксимиле.ВВыводимуюОбласть()
.УстановитьПараметры(ПодписьПараметры)
Писатель.ВывестиВертикально(ВыводимаяОбластьПодписиБезФаксимиле)

//////////////

пер ВыводимаяОбластьОтветственный = ОбластьОтветственный.ВВыводимуюОбласть()
.УстановитьПараметры({"ОтветственныйЗаОформлениеДокумента": ДанныеПечати.Ответственный})
Писатель.ВывестиВертикально(ВыводимаяОбластьОтветственный)

возврат ИтоговыйДокумент
;

// Проверка, что строка помещается на страницу табличного документа
@Локально @НаСервере
статический метод СтрокаПомещается(
Писатель: ЗаписьТабличногоДокумента,
ОбластьСтроки: ОбластьТабличногоДокумента,
ОбластиИтогов: Массив<ОбластьТабличногоДокумента>): Булево

пер МассивПроверки = новый Массив<ОбластьТабличногоДокумента>()

для СтрМас из ОбластиИтогов
МассивПроверки.Добавить(СтрМас)
;
МассивПроверки.Добавить(ОбластьСтроки)

возврат Писатель.ПроверитьВместимостьПоВертикали(МассивПроверки)
;

// Создание структуры, которая содержит данные для формирования счета на оплату
@Локально @НаСервере
статический метод ДанныеПечати(): ДанныеПечати
исп ПотокЛоготипа = Ресурс{Логотип.png}.ОткрытьПотокЧтения()
знч БайтыЛоготипа = ПотокЛоготипа.ПрочитатьКакБайты()

пер ДанныеПечати = новый ДанныеПечати(
БанкПолучателяПредставление = "\"БАНК\" (ПАО) Г. МОСКВА",
БИКБанкаПолучателя = "044778550",
СчетБанкаПолучателяПредставление = "30103220100000000350",
ИНН = "7785233711",
КПП = "773241001",
СчетПолучателяПредставление = "40702852520120154223",
ПредставлениеПоставщика = "ООО \"Компания Поставщик\"",
ПредставлениеПоставщикаПолное = "ООО \"Компания Поставщик\", ИНН 7785233711, КПП 773241001, 1425850, Москва г, тел.: (495) 5555555, доб. 777",
ПредставлениеДокумента = "Счет на оплату № 12000018 от 18 ноября 2022 г.",
ПредставлениеПокупателя = "ООО \"Компания Покупатель\"",
Всего = "",
ЗаголовокНДС = "В том числе НДС:",
ВсегоНДС = "",
РасшифровкаПодписиРуководителя = "Иванов Ю.В.",
РасшифровкаПодписиГлавногоБухгалтера = "Петрова М.А.",
Ответственный = "Иванов А. А.",
Логотип = БайтыЛоготипа,
Товары = []
)

пер ТаблицаТоваров = новый Массив<Товар>()
пер Всего = 0
пер ВсегоНДС = 0

// Запрос к справочнику Товары

пер Запрос = Запрос{ВЫБРАТЬ
Товары.Код КАК Код,
Товары.Количество КАК Количество,
Товары.Цена КАК Цена,
Товары.Наименование КАК Наименование
ИЗ
Товары КАК Товары}

исп Результат = Запрос.Выполнить()

пер НомерТовара = 1
для Товар из Результат
пер СтрокаТовара = СтрокаТовара(НомерТовара, Товар)
ТаблицаТоваров.Добавить(СтрокаТовара)
Всего = Всего + СтрокаТовара.Сумма
ВсегоНДС = ВсегоНДС + СтрокаТовара.СуммаНДС
НомерТовара += 1
;

ДанныеПечати.Всего = Всего.ВСтроку() + " ₽"
ДанныеПечати.ВсегоНДС = ВсегоНДС.ВСтроку() + " ₽"

ДанныеПечати.Товары = ТаблицаТоваров

возврат ДанныеПечати
;

// Создание структуры с данными об отдельном товаре
@Локально @НаСервере
статический метод СтрокаТовара(НомерТовара: Число, Товар: неизвестно): Товар
пер СтавкаНДС = 0.2

возврат новый Товар(
НомерСтроки = НомерТовара,
ПредставлениеНоменклатуры = Товар.Наименование,
ПредставлениеКодаНоменклатуры = "Код товара " + Товар.Код,
Количество = Товар.Количество,
Цена = Товар.Цена,
Сумма = Товар.Цена * Товар.Количество,
СтавкаНДС = СтавкаНДС,
СуммаНДС = (Товар.Цена * Товар.Количество * СтавкаНДС).Округлить(2)
)
;

Затем добавьте в проект справочник и назовите его Товары. В этом справочнике будут содержаться товары, которые позднее будут включены в счет на оплату. Заполните описание справочника соответствующим образом:

ВидЭлемента: Справочник
Ид: 7cbbbbc0-f2b0-4b90-bde0-1fc4efb3bd62
Имя: Товары
ОбластьВидимости: ВПодсистеме
Интерфейс:
Список:
Представление: ""
Форма: АвтоматическаяФормаСписка
Представление: Наименование
Реквизиты:
-
Имя: Код
Длина: 50
-
Ид: 75a42651-799c-4150-86dd-e48081b89c8c
Имя: Количество
Тип: Число
-
Ид: 9bb2831c-7fca-49af-ba32-8e88f47ba66a
Имя: Цена
Тип: Число
-
Имя: Наименование

Также добавьте к справочнику форму списка и назовите ее АвтоматическаяФормаСписка:

Для того чтобы отобразить заполненный табличный документ в интерфейсе приложения, создайте форму и назовите ее ФормаГенерацииСчета. В форму следует добавить два элемента:

  • кнопку генерации счета;
  • компонент, отвечающий за просмотр PDF документа в интерфейсе приложения.

Описание формы может выглядеть следующим образом:

ВидЭлемента: КомпонентИнтерфейса
ОбластьВидимости: ВПодсистеме
Ид: 40d5d2f7-0d84-4cdf-9449-fbfbe20f5e8a
Имя: ФормаГенерацииСчета
Наследует:
Тип: Форма
Содержимое:
Тип: ПроизвольныйШаблонФормы
Содержимое:
Тип: ФиксированнаяГруппа
Содержимое:
-
Тип: Кнопка
Заголовок: Сгенерировать счет
ПриНажатии: ПриНажатииСгенерироватьСчет
-
Имя: ВыводPdf
Тип: ПросмотрPdf

В модуле формы напишите следующий код:

// Обработчик нажатия на кнопку. При нажатии на кнопку происходит формирование
// счета на оплату, вывод счета на экран, а также запускается скачивание
@НаКлиенте
метод ПриНажатииСгенерироватьСчет(Источник: Кнопка, Событие: СобытиеПриНажатии)
попытка
Источник.Доступность = Ложь

пер СсылкаНаДвоичныйОбъектСчет = ПечатьДокумента.ПолучитьСчет()

// Вывод документа на экран
Компоненты.ВыводPdf.Данные = СсылкаНаДвоичныйОбъектСчет

// Сохранение файла на клиенте
ВыгрузкаФайлов.НачатьВыгрузку(СсылкаНаДвоичныйОбъектСчет, "СчетОплаты.pdf")
вконце
Источник.Доступность = Истина
;
;

// Заполнение справочника Товары тестовыми данными
@Обработчик
метод ПослеСоздания()
ЗаполнитьТовары()
;

@НаСервере @ДоступноСКлиента
статический метод ЗаполнитьТовары()
для Индекс = 1 по 50
знч СГ = новый СлучайныйГенератор()
знч Количество = СГ.СлучайноеЦелое(1, 1500)
знч Цена = СГ.СлучайноеЦелое(500, 2500000) / 100

пер Товар = СоздатьТовар(Код = Индекс.ВСтроку(), Наименование = "Товар номер %{Индекс}",
Цена = Цена, Количество = Количество)
;
;

@НаСервере
статический метод СоздатьТовар(Код: Строка, Наименование: Строка, Цена: Число, Количество: Число): Товары.Ссылка
пер Товар = Товары.НайтиПоКоду(Код)
если Товар != Неопределено
возврат Товар
;

пер НовыйТовар = новый Товары.Объект(
Код = Код,
Наименование = Наименование,
Цена = Цена,
Количество = Количество
)
НовыйТовар.Записать()

возврат НовыйТовар.Ссылка
;

Затем добавьте в проект компонент интерфейса типа СтандартноеКлиентскоеПриложениеСРазделами. В командный интерфейс панели навигации следует добавить две команды:

  • команду открытия формы, внутри которой формируется счет на оплату;
  • команду открытия формы списка справочника.

Оформите описание компонента следующим образом:

ВидЭлемента: КомпонентИнтерфейса
Ид: 4d21dd3b-768b-4053-8177-3cfafa23031b
Имя: Главная
ОбластьВидимости: ВПодсистеме
Наследует:
Тип: СтандартноеКлиентскоеПриложениеСРазделами
КомандныйИнтерфейсПанелиНавигации:
Тип: ФрагментКомандногоИнтерфейса<Команда>
Элементы:
-
Тип: НавигационнаяКоманда
Представление: Счет на оплату
ТипФормы: ФормаГенерацииСчета
-
Тип: НавигационнаяКоманда
Представление: Товары
ТипФормы: АвтоматическаяФормаСписка

Опубликуйте проект и откройте приложение. Во вкладке Товары вы найдете справочник с товарами, которые будут включены в счет на оплату. Справочник уже заполнен демонстрационными данными, однако при желании вы можете добавить либо удалить позиции.

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