Пошаговая обработка. Пример с обработкой csv-файла

Пошаговая обработка. Пример с обработкой csv-файла

1082
23.03.2015

Встала задача - реализовать загрузку каталога из двух csv-файлов: файла с разделами каталога и файла с товарами с разброской свойств, характеристик товаров и привязкой к разделам. Создание товаров/разделов - не вижу смысла описывать, остановлюсь более детально на механизме обработки csv-файла.

Доброго времени суток. Встала задача - реализовать загрузку каталога из двух csv-файлов: файла с разделами каталога и файла с товарами с разброской свойств, характеристик товаров и привязкой к разделам. Создание товаров/разделов - не вижу смысла описывать, остановлюсь более детально на механизме обработки csv-файла. 

Для начала, рекомендую ознакомиться с  постом . Мой механизм чтения CSV - практически полностью идентичен (с небольшим дополнением). 

Итак, код чтения csv-файла: 

require_once ($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/classes/general/csv_data.php");
$csvFile = new CCSVData('R', false);
$csvFile->LoadFile($_FILES['products_csv']['tmp_name']);
$csvFile->SetDelimiter(',');
$arRows = array();
$Headers = array();
while ($arRes = $csvFile->Fetch()) {
if(empty($Headers)){
$Headers = $arRes;
    } else {
$arRow = array();
foreach ($Headers as $key=>$value) {
$arRow[$value] = $arRes[$key];
        }
$arRows[] = $arRow;
    }
}

Вот так получаем ассоциативный массив из csv-файла.

Построчно:

  • Подключаем CSV-класс
  • Читаем файл (при этом, первую строку также считываем) 
  • Загружаем файл, который был добавлен в файловый input с именем "products_csv" 
  • устанавливаем в качестве разделителя запятую 
  • объявляем массив, в который будем помещать строки 
  • объявляем массив, в который будем помещать заголовки полей 
  • обрабатываем каждую строку файла 
  • Если массив заголовков еще пустой, то заполняем его. 
  • Иначе - перебираем все заголовки полей и формируем ассоциативный массив на основании данных строки файла 
  • помещаем сформированный массив в общий контейнер. 

Ну вот. Данные из файла считали. Дальше их необходимо обработать. Загрузить сразу все одним комом - не реально (Разделов у меня было 144 - они бы загрузились. А вот товаров - несколько тысяч. Тут бы сервер и объяснил мне на сколько я не прав...), следовательно, нужно обрабатывать блоками. Я выбрал вариант обработки каждой строки по отдельности. Для этого получился небольшой JS скрипт с отправкой данных через ajax-post-запросы:

<div id="loading"><p class="persents"><?=Loc::getMessage('PAI_LOADING');?><span class="pv">0</span>%  (<?=Loc::getMessage('PAI_ROW');?><span class="rv">1</span>/<?=count($arRows)?>) </p></div>
<script type="text/javascript">
    var ajaxurl = ''; // url to pass ajax requests
        var Rows = <?=json_encode($arRows);?>
        var countRows = <?=count($arRows);?>

        function work_with_row(num, Row, d){
        var Persents = (parseInt(num)+1)*100 / parseInt(countRows);
        $('p.persents').find('span.pv').html(Math.round(Persents));
        $('p.persents').find('span.rv').html(parseInt(num)+1);
        $.ajax({
        type: "POST",
        url: ajaxurl,
        data: {action: 'AddProduct', ProductData: Row},
        dataType: "json",
        success: function (data) {

        d && d.resolve();
        },
        onfailure: function(){
        d && d.resolve();
        }
        });
        }

        $(document).ready(function(){
        var wait = BX.showWait('loading');
        var deferreds = [];
        var i=10;
        $.each(Rows,function(index,value){
        var d = new $.Deferred();
        window.setTimeout(function() { work_with_row(index,value,d) }, 1000*index+(i++));
        deferreds.push(d);
        });
        $.when.apply($, deferreds).done(function () {
        $('p.persents').html('<?=Loc::getMessage('PAI_LOAD_DONE')?>');
        BX.closeWait('loading',wait);
        });
        });
        </script>

Построчно:

  • div-контейнер, в котором будет публиковаться информация о состоянии загрузки 
  • задаем переменную, в которой прописываем адрес, куда будем отправлять ajax-запросы 
  • в переменную Rows помещаем считанные из csv-строки 
  • в переменную countRows записываем количество строк для последующего подсчета текущего состояния загрузки 
  • описываем функцию для обработки каждой записи 
  • определяем текущий статус загрузки в процентном и абсолютном соотношениях 
  • далее отправляем аякс запрос, результаты которого помещаем в очередь на вывод пользователю 
  • далее описываем функцию, которая отрабатывает сразу после загрузки страницы, т.е. после чтения csv-файла 
  • показываем прелоадер в правом верхнем углу блока с ID=loading 
  • определяем массив для очереди 
  • устанавливаем приращение для очереди 
  • перебираем все записи, при этом вызываем функцию обработки записи с интервалом 
  • когда обработка завершена - выводим пользователю соответствующее сообщение и убираем прелоадер 

Все! Вот такой вот вышел очередной опыт в переносе каталога из одной системы - в другую. 


Источник: http://dev.1c-bitrix.ru/community/webdev/user/60622/blog/13245/


Благодарю за внимание! Делитесь вашими замечаниями в комментариях ниже.


P.S. Обращайтесь ко мне за приобретением лицензий и продлений на 1C-Битрикс "Управление сайтом", лицензий на облачную и коробочную версии Битрикс 24 а также за приобретением и внедрением готовых решений на базе 1С-Битрикс от партнеров. За более подробной информацией свяжитесь со мной любым удобным для вас способом


Комментарии

Еще никто не комментировал данную публикацию. Будьте первыми!

Добавить комментарий

captcha

Возврат к списку