Поиск по таблице .xls (EXCEL) средствами PHP на примере практической задачи

В сфере продаж сантехники и приборов отопления через интернет есть существенная проблема — отсутствие какого-либо единого стандарта оформления прайс-листов. Причем проблема присутствует не только между поставщиками, но и даже в рамках одной кампании, прайсы на разную продукцию могут оформляться по-разному, что в итоге приводит к неразберихе и ошибочным действиям в работе организации (проверено на личном опыте).

Допустим, у Вас интернет-магазин на 100 товаров. Никакой сложности с тем, чтобы поменять цены и отредактировать карточки товара у Вас, скорее всего, не возникнет. А что, если этих товаров 500, 2000 или 20000 тысяч? Этот вопрос я поднимал раньше, в этой статье, поэтому повторяться не буду.

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

Рисунок 1 — У каждого поставщика прайс выглядит по — своему

Например, у Вас есть код, который обрабатывает прайс с товарами. В нём вы задаете столбцы для полей, которые соответствуют прайсу A: 1 — это имя, 2 — это артикул, 3 — это цена. Вам также нужно обработать прайс B, где: 1 — это артикул, 2 — это имя, а 3 — это бренд, а 4 — это стоимость. Получается скрипт, где порядок столбцов задан статически, первый прайс обработает, а второй — уже нет, потому что в этом файле порядок столбцов уже другой. Либо Вам придется вручную задавать порядок столбцов для каждого прайса, что не очень удобно при их большом количестве (например, мы регулярно обрабатываем больше сотни прайсов от разных производителей и поставщиков).

По сути, есть два способа решения этой проблемы:

  1. Добиваться соблюдения единого стандарта оформления прайсов от каждого поставщика. Как показывает практика, в суровой реальности, в 90% случает поставщики не понимают, что Вы от них хотите, зачем это нужно, даже несмотря на пачку разумных доводов.
  2. Сделать свой скрипт более гибким. То есть, таким, чтобы не в зависимости от того, что нагородит в своих прайсах поставщик, он будет определять нужные столбцы и брать необходимые данные.

Чтобы п.2 был возможен, есть несколько условий, без соблюдения которых это невозможно:

  • прайс должен содержать артикул (SKU), по которому можно идентифицировать товар. Чисто теоретически, идентифицировать товар можно по наименованию, но на практике, написание наименований может отличаться, а сопоставление товаров по частичному совпадению в названии — это не всегда надежно.
  • Прайс должен быть «линейным» — есть строка с названиями полей, данные по каждому полю расположены в рамках одного столбца. В качестве примера приведу ниже прайс, который автоматически можно обработать (в теории), но это нерационально.

Рисунок 2 — Примерно так выглядит хороший прайс

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

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

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

Чтобы реализовать поиск по таблице Excel, напишем функцию, которая будет методом перебора, итерацию за итерацией, анализировать содержание всех ячеек книги в поисках искомого значения. В качестве искомого значения подразумеваются вариации названий, которые необходимо обработать — это артикул (sku), название товара, цена, складской запас (остаток) и другие данные, которые могут быть необходимы для работы Вашего магазина. В случае совпадения искомого значения и содержимого ячейки, функция записывает индекс этой ячейки в массив и заканчивает переборку входных параметров. В итоге мы имеет следующий код:

// $ColumnName  - name of column
// $SearchValue - search parameter name
// $pExcel - xls or сsv file, which we open via PHPEXCEL

function GetTheColumnIndex($columnName, $searchValue, $pExcel) {

$foundInCells = array();
  foreach ($pExcel->getWorksheetIterator() as $worksheet) {
    $ws = $worksheet->getTitle();
    foreach ($worksheet->getRowIterator() as $row) {
      $cellIterator = $row->getCellIterator();
      $cellIterator->setIterateOnlyExistingCells(false);
        foreach ($cellIterator as $cell) {
          foreach($searchValue as $ValueVariant) {
            if ($cell->getValue() == $ValueVariant) {
              $foundInCells[] = $ws . '!' . $cell->getCoordinate();
            } 
        }
    }
  }

}

// To get the value of the column index, keep only the last two characters of the variable..

  if (!empty($foundInCells[0])) {

    $ValueIndex = substr($foundInCells[0], -2);
      if (!empty($ValueIndex)) {
        echo 'Имеем следующий индекс для '. $columnName . ':';
        echo PHP_EOL;
        echo $ValueIndex;
        echo PHP_EOL;        
      } 
    } else {
        echo PHP_EOL;        
        echo 'Индекс для '. $columnName . ' не найден';
        echo PHP_EOL;
    }

}

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

$SkuVal   = array('Артикул', 'артикул', 'АРТИКУЛ', 'SKU', 'Sku', 'sku', 'ARTICLE', 'PRODUCTO', 'Код', 'Артикул b2b');

GetTheColumnIndex('SKU', $SkuVal, $pExcel);

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

В совокупности с другими функциями, которые я опишу в последующих статьях, данный скрипт позволяет сделать универсальный код, подходящий для обработки прайс-листов с разными форматами.

Оставьте комментарий

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

Прокрутить вверх