18 июн. 2013 г.

Отдаем PDF через Web-сервис

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

Для начала создадим в пустой конфигурации справочник "Контрагенты" с реквизитом "ИНН" и документ "Счет" с реквизитами "Контрагент" и "СуммаДокумента".
Теперь добавим пакет XDTO "test_ws"с пространством имен "http://www.test-ws.org", в котором опишем тип объекта "File". Он будет содержать свойства:
binaryData - (base64Binary (http://www.w3.org/2001/XMLSchema));
ext - string (http://www.w3.org/2001/XMLSchema);
message - string (http://www.w3.org/2001/XMLSchema).

Создаем web-сервис "DocWork", пространство имен "http://www.test-ws.org", выбираем пакет "http://www.test-ws.org". Добавляем в сервис операцию "CreateBill", возвращаемый тип File (http://www.test-ws.org), входные параметры:
INN - string (http://www.w3.org/2001/XMLSchema);
Summ - decimal (http://www.w3.org/2001/XMLSchema).

Код web-сервиса:
Функция CreateBill(INN, Summ)
 
 typeFile = ФабрикаXDTO.Тип("http://www.test-ws.org", "File");
 
 текФайл = ФабрикаXDTO.Создать(typeFile);
 текФайл.binaryData = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "base64Binary"));
 текФайл.ext = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string"));
 
 Если ПустаяСтрока(INN) ИЛИ Summ = 0 Тогда
  текФайл.message = "empty data";
  Возврат текФайл;
 КонецЕсли;
 
 Запрос = Новый Запрос;
 Запрос.Текст = 
  "ВЫБРАТЬ ПЕРВЫЕ 1
  | Контрагенты.Ссылка
  |ИЗ
  | Справочник.Контрагенты КАК Контрагенты
  |ГДЕ
  | Контрагенты.ИНН = &ИНН";

 Запрос.УстановитьПараметр("ИНН", INN);

 Результат = Запрос.Выполнить().Выгрузить();
 Если Результат.Количество() = 0 Тогда
  текФайл.message = "client not found";
  Возврат текФайл;
 КонецЕсли;
 
 СчетДок = Документы.Счет.СоздатьДокумент();
 СчетДок.Дата = ТекущаяДата();
 СчетДок.Контрагент = Результат[0].Ссылка;
 СчетДок.СуммаДокумента = Summ;
 СчетДок.Записать();
 
 ТабДок = Новый ТабличныйДокумент;
 Документы.Счет.Печать(ТабДок, СчетДок.Ссылка);
 
 ИмяФайла = ПолучитьИмяВременногоФайла("pdf");
 ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);
 ДанныеФайла = Новый ДвоичныеДанные(ИмяФайла);
 
 текФайл.binaryData = ДанныеФайла;
 текФайл.message = "ok";
 текФайл.ext = "pdf";
 
 Возврат текФайл;
КонецФункции
 
Тестовая обработка
&НаСервере
Функция ПолучитьПДФ()

 ОпределениеВС = Новый WSОпределения("http://localhost/testWS/ws/ws1.1cws?wsdl");
 СсылкаВС = Новый WSПрокси(ОпределениеВС, "http://www.test-ws.org", "DocWork", "DocWorkSoap");
 
 ФайлСервис = СсылкаВС.CreateBill(ИНН, Сумма);
 
 Возврат ФайлСервис.binaryData;

КонецФункции// ПолучитьПДФ()


&НаКлиенте
Процедура СоздатьСчет(Команда)
 
 мДанные = ПолучитьПДФ();
 Если мДанные = Неопределено Тогда
  Возврат;
 КонецЕсли;
 мДанные.Записать("c:\temp_bil.pdf");
 
КонецПроцедуры

А так же обещанное видео, как есть, без купюр :)


Комментариев нет:

Отправить комментарий