Выгрузка HTML описаний с картинками (Base64) товаров на сайт/интернет-магазин/B2B, разберем регулярное выражение получения тега body, ПолучитьHTML, ФорматированныйДокумент

24.02.21

Интеграция - Сайты и интернет-магазины

Редактор HTML платформы 1С простой и очень удобный для небольших задач, однако ПолучитьHTML возвращает отдельно картинки и отдельно целиком HTML страницу со ссылкой на имена этих картинок, что неудобно для отправки в базу данных сайта/интернет-магазина/веб-приложения/B2B. Разберем на открытом коде, как решить эту проблему, напишем универсальную функцию получения значения любого тега HTML на регулярных выражениях. Бонусом - возможность редактировать теги HTML в текстовом режиме.

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

В нашем конструкторе веб-приложений EDIbot (подсистема для 1С для создания Dashboard, B2B) тоже возникла необходимость использования в ячейках внутреннего HTML оформления шаблона, покажем на примере:

 

 

Или вот как эта карточка выглядит в вебе -   https://jsonwebapp.com/regexp/json, ссылка на JSON для песочницы.

Итак, нам понятно, что мы хотим получить на выходе нашей публикации, давайте приступим к реализации. 

Функция ПолучитьHTML()  возвращает нам HTML страницу со ссылками внутри неё на ключи картинок ("image001") и заполняет структуру вложений.  

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="format-detection" content="telephone=no" />
<style type="text/css">
body{margin:0;padding:8px;}
p{line-height:1.15;margin:0;white-space:pre-wrap;}
ol,ul{margin-top:0;margin-bottom:0;}
img{border:none;}
li>p{display:inline;}
</style>
</head>
<body>
<p style="text-align: left;"><span style="font-size: 26pt;font-weight: bold;">&lt;body[^&gt;]*&gt;((.|\n)*)&lt;\/body&gt;</span></p>
<p style="text-align: left;"><br></p>
<p style="text-align: left;"><img height="146" src="image001" style="border:none;" width="449"/></p>
</body>
</html>

Как выяснилось, нам это неудобно, и требуется: 

1.Получить значение тега <body> из HTML (без самого тега body), который нам возвращает ПолучитьHTML.

2.Преобразовать получаемые картинки в base64 и заменить на него ключи в теле HTML.

 

Давайте реализуем функцию, которая получает значение произвольного тега HTML без самого тега - ПолучитьЗначениеТегаHTML(HTML, "body").

Проще всего для этого использовать регулярные выражения, в данном случае, нам подойдёт - <body[^>]*>((.|\n)*)<\/body>.

Давайте разберем его:

  1. <body[^>]*> - означает, что нам нужно найти в тексте <body>, причем после слова body может идти любой символ, кроме >. Используем жадный алгоритм (без ?), квантификатор *, т.е. нам подходит ноль или более букв после слова body. В итоге алгоритм найдет и <body>, и <body style="max-width: 1920px;background-color: rgb(166,166,166);">
  2. ((.|\n)*) - означает, что нам подходит любой символ или перевод строки после тега <body>, используем также жадный алгоритм. Скобочки нужны, чтобы выделить значение в отдельную группу (без слова body), которую мы легко сможем получить используя SubMatches. Кстати, если надо найти все теги <p>, то нужно из жадного сделать ленивый, добавив знак вопроса - ((.|\n)*?).  
  3. <\/body> - означает, что шаблон завершается тегом </body>, символ \ экранирует символ /. 

Попробовать его работу можно на сайте - https://regex101.com/r/MCgzCo/1/

Итак, наша функция будет выглядеть следующим образом:

Функция ПолучитьЗначениеТегаHTML(HTML, Тег) экспорт
	
	Результат = HTML;
	
	РегулярноеВыражение = _ОбщегоНазначенияКлиентСервер.НовоеРегулярноеВыражение("<"+Тег+"[^>]*>((.|\n)*)<\/"+Тег+">", Истина, Истина, Истина);			
	
	Выражения = РегулярноеВыражение.Execute(HTML);	
	
	Если Выражения.Count()>0 И Выражения.Item(0).SubMatches.Count()>0 Тогда		
		Результат = СокрЛП(Выражения.Item(0).SubMatches.Item(0));		
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

 

 

В результате обработки этой функцией нашего HTML мы получаем текст:

<p style="text-align: left;"><span style="font-size: 26pt;font-weight: bold;">&lt;body[^&gt;]*&gt;((.|\n)*)&lt;\/body&gt;</span></p>
<p style="text-align: left;"><br></p>
<p style="text-align: left;"><img height="146" src="image001" style="border:none;" width="449"/></p>

