Подключаемые печатные формы с .DOCX макетом без Word’а




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

25 Comments

  1. newold2

    1 стартмани — это бесплатно?

    Reply
  2. 🅵🅾️🆇

    (1) Вы пропустили в публиции следующий абзац:

    UPD: К сожалению Инфостарт не дает бесплатно выложить обработку, поэтому прикрепляю листинг (ну или напишите мне):

    И вы всегда можете написать мне, Я обязательно отвечу, если в телегу — то практически моментально :3

    Адрес в профиле, редактор не позволил мне прикрепить бесплатно и указать контактные данные.

    Также инфостарт не разрешает давать линк на гитхаб :c

    Reply
  3. newold2

    Каюсь, извиняюсь — действительно пропустил. Подход понравился, сам делал нечто подобное.

    Reply
  4. 🅵🅾️🆇

    (3) Можете написать в личку — обязательно поделюсь)

    Если есть желание поучаствовать — с радостью приму помощь, нереализованный фичи и улучшения описал в статье.

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

    По сути чтоб создать на её основе новую печатную форму — потребуется изменить шаблон и подправить код всего в одной функции. Причем если новая печатная форма также будет касаться сотрудника — можно ограничится только редактированием макета.

    ЗЫ: есть еще подключаемая, самозаполняемая печатная форма по справкам по сотруднику.

    Но код там местами не очень, поэтому выложить могу только обфусцированной, иначе мне будет слегка неуютно)

    Reply
  5. spy-83

    картинки из 1с можно вставить в макет word с помощью вашей обработки?

    к примеру вывести основное изображение номенклатуры

    Reply
  6. 🅵🅾️🆇

    (5) Пока нельзя, но технически в этом нет ничего сложного.

    Вордовский файл это по сути архив с xml файлами и вложениями.

    Если вставить в шаблон картинку, то она окажется в отдельном каталоге и её можно будет заменить.

    Reply
  7. spy-83

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

    Reply
  8. 🅵🅾️🆇

    (7)

    заранее неизвестно количество строк

    Исходные файлы xml ворда толком ничем не отличаются от html документа.

    Вы же не будете утверждать, что невозможно сверстать веб страничку в 1с?)

    заранее не получится вставить саму картинку

    Ну как вы обычно выводите картинки в табличный документ?

    Вы вставляете некую заготовку, а потом заменяете её на нужное изображение.

    Так и здесь. При разархивировании docx получаете изображение которое вставили в документ шаблоном ранее.

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

    Вообще xml документы имеют ссылки между собой и вполне ясно говорят, что и как они подключают.

    Если тут есть гуру XDTO — то в теории можно будет научить 1с’ку читать ворд довольно изящно.

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

    Reply
  9. jONES1979

    Здравствуйте!

    А этот проект есть на гитхаб? Можно ссылку или идентификатор для поиска?

    Reply
  10. 🅵🅾️🆇

    (9) Привет. Да, есть.

    Ссылки на гит тут, вроде как, запрещено прикреплять.

    Но в отдельный репозиторий не выносил, а также никак не могу заставить себя выкладывать на гит именно исходный код, а не бинарники.

    Давайте попробуем так, оставлю свой никнейм: PlugFox

    И некий относительный путь: ones/Обработки и отчеты/Обработки/RMR СоглашениеОНеразглашенииИнформации.epf

    Если что — всегда отвечу в личку.

    Reply
  11. Sanek_159

    Добрый день.

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

    Если в Процедуре «ЗаполнитьПараметрМакета» где устанавливается «ПараметрМакета» заменить Символы.НПП на » » (пробел), то параметры все открываются слитно с соседними словами.

    Неразрывный пробел не подходит, т.к. параметров может быть много и ворд распределяет текст не корректно.

    Reply
  12. 🅵🅾️🆇

    (11) Привет, насколько помню, можно подредактировать и сделать более удобно.

    Насколько помню, это связано с тем, что редактируя макет Word в Word’е он вставляет туда кучу лишнего мусора и без неразрывного пробела, в некоторых случаях, слова могут слипаться.

    Я постараюсь сделать более удобно в дальнейшем, но не в ближайшее время, тк сильно загружен, да еще и пишу огромную статью про inline webhook telegram бота.

    Reply
  13. 🅵🅾️🆇

    Исправил «исчезновение» пробелов рядом с переменными

    Оно возникало от того, что пропадали пробелы в содержимом «w:r/w:t[@xml:space=’preserve’]» блоков.

    Пример модуля обработки:

    http://git.pfx.pw/snippets/1

    Обратите внимание на область Работа_с_word

    и в частности на добавленную функцию: ЗаполнитьПробелы()

    и закоменченное добавление неразрывных пробелов в функции ЗаполнитьПараметрМакета()

    Reply
  14. sytkosa

    (13) Привет. Можете пере выложить решение проблемы «исчезновение пробелов».

    Заранее спасибо

    Reply
  15. 🅵🅾️🆇

    (14) gist.github.com

    Перевыложил.

    На домашнем сервере, просто, перешел с gitlab на gitea)

    Reply
  16. Xershi

    Интересное решение.

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

    А то пока все не прочитал, не понял, что вы тут сделали!

    Структуру ворда сами разбирали?

    А если нужен устаревший формат?

    Reply
  17. 🅵🅾️🆇

    (16)

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

    А то пока все не прочитал, не понял, что вы тут сделали!

    К сожалению крайне не хватает времени на публикации.

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

    Может следующая статья будет про это + полуавтоматическое подключение и обновление печатных форм в куче конфигураций одним батником)


    Структуру ворда сами разбирали?

    А если нужен устаревший формат?

    Да, сам, это просто xml, парсю его с помощью XPath выражений.

    .doc — не xml, он в корне отличается, это бинарный формат. Сделать нативно средствами 1с тоже можно, но мне явно не до этого сейчас)

    Reply
  18. Xershi

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

    Reply
  19. 🅵🅾️🆇

    (18)

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

    Название статьи, внезапно:

    Подключаемые печатные формы с .DOCX макетом без Word’а

    А .docx появился в 2007 ворде, если не изменяет память.

    2003 ворд — это уже прям раритет, вы в нем очень многое не сможете открыть)))

    Reply
  20. Xershi

    (19) название статьи конечно говорит, но чтобы не было лишних вопросов, как у меня допустим. Мало ли там просто букву убрать и заработает!

    Reply
  21. 🅵🅾️🆇

    (20) Добавил дополнительно заметочку в статью)

    Reply
  22. Xershi

    (21) если бегло читать статью внимание падает не на особенности, а на ваше слово «RED». Читающему что и зачем — это просто мусор))

    Думаю стоит над акцентами поработать. Но как минимум одним вопросом меньше!

    Reply
  23. 🅵🅾️🆇

    (22) Здорово) Спасибо за фидбэк.

    Возможно в будущем статьи будут правиться корпоративным редактором, ну или как минимум постараюсь выработать шаблон (пока еще в поиске себя).

    Reply
  24. AlexAdm

    Добрый день. Заинтересовала данная обработка, можете поделиться?

    Reply
  25. 🅵🅾️🆇

    (24) plugfox@gmail.com

    telegram: @plugfox

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *