Работа с файлом PDF из 1С




Принцип обмена данными из 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='\

43 Comments

  1. cool.vlad4

    делал свою компоненту Native на C++ пару лет назад, все никак руки доделать не дойдут ибо сейчас это не актуально, то что нашел, прикрепил. умеет сохранять страницы в текст(правда там поленился убрать вывод информации по шрифтам и прочему), в png, количество страница…но основная цель была сохранение в png

    Reply
  2. cool.vlad4

    (1)

    м и прочему), в png, количество страница…но осн

    если найду, выложу еще компоненту делал, которая наоборот собирает из изображений pdf

    Reply
  3. Margo462

    (1) обязательно пригодиться, спасибо)

    Reply
  4. DarkAn

    Я в свое время тоже разбирался с разбиением ПДФов. Мне понравилась программа GostScript, в ней разбиение многостраничного файла делается одной командой: вот строка из bat-файла

    call «C:Program Filesgsgs9.20ingswin64.exe» -q -dSAFER -dBATCH -dNOPAUSE -sDEVICE=jpeg -r100 -sPAPERSIZE=a4 -sOutputFile=»Z:!doc-%03d.png» «Z:!1234.pdf»

    Здесь:

    «Z:!1234.pdf» — путь к многостраничному фалу

    -sOutputFile=»Z:!doc-%03d.png» — параметр говорит о создании файлов по маске (1 страница — 1 файл): doc-001.png, doc-002.png, doc-003.png, …

    В свое время остановился, на попытке понять как обработать не 1, 2, 3 многостраничный файлов, а 100+ (так до конца и не разобрался с параметрами). Может время придет — вернусь к работе

    Reply
  5. DarkAn

    (4) Вот мануал по Ghostscript

    http://web.mit.edu/ghostscript/www/Use.htm

    Reply
  6. DrAku1a

    Без компонент, на двоичных данных бы… За такое и 10 $m не жалко будет!

    Где-то на ИС встречал в комментариях «Количество страниц в PDF-файле».

    Reply
  7. Margo462

    (6) интересно…хотелось бы, а то этот конвертер PDF2TXT на 30 дней, еще ключи искать, бесплатную прогу найти пока не смогла

    Reply
  8. Dzenn

    Согласен, pdftk хорошая, годная компонента

    Reply
  9. DarkAn

    (6) (7) Из личного: для решения описанной задачи (0) мы сначала воспользовались программой ABBYY Scan Station (ABBYY — по запросу спокойно предоставляет 30-дневный ключ, спокойно предоставили продление еще на 1 месяц, для тестов), после чего мы сделали приобретение, т.к. софтина ОЧЕНЬ проста в настройке и хорошо выполняет обозначенную задачу (но без распознавания).

    Единственный ее недостаток и весьма значительный — это не возможность ее запустить с командной строки — то есть нет запуска по расписанию.

    Но из плюсов я бы назвал цену 2-3 года назад она составляла 24 000 руб. или 10 часов франча (на тот момент).

    Так мы поигрались наверное с год, пока мне не надоело запускать каждый день данную сфотину и мы приобрели ее расширенную версию — ABBYY Recognation Server. В данной софтине настроек и возможностей поболее — работает на УРА уже 1,5 года. Есть еще распознавание и индексирование — последнее требует работу оператора (при приобретении удалось зачесть стоимость ранее приобретенной ABBYY Scan Station).

    По ценам уже значительно дороже и цена зависит от количества распознанных страниц в месяц. На сегодня у нас 50к страниц и этого пока хватает (1 числа каждого месяца счетчик сбрасывается).

    Цены опять же в открытых источниках не найти, но я их так же приведу для понимания: Сама программа + лицензия на 15к страниц — 215 000 руб, апгрейд с 15к до 50к страниц- 170к руб, апгрейд с 15к до 100к страниц — 247к руб (цены на июль 2016)

    Стоимость разовая и в дальнейшем доплат не требует.

    Это не реклама, просто показал, что решили использовать у нас в организации. Иногда может быть значительно эффективнее купить готовый продукт, чем писать свое с нуля. С нуля для разработчика хорошо — ты учишься работать с «новым», но работодатель не всегда может быть заинтересован оплачивать таким образом твое обучение, если стоит вопрос в сроках и качестве (ведь сколько еще времени уйдет на отладку «подводных камней»).

    P.S.

    Кстати в 1С Документооборот используют так же сторонние библиотеки, тот же самый GostScript указанный в (4) для «распиливания» файлов, а для распознавания другую не помню как называется. От туда можно было бы глянуть как они это делают, но пока у меня нет на это времени да и описаный выше софт решает поставленную задачу.

    Reply
  10. Margo462

    (9) за 215 тр я сама буду эти файлы распознавать 😀 слишком дорого))

    Reply
  11. DarkAn

    (10) ну я же в конце дал наводку, где посмотреть, как делают в 1С 🙂

    Reply
  12. Margo462

    (11) будем изучать)

    Reply
  13. DarkAn

    (10) Кроме того вопрос цены, это не вопрос разработчика — не его это зона ответственности. А финансового директора или Гл. буха. Придете к ним и спросите: поставленную задачу можно решить как минимум 2мя путями. Первый вот счет на 215к и запустим через 3-5 дней. Второй писать самим, но так как мы с этими библиотеками еще не работали (опыта нет) то для полной автоматизации может потребоваться гораздо больше времени и разработчик будет занят и еще по ходу дела ошибки будем отлаживать 🙂 Вот они пусть и принимают решение о том дорого это или нет, но ни как не разработчик 🙂

    Reply
  14. Margo462

    (13) я думаю что даже если бы прога 1 тр стоила, то все равно пришлось бы искать бесплатный способ)

    Reply
  15. DarkAn

    (14) Еще раз повторюсь, стоимость это не вопрос разработчика.

    (14)

    я думаю

    — это подтверждает. Решается приближенно достаточно просто. Возьмите свою часовую ставку помножте ее на предполагаемое время разработки и изучения, потом помножте еще раз на 2 и сравните со стоимость программы. Это приблизительно 🙂

    Reply
  16. kraynev-navi

    (2) Иногда вот так сталкиваешься, часами ищешь решение как ТС. Крутишь ghost, sumatra (https://www.sumatrapdfreader.org/docs/Command-line-arguments.html — кстати, бесплатная тулза), пробуешь на своих данных и мощностях и думаешь, блин, ну умел бы писать нативные компоненты, написал бы уже изящно и работало бы всегда.

    Спасибо за труд! (утащил к себе в нору)

    Reply
  17. Margo462

    (15) то, что мне нужно было готового такого нет, я скоро опубликую обработку где я это применила, по мне так проще программу PDF2TXT оплатить, там вроде 2 тр она стоит и обновления в течение года))

    Reply
  18. DarkAn

    (17)

    что мне нужно было готового такого нет

    Ну Вы же не описали, что Вам нужно. А то что описано, я привел альтернативы и их значительно больше и по разной цене. Все зависит от Вашей занятости 🙂

    Но мы уже отходим от темы. Появится Ваша разработка посмотрим, насколько она «уникальна». Даже самому интересно, так как механизм прикрепления файлов к объектам базы 1С сам реализовывал. Но у Вас возможно другая разработка, но интересные идеи и направления можно найти.

    Reply
  19. borodatii

    А зачем сначала перегонять PDF в ДвоичныеДанные, а потом их сохранять как PDF? Я про первые 4 строки кода.

    Reply
  20. Margo462

    (19) да это наверное уже лишнее, раньше ошибка была, потом не убирала просто, щас уберу)

    Reply
  21. Margo462

    (18) https://infostart.ru/public/724762/ вот, ну это я сама такое придумала как к выпискам pdf подцеплять, может у кого-то будут другие мысли как это осуществить))))

    Reply
  22. DarkAn

    (21)

    думала как к выпискам pdf

    Спасибо!

    Reply
  23. Margo462

    (22) убрала с публикации, как исправлю на временный каталог тогда опубликую)

    Reply
  24. Lewkis

    Всем добрый день. Хочу тоже поделиться своими наработками в этой области. Делал для своих нужд скрипт на Python для извлечения текста из PDF.

    Если интересно, вот ссылка https://github.com/yoyuyoppe/Converter-PDF.git.

    Зависимости: должен стоять python 3.x и библиотека для разбора pdf (pip install pdfminer3k)

    Приложил пример запуска скрипта из 1С.

    Reply
  25. 🅵🅾️🆇

    (0) (1) Можно воспользоваться tesseract ocr (смотрите на github’е)

    Там крайне много возможностей, в том числе можно получать не только сырой текст, но и положение онного на странице.

    Ставиться не сложно, на лине так вообще одной строкой в терминале.

    Под винду уже есть собраные версии.

    Reply
  26. 🅵🅾️🆇

    (6) Предположу, что там использовался некий маркер в ДД PDF файла.

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

    UPD:

    Попробуйте взять бесплатный HxD и поковырять различные PDF файлы, как с текстом, так состоящие из картинок.

    UPD 2:

    (0) Глянул сам, прям на вскидку как определить количество страниц:

    Подключаете файл как поток двоичных данных на чтение, считаете количество повторений («/Type/Page»)

    Попробуйте глянуть HxD ручками, все станет понятно.

    Но вероятнее всего есть способ еще проще, в PDF файле может содержаться некий маркер который заранее «знает» количество страниц.

    Reply
  27. 🅵🅾️🆇

    (7) Можно воспользоваться tesseract ocr (смотрите на github’е)

    Там крайне много возможностей, в том числе можно получать не только сырой текст, но и положение онного на странице.

    Ставиться не сложно, на лине так вообще одной строкой в терминале.

    Под винду уже есть собраные версии.

    UPD:

    Если вопрос стоит как «искать ключи», то очивидный FineReader очивиден, дальше торрентов искать не придеться 😉

    Также практически на 100% уверен, что у гугла есть подобный вебсервис, там вроде хотели денюжек, но крайне мало и возможно есть «триал».

    Reply
  28. cool.vlad4

    (25) ага, и качество распознавания ниже плинтуса, пробовал я его, тут речь идет об извлечении текста, который не нужно распознавать, он и так текст

    Reply
  29. Margo462

    (27) посмотрите я дополнила статью, нашла бесплатное приложение pdftotext, работает тоже из командной строки 🙂

    Reply
  30. Margo462

    (18) посмотрите я дополнила статью, нашла бесплатное приложение pdftotext, работает тоже из командной строки 🙂

    Reply
  31. Margo462

    (24) посмотрите я дополнила статью, нашла бесплатное приложение pdftotext, работает тоже из командной строки 🙂

    Reply
  32. 🅵🅾️🆇

    (29) Это не спортивно :3

    Я прохлопал ушами, что у вас изначально PDF содержащий сырой текст:

    https://habrahabr.ru/post/69568/

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

    Reply
  33. spezc

    Хорошая статья, держи звезду.

    Reply
  34. spezc

    По горячим следам задам вопрос, кто знает как из 1С вставить картинку в PDF? У меня есть скан документа в PDF, у меня есть *.png/*.gif с макетом печати. Мне нужно получить PDF, в котором будет этот шаблон печати будет добавлен на первую (на все) страницу оригинального PDF?

    Reply
  35. altu71

    Можно упростить процесс, если использовать iFilter для PDF, например отсюда ADOBE. Тогда текст можно получить сразу из PDF файла объектом «ИзвлечениеТекста»

    Reply
  36. Margo462

    (35) пробовала, не получается, у нас adobe reader ограниченная версия, может поэтому…

    Reply
  37. altu71

    Ссылка, которую я вставил, на бесплатный официальный установочный файл от adobe. Достаточно его одного, можно acrobat вообще не ставить

    Reply
  38. Margo462

    (37) спасибо, как нибудь попробую, может получится в этот раз

    Reply
  39. eugenevk

    Хорошо описан pdftk server. Правда не учтено, что программа совершенно не переваривает русские буквы в каталогах и именах файлов. Когда-то давно с этим сталкивался. Проверил, все по-прежнему. Не хотят зарубежные разработчики поддерживать utf(

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

    Reply
  40. plus_sign

    (39)Большое спасибо за способ обхода проблемы с русскими буквами. Пригодилось в работе.

    Часть команд pdftk без проблем глотают русские буквы в любом количестве. А вот команды dump_data* и правда не воспринимают русские буквы в имени выходного файла.

    Reply
  41. sharonovev

    (1)Наше то,. что долго искал.

    Есть вопрос — попробовал использовать закомментированный кусок кода:

    ДвДанные = Конвертер.ПолучитьДанныеИзображения();

    Платформа благополучно отъезжает.

    На сохранении файла — работает корректно все.

    Этот метод работает?

    (1)

    Reply
  42. kras01

    Если надо кому,переделал обработку из поста 1 под управляемые формы

    Reply
  43. ReDvAlL
    Далее программа Pdftk server при помощи команды «cat + «номер страницы» + output» разбила мне файл PDF по страницам в цикле:

    Как вариант (даже наверное предпочтительнее) использовать следующую команду:

    pdftk.exe ВашИсходныйФайлPDFКоторыйНадоРазбитьНаСтраницы.pdf burst

    На выходе получим столько файлов PDF, сколько было страниц в исходном файле + doc_data.txt с той же технической информацией об исходном PDF, что нам возвращает dump_data. Имена у файлов будут pg_0001, pg_0002, pg_0003 и т.д.

    Небольшой кусочек справки о команде burst с сайта pdflabs:

    Splits a single input PDF document into individual pages. Also creates a report named doc_data.txt which is the same as the output from dump_data. If the output section is omitted, then PDF pages arenamed: pg_%04d.pdf, e.g.: pg_0001.pdf, pg_0002.pdf, etc. To name these pages yourself, supply a printf-styled format string in the output section. For example, if you want pages named: page_01.pdf, page_02.pdf, etc.,pass output page_%02d.pdf to pdftk.

    P.S. За статью большое спасибо!

    Reply

Leave a Comment

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