Здесь вставленная картинка описывается ключом ("image001") и отправка такой информации на сайт/интернет-магазин/веб-приложение приведёт к отображению страницы без картинки. Чтобы исправить такое положение дел, мы воспользуемся заменой ключей картинок на их значение в формате base64, собственно вот реализация такой процедуры: 

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

 

Теперь мы можем построить нашу итоговую универсальную функцию по сохранению HTML, которая на вход получает форму, объект, вложения HTML и реквизиты формы (типа структура), используемые для HTML редактирования.

Процедура СохранитьHTMLПоля(Форма, Объект, СтруктураВложенийHTML, Реквизиты)экспорт
    
    Если СтруктураВложенийHTML=Неопределено Тогда
        СтруктураВложенийHTML = Новый Структура();
    КонецЕсли;
    
    Для Каждого Реквизит Из Реквизиты Цикл
        
        ВложенияHTMLРеквизита = Новый Структура();
        
        Форма[Реквизит.Значение].ПолучитьHTML(Объект[Реквизит.Ключ], ВложенияHTMLРеквизита);
        
        СтруктураВложенийHTML.Вставить(Реквизит.Ключ, ВложенияHTMLРеквизита);
        
        //сохраним только тело
        Объект[Реквизит.Ключ] = ПолучитьЗначениеТегаHTML(Объект[Реквизит.Ключ], "body");
        
        ЗаменитьКартинкиНаBase64(Объект[Реквизит.Ключ], ВложенияHTMLРеквизита);    
        
    КонецЦикла;    
    
КонецПроцедуры   

 

Пример вызова функции, например, из ПередЗаписьюНаСервере: _ВебАппHTML.СохранитьHTMLПоля(ЭтаФорма, ТекущийОбъект, ВложенияHTML, Новый Структура("_ОписаниеHTML", "_ОписаниеHTMLФорма"));

_ОписаниеHTML - это реквизит метаданных типа неограниченная строка

_ОписаниеHTMLФорма - это реквизит формы типа ФорматированныйДокумент.

 

 

Отлично, мы сохранили с Вами данные, а теперь при открытии в следующий раз их нужно восстановить, т.е. выполнить обратное действие по замене картинок на их ключи. Зачем? А чтобы мы могли потом редактировать теги HTML без пролистывания большого значения base64.

 

Для этого реализуем универсальную функцию  - ВосстановитьHTMLПоля(Форма, Объект, СтруктураВложенийHTML, Реквизиты).

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

 

Бонусом, как и обещал, мы теперь с Вами можем переходить вот в такой режим редактирования:

 

 

Все это легко сделать с помощью разработанных ранее универсальных функций:

&НаСервере
Процедура УправлениеРедактированиемHTML()
	
	Если Объект._РежимРедактированияТекста Тогда
		
		ВложенияHTMLРеквизита = Новый Структура();
		_ОписаниеHTMLФорма.ПолучитьHTML(Объект._ОписаниеHTML, ВложенияHTMLРеквизита);

		Объект._ОписаниеHTML = _ВебАппHTML.ПолучитьЗначениеТегаHTML(Объект._ОписаниеHTML, "body");
		
		Если НЕ ТипЗнч(ВложенияHTML)=Тип("Структура") Тогда
			ВложенияHTML = Новый Структура();
		КонецЕсли;	
		
		ВложенияHTML.Вставить("_ОписаниеHTML", ВложенияHTMLРеквизита);
		
	Иначе
		
		_ОписаниеHTMLФорма.УстановитьHTML(Объект._ОписаниеHTML, ВложенияHTML._ОписаниеHTML);
		
	КонецЕсли;
			
КонецПроцедуры

 

UPD.

Функция НовоеРегулярноеВыражение(Паттерн = "", ИгнорироватьРегистр = Истина, МногострочныйРежим = Ложь, ВсеВхождения = Истина) экспорт
	
	РегулярноеВыражение = Новый COMОбъект("VBScript.RegExp");
	РегулярноеВыражение.Pattern    = Паттерн;
	РегулярноеВыражение.IgnoreCase = ИгнорироватьРегистр;
	РегулярноеВыражение.MultiLine  = МногострочныйРежим;
	РегулярноеВыражение.Global     = ВсеВхождения;
	
	Возврат РегулярноеВыражение;
	
КонецФункции

 

Надеюсь, моя публикация была Вам полезна и сэкономит Ваше время, ссылка на все публикации SizovE.

Подписывайтесь на мой канал (наверху), будет много интересного бесплатного контента :)

SizovE

См. также

Сайты и интернет-магазины Платформа 1С v8.3 1С:Розница 2 Розничная и сетевая торговля (FMCG) Россия Платные (руб)

