Обработка файлов xlsx на PHP

Достаточно распространенной задачей при импорте данных со сторонних ресурсов является обработка экселевских документов. Раньше для этих целей использовалось расширение PhpOffice, Но чтобы данное расширение корректно заработало с файлами xlsx - нужно было изрядно поплясать с бубном.

С некоторых пор перешел на PhpSpreadsheet. Данная библиотека является логичным продолжением библиотеки PHPExcel, которая уже несколько лет не поддерживается.

Подробно с данной библиотекой можно познакомиться на ее официальном сайте.

Установка библиотеки осуществляется с помощью composer.

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

Вот несколько примеров использования данного модуля.

if(\Bitrix\Main\Loader::includeModule('pai.phpoffice')){
    $sFile = \Bitrix\Main\Application::getDocumentRoot().'/upload/file-test.xls';
    $oReader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile($sFile);
    // Если вы хотите установить строки и столбцы, которые необходимо читать, создайте класс ReadFilter
    // $filterSubset = new PhpOffice\PhpSpreadsheet\chunkReadFilter(1,100,range('A','I'));
    // $oReader->setReadFilter($filterSubset);
    $oSpreadsheet = $oReader->load($sFile);
    $oCells = $oSpreadsheet->getActiveSheet()->getCellCollection();
    $arRows = [];
	$cat = '';
	for ($iRow = 2; $iRow <= $oCells->getHighestRow(); $iRow++)
	{
		$row = [];
		for ($iCol = 'A'; $iCol <= 'I'; $iCol++)
		{
			$oCell = $oCells->get($iCol.$iRow);
			if($oCell)
			{
				$row[$iCol] = iconv('utf8','windows-1251',$oCell->getValue());
			}
		}

		if(strlen($row['A'])>0){
			$cat = $row['A'];
		}

		if(strlen($row['B'])<=0) continue;

		$arRows[] = [
			'CAT'=>$cat,
			'ARTICLE'=>$row['B'],
			'NAME'=>$row['C'],
			'PRICE_USD'=>$row['D'],
			'PRICE_UAH'=>$row['E'],
			'DESCRIPTION'=>$row['F'],
			'VIDEO'=>$row['G'],
			'GARANTEE'=>$row['H'],
			'PROMO'=>$row['I']
		];
	}
}

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

Вот пример на создание и запись:

use PhpOffice\PhpSpreadsheet\Spreadsheet;
if(\Bitrix\Main\Loader::includeModule('pai.phpoffice')){
  $sOutFile = 'out.xlsx';

  $oSpreadsheet_Out = new Spreadsheet();

  $oSpreadsheet_Out->getProperties()->setCreator('Name Password')
    ->setLastModifiedBy('Name Password')
    ->setTitle('Office 2007 XLSX Test Document')
    ->setSubject('Office 2007 XLSX Test Document')
    ->setDescription('Test document for Office 2007 XLSX, generated using PHP classes.')
    ->setKeywords('office 2007 openxml php')
    ->setCategory('Test result file')
  ;

  // Add some data
  $oSpreadsheet_Out->setActiveSheetIndex(0)
    ->setCellValue('A1', 'Привет 123')
    ->setCellValue('B2', 'world!')
    ->setCellValue('C1', 'Hello')
    ->setCellValue('D2', 'world!')
  ;

  $oWriter = IOFactory::createWriter($oSpreadsheet_Out, 'Xlsx');
  $oWriter->save($sOutFile);
  //$oWriter->save('php://output');
}

Пример на чтение файла:

use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
if(\Bitrix\Main\Loader::includeModule('pai.phpoffice')){
  $sFile = 'in.xlsx';
  $oReader = new Xlsx();
  //$oReader = IOFactory::createReaderForFile($sFile);

  // Если вы хотите установить строки и столбцы, которые необходимо читать, создайте класс ReadFilter
  //$oReader->setReadFilter( new MyReadFilter(11, 1000, range('B', 'O')) );

  $oSpreadsheet = $oReader->load($sFile);
  $oCells = $oSpreadsheet->getActiveSheet()->getCellCollection();
  for ($iRow = 1; $iRow <= $oCells->getHighestRow(); $iRow++)
  {
    for ($iCol = 'A'; $iCol <= 'C'; $iCol++)
    {
      $oCell = $oCells->get($iCol.$iRow);
      if($oCell)
      {
        echo $oCell->getValue();
      }
    }
  }
}

Сообщение Warning: ZipArchive::getFromName(): Invalid or uninitialized Zip object in возникает, если попробовать открыть XLS файл, через new xlsX(); Это возникает в том случае, когда вместо автоопределения указывается вручную тип данных для обработки

Имейте ввиду, что для использования данной библиотеки, необходима версия php не ниже 7.1. Если вы пользуетесь более старой версией - вам данный модуль не подойдет.

Как только будут появляться новые интересные примеры использования данной библиотеки - буду дополнять данную статьтью:)

Пример на использование фильтрации выборки

Класс:

use \PhpOffice\PhpSpreadsheet\Reader\IReadFilter;

class chunkreadfilter implements IReadFilter
{

	private $startRow = 0;
	private $endRow = 0;
	private $columns = [];

	public function __construct($startRow, $endRow, $columns)
	{
		$this->startRow = $startRow;
		$this->endRow = $endRow;
		$this->columns = $columns;
	}

	public function readCell($column, $row, $worksheetName = '')
	{
		if ($row >= $this->startRow && $row <= $this->endRow) {
			if (in_array($column, $this->columns)) {
				return true;
			}
		}

		return false;
	}
}

Использование:

$filterSubset = new \chunkReadFilter($line,$line+100,range('A','I'));
$oReader->setReadFilter($filterSubset);
Количество показов: 402
07.01.2020

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

Разработка сайта

Подайте заявку на разработку сайта на базе готового решения от компании 1С-Битрикс или одного из партнеров компании. Максимально подробно опишите, чему будет посвящен сайт, если это интернет-магазин - что он будет продавать, нужна ли мультиязычность, будут ли разные типы цен (розница, опт, крупный опт), будет ли интеграция с 1С, будет ли выгрузка товаров на различные торговые площадки...

Сопровождение сайта

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

Работы по сайту

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