1С: Еще раз о создании файла DOCX по шаблону без Word на сервере

Подобная статья уже была где-то на сайте, но вот еще одна, но решил актуализировать.

Итак, задача: при нажатии кнопки «В Word», сформировать на сервере файл по шаблону, сохранить его на клиент и открыть любым зарегистрированным приложением. Работать должно кроссплатформенно Linux/Windows

Создадим docx файл вида:

Решение:

{v8 Область.Тушка}

какойто текст, текст, текст. Бла-бла-бла..

{v8 АрбитражныйСудНаименование}

{/v8 Область.Тушка}

Загрузим его в макет как бинарные данные.

Далее код кнопки:


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)	
	ПоказатьОповещениеПользователя("Формирую документ", "", "Формируем документ. Это может занять некоторое время", БиблиотекаКартинок.БизнесПроцесс);	
	Для Каждого ДокументСсылка Из ПараметрКоманды Цикл
		БинарныеДанные = СформироватьДокументНаСервере(ДокументСсылка);
		врмф = ПолучитьИмяВременногоФайла(".docx");
		БинарныеДанные.Записать(врмф);
		
		Оповещение = Новый ОписаниеОповещения("ЗапускПриложения", ЭтотОбъект);
		НачатьЗапускПриложения(Оповещение, врмф, , Ложь);
	 	ПоказатьОповещениеПользователя("Документ сформирован", "", "Дождитесь открытия приложения для работы с документом", БиблиотекаКартинок.БизнесПроцесс);
	КонецЦикла;		
КонецПроцедуры

&НаКлиенте
Процедура ЗапускПриложения(КодВозврата, ДополнительныйПараметр) Экспорт

КонецПроцедуры



&НаСервере
Функция СформироватьДокументНаСервере(ДокументСсылка);
	Возврат Документы.СК_КалькуляторИндексации.СгенерироватьДокумент(ДокументСсылка,"ЗаявлениеОбИндексации");
КонецФункции

Код формирования файла на сервере:

Процедура ДобавитьОписаниеОбласти(НаборОбластей, знач ИмяОбласти, знач ТипОбласти) Экспорт
	НоваяОбласть = Новый Структура;	
	НоваяОбласть.Вставить("ИмяОбласти", ИмяОбласти);
	НоваяОбласть.Вставить("ТипОбласти", ТипОбласти);	
	НаборОбластей.Вставить(ИмяОбласти, НоваяОбласть);	
КонецПроцедуры

Функция ПолучениеОписанияОбластей() Экспорт
	ОписаниеОбластей = Новый Структура;	
	ДобавитьОписаниеОбласти(ОписаниеОбластей, "Тушка", "Общая");
	ДобавитьОписаниеОбласти(ОписаниеОбластей, "Подвал", "Общая");
	ДобавитьОписаниеОбласти(ОписаниеОбластей, "ВерхнийКолонтитул", "ВерхнийКолонтитул");
	ДобавитьОписаниеОбласти(ОписаниеОбластей, "НижнийКолонтитул", "НижнийКолонтитул");
	ДобавитьОписаниеОбласти(ОписаниеОбластей, "НижнийТитульныйКолонтитул", "НижнийТитульныйКолонтитул");		
	Возврат ОписаниеОбластей;		
КонецФункции		


функция ПолучитьДанныеМакета(Знач ИмяМакета)
	
	ОписаниеОбластей = Новый Соответствие;
	ДвоичныеДанныеМакетов = Новый Соответствие;
	ТипыМакетов = Новый Соответствие; 	
	ДвоичныеДанныеМакетов.Вставить(ИмяМакета, ПолучитьМакет(ИмяМакета)); 	
	ОписаниеОбластей.Вставить(ИмяМакета, ПолучениеОписанияОбластей());
	
	Макет = Новый Структура;
	Макет.Вставить("ОписаниеОбластей", ОписаниеОбластей);
	Макет.Вставить("ДвоичныеДанныеМакетов", ДвоичныеДанныеМакетов);
	Макет.Вставить("ТипыМакетов", ТипыМакетов);
	Макет.Вставить("ЛокальныйКаталогФайловПечати", Неопределено); 
	Если НЕ Макет.Свойство("ТипыМакетов") Тогда
		Макет.Макеты.Вставить("ТипыМакетов", Новый Соответствие); 
	КонецЕсли;
	
	
	Возврат Макет;                               
	
Конецфункции                    