Готовое интеграционное решение для оплаты покупок Долями в 1C:Розница 2.3. Реализовано в виде расширения. Интеграция сервиса dolyame.ru для приема платежей в рассрочку. Поддерживает работу от разных юридических лиц. Работа: в составе РИБ, отдельно от РИБ, тонкий, толстый клиент, web-клиент (через интернет-браузер).

20400 руб.

19.12.2023    3103    20    8    

20

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс 24. Разработка имеет двухстороннюю синхронизацию 1С и Bitrix24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (платформа начиная с 8.3.23). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    19005    10    16    

17

Сайты и интернет-магазины WEB-интеграция Системный администратор Программист Пользователь Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    16748    15    19    

15

Сайты и интернет-магазины Платформа 1С v8.3 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Управленческий учет Платные (руб)

Расширение для 1С Управление торговлей, реализует: а) Загрузку номенклатуры с сайта с нужными параметрами. б) Позволяет быстро обновлять цены и остатки из 1С в Веб сайт на Битрикс, на лету. (онлайн). в) Моментально прогружать заказы и создавать реализации.

30000 руб.

29.03.2024    796    1    1    

1

Сайты и интернет-магазины Программист Бухгалтер Руководитель проекта Платформа 1С v8.3 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Россия Управленческий учет Платные (руб)

В обработке реализован механизм интеграции между системой поставщика на базе конфигураций 1с(управление торговлей 11) и Личным кабинетом Hoff. Реализован обмен остатками. Обработка реализована и тестировалась для УТ 11.4 Система позволяет выгружать из базы 1с поставщика хофф остатки товаров и другие данные в систему Hoff Преимущества: оперативное и регулярное обновление информации на сайте, уходит двойная работа по вводу остатков в разных системах (1С и личном кабинете HOFF), что чревато возникновением большого количества ошибок в управленческом учете. А также сократятся трудозатраты и повысится прибыль предприятия от продаж. Целевая аудитория: отделы маркетинга, продаж и склад, управленцы из сферы крупного, среднего бизнеса и мелкие предприниматели, владельцы ИП.

29880 руб.

16.11.2022    6586    1    5    

2

Оптовая торговля Розничная торговля Сайты и интернет-магазины Системный администратор Программист Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 10 1С:Управление нашей фирмой 1.6 1С:Управление торговлей 11 Управленческий учет Платные (руб)

Внешняя обработка для обмена данными с интернет-магазином OpenCart. Позволяет быстро наполнить магазин товарами, затем обновлять цены и добавлять новые товары. Далее можно средствами OpenCart настраивать и дополнять карточки товаров как надо для магазина, при этом связь товаров с 1С не теряется.

3840 руб.

30.03.2018    44546    86    139    

89
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. AneJIbcuH 38 22.02.21 17:16 Сейчас в теме
Подскажите, а тут что за функция?
_ОбщегоНазначенияКлиентСервер.НовоеРегулярноеВыражение(
2. SizovE 266 24.02.21 10:19 Сейчас в теме
(1) Спасибо, забыл выложить
Функция НовоеРегулярноеВыражение(Паттерн = "", ИгнорироватьРегистр = Истина, МногострочныйРежим = Ложь, ВсеВхождения = Истина) экспорт
	
	РегулярноеВыражение = Новый COMОбъект("VBScript.RegExp");
	РегулярноеВыражение.Pattern    = Паттерн;
	РегулярноеВыражение.IgnoreCase = ИгнорироватьРегистр;
	РегулярноеВыражение.MultiLine  = МногострочныйРежим;
	РегулярноеВыражение.Global     = ВсеВхождения;
	
	Возврат РегулярноеВыражение;
	
КонецФункции
Показать
3. dimasts 22 16.04.21 23:13 Сейчас в теме
Как быть с картинками имеющими адрес такого типа?
"blob:applewebdata://97a79a97-c02b-4585-8339-fd38316054e7/44b6636c-7eab-494a-a09e-8731d7ee2e92"
Такой адрес имеют все картинки перетасканные в ПолеФорматированногоДокумента
Они не сохраняются при ПолученииHtml и даже при сохранении в ХранилищеЗначений, но агружаются при новом открытии документа.

при перезагрузке ТонкогоКлиента картинки исчезают.
4. SizovE 266 17.04.21 07:40 Сейчас в теме
(3) А Вы пробовали перетаскивать в другие редакторы? Например, зайти сюда, перетащить картинку http://suneditor.com/sample/index.html, посмотреть по кнопке </>, как будет там. Если гуд, то вот Вам как его подключить в одной из моих публикаций https://infostart.ru/1c/articles/1352459/
Оставьте свое сообщение