Функция СгенерироватьДокумент(ДокументСсылка,ИмяМакета) Экспорт
	
	ДанныеОбъекта = Новый Структура;
	ДанныеОбъекта.Вставить("АрбитражныйСуд", "Самый гуманный суд в мире!");
	
	ДанныеМакетов = ПолучитьДанныеМакета(ИмяМакета);	
	
	ТипМакета = ДанныеМакетов.ТипыМакетов[ИмяМакета];
	ДвоичныеДанныеМакета = ДанныеМакетов.ДвоичныеДанныеМакетов;
	Области = ДанныеМакетов.ОписаниеОбластей;
		
	
	Макет = УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента(ДвоичныеДанныеМакета[ИмяМакета],ТипМакета,ИмяМакета);
	
	Если Макет = Неопределено Тогда
		Возврат "";
	КонецЕсли;
	
	ЗакрытьОкноПечатнойформы = Ложь;	
	

	ПечатнаяФорма = УправлениеПечатью.ИнициализироватьПечатнуюФорму(ТипМакета, Макет.НастройкиСтраницыМакета,Макет);
	АдресХранилищаПечатнойФормы = "";
		
	Если ПечатнаяФорма = Неопределено Тогда
		УправлениеПечатью.ОчиститьСсылки(Макет);
		Возврат "";
	КонецЕсли;	
	
	Область = УправлениеПечатью.ОбластьМакета(Макет, Области[ИмяМакета]["Тушка"]);
	УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеОбъекта);
		
	АдресХранилищаПечатнойФормы = УправлениеПечатью.СформироватьДокумент(ПечатнаяФорма);
			
	УправлениеПечатью.ОчиститьСсылки(ПечатнаяФорма, ЗакрытьОкноПечатнойФормы);
	УправлениеПечатью.ОчиститьСсылки(Макет);
	
	докбин = Новый ХранилищеЗначения(ПолучитьИзВременногоХранилища(АдресХранилищаПечатнойФормы));
	док = докбин.Получить();
	Возврат док;

		
КонецФункции	

Драйвер принтера TCS-210 Linux

Ну не хотят еще до сих пор разработчики драйверов под Linux писать их нормально. Ну как можно сделать драйвера, без возможности добавить свои размеры бумаги? Только хардкор, только ручная правка файла ppd для CUPS.

В ниже представленном драйвере, добавлен размер бумаги 58х28мм, один из распространённых размеров для печати этикеток.

Защита сайта сертификатом p12

Задача: обеспечить вход на сайт только при наличии действующего сертификата формата p12.

Решение:

Инструкция создана на основе нескольких источников, в т.ч. этого и этого, но с внесением поправок что год уже конец 2022, и появились некоторые нюансы, что старые инструкции не работают по умолчанию для новых дистрибутивов.

Сначала создадим корневой сертификат сервера и необходимые для дальнейшей работы файлы и папки. Для этого создадим в любой папке файл root_cer.sh с содержимым вида:

mkdir db                # БД сертификатов
mkdir certs             # ключ и сертификат сервера
mkdir db/certs          # пользовательские сертификаты
mkdir db/newcerts       # новые сертификаты
mkdir p12               # сертификаты для передачи клиентам (p12)
touch db/index.txt
echo "01" > db/serial
openssl req -new -newkey rsa:2048 -nodes -keyout certs/server.key -x509 -days 1024 \
          -subj /C=RU/ST=Vol/L=Vol/O=LTD\ ElkiPalki/OU=Sale/CN=zz/emailAddress=wefwerfwe@gmail.com \
          -out certs/server.crt

, где:

rsa:2048- длина ключа, -days — сколько дней действителен сертификат, -x509 — создаём самоподписаный сертификат, /C — страна, /ST — область, /L — город, /O — организация, /OU — отдел,

Результатом работы будут два файла в папке certs: servert.crt (сертификат) и serverk.key (закрытый ключ). Данные закрытого ключа можно посмотреть при помощи:

openssl rsa -noout -text -in server.key  
openssl x509 -noout -text -in server.crt           

В файле db/serial записывается текущий серийный номер
подписываемого сертификата в шестнадцатиричном формате.

В файл db/index.txt сохраняются данные о подписываемых сертификатах.

Далее необходимо создать файл с настройками для генерации пользовательских сертификатов ca.config:

 [ ca ]
        default_ca             = CA_CLIENT       # При подписи сертификатов  использовать секцию CA_CLIENT

        [ CA_CLIENT ]
        dir                    = ./db            # Каталог для служебных файлов
        certs                  = $dir/certs      # Каталог для сертификатов
        new_certs_dir          = $dir/newcerts   # Каталог для новых сертификатов

        database               = $dir/index.txt  # Файл с базой данных
        # подписанных сертификатов
        serial                 = $dir/serial     # Файл содержащий серийный номер
        # сертификата
        # (в шестнадцатиричном формате)
        certificate            = ./certs/server.crt        # Файл сертификата CA
        private_key            = ./certs/server.key        # Файл закрытого ключа CA

        default_days           = 365             # Срок действия подписываемого
        # сертификата
        default_crl_days       = 7               # Срок действия CRL (см. $4)
        default_md             = sha256          # Алгоритм подписи

        policy                 = policy_anything # Название секции с описанием политики в отношении данных сертификата

        [ policy_anything ]
        countryName            = optional        # Код страны - не обязателен
        stateOrProvinceName    = optional        # ......
        localityName           = optional        # ......
        organizationName       = optional        # ......
        organizationalUnitName = optional        # ......
        commonName             = supplied        # ...... - обязателен
        emailAddress           = optional        # ......

Для автоматизации генерации клиентских сертификатов можно собрать небольшой bash скрипт:

#!/bin/bash
NO_ARGS=0
BASE_DIR=""
P12_DIR="$BASE_DIR/p12"
CA_CFG="$BASE_DIR/ca.config"            # Конфигурационный файл для подписи
CERTS="$BASE_DIR/db/certs"              # Каталог для хранения сертификатов
CA_FILE="$BASE_DIR/certs/server.crt"    # Доверенный сертификат (Им подписывам)

usage () {
  echo "Скрипт basename $0 предназначен для создания клиентских SSL сертификатов."
  echo ""
  echo "Использование: basename $0 email name password"
}

if [ $# -eq "$NO_ARGS" ]  # Сценарий вызван без аргументов?
then
  usage                   # Если запущен без "аргуменотов" - вывести справку
  exit $E_OPTERROR        # и выйти с кодом ошибки
fi

EMAIL=$1
echo "Email:$EMAIL"
NAME=$2
echo "Name:$NAME"
PASSWORD=$3
echo "Password:$PASSWORD"

# создаём запрос на клиентский сертификат
openssl req -new -newkey rsa:2048 -nodes -keyout "$CERTS/$NAME.key" \
        -subj /C=RU/CN=usr/emailAddress="$EMAIL" \
        -out "$CERT/$NAME.csr"

# подписываем запрос на сертификат при помощи доверенного сертификата
openssl ca -config "$CA_CFG" -in "$CERT/$NAME.csr" -out "$CERT/$NAME.crt" -batch

# создаём файл p12 для передачи клиенту
openssl pkcs12 -export -in "$CERT/$NAME.crt" -inkey "$CERTS/$NAME.key" \
        -certfile "$CA_FILE" -out "$P12_DIR/$NAME.p12" -passout pass:"$PASSWORD"

На входе скрипта необходимо задать email, имя пользователя без пробелов и пароль на установку сертификата. На выходе будет запись в БД сертификатов и непосредственно сам контейнер p12 в папке p12 для передачи клиенту.

И ещё один полезный скрипт, для автоматизации отзыва сертификатов revote.sh:

#!/bin/bash
NO_ARGS=0
BASE_DIR=""
CA_CFG="$BASE_DIR/ca.config"
CERTS="$BASE_DIR/db/newcerts"
usage () {
  echo "Скрипт basename $0 предназначен для отзыва клиентских SSL сертификатов."
  echo ""
  echo "Использование: basename $0 serial"
}
if [ $# -eq "$NO_ARGS" ]  # Сценарий вызван без аргументов?
then
  usage                   # Если запущен без "аргуменотов" - вывести справку
  exit $E_OPTERROR        # и выйти с кодом ошибки
fi

SERIAL=$1
echo "Отзываю сертификат: $CERTS/$SERIAL.pem"
openssl ca -config "$CA_CFG" -revoke "$CERTS/$SERIAL.pem"
# составим список отозваных в файл revoked.crl
openssl ca -gencrl -config "$CA_CFG" -out revoked.crl

Посмотреть список отозваных сертификатов можно при помощи команды:

openssl crl -in revoked.crl -text -noout

Осталось только настроить apache для того что бы он пускал на сайт, только при наличии сертификата, добавив:

SSLCACertificateFile /path/to/server.crt
SSLVerifyClient require

1С: Генерация документа DOCX на сервере без установки WORD

Задача: создать по шаблону файл формата Word на сервере 1С предприятие. Кросплатформенно (т.е. никаких COMОбъект).

Первоначально было сделано на основе сохранения табличного документа генерируемого из Макета. Однако в нём сложно получить вычурную разметку, которая необходима в моем случае.

Решение: используем функционал БСП УправлениеПечатью, а именно функцию ИнициализироватьМакетОфисногоДокумента.

1.Создаем документа в формате OpenXML. Любым редактором. Хоть Word хоть LibreOffice. Без разницы. Разметку в нём делаем в соответствии с разделителями вида:

Подробнее о разметке тут

2. Создаем в конфигураторе 1С документ и макет с бинарными данными и загружаем в него этот файл.

3. В Менеджере документа размещаем:

4. В Форме документа размещаем:

В приведенном примере, файл формируется на сервере и открывается для наглядности в Word уже «готовым» на клиенте. В принципе ничего не мешает эту фазу исключить и сразу сохранять полученный с сервера файл куда угодно.




1 2 3 4 5 11