Удаление Zebra с помощью phpspreadsheet

#php #laravel #phpspreadsheet

#php #laravel #phpspreadsheet

Вопрос:

Я искал примеры и / или руководства по использованию условного форматирования phpspreadsheet. В частности, я искал, чтобы я мог разделять свою электронную таблицу на полосы таким образом, чтобы можно было повторно использовать лист. Я пришел к очень пустому ответу только с несколькими точечными вопросами SO, используя старую библиотеку PHPExcel и только один пример из документации. Учитывая, что полосы zebra — довольно распространенный стиль для применения, я был слегка возмущен тем, что не смог найти задание копирования / вставки. Итак, я разобрался в этом сам и теперь оставлю это здесь для потомков и, надеюсь, себя через несколько лет.

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

Ответ №1:

Удаление Zebra

 $range = 'A3:'.$spreadsheet->getActiveSheet()->getHighestDataColumn.
               $spreadsheet->getActiveSheet()->getHighestDataRow();
$conditional1 = new PhpOfficePhpSpreadsheetStyleConditional();
$conditional1->setConditionType(PhpOfficePhpSpreadsheetStyleConditional::CONDITION_EXPRESSION)
              ->setOperatorType(PhpOfficePhpSpreadsheetStyleConditional::OPERATOR_EQUAL)
              ->addCondition('MOD(ROW(),2)=0');
$conditional1->getStyle()->getFill()->setFillType(PhpOfficePhpSpreadsheetStyleFill::FILL_SOLID)
             ->getStartColor()->setARGB('DFDFDF');
$conditional1->getStyle()->getFill()->setFillType(PhpOfficePhpSpreadsheetStyleFill::FILL_SOLID)
             ->getEndColor()->setARGB('DFDFDF');
$spreadsheet->getActiveSheet()->getStyle($range)->setConditionalStyles([$conditional1]);
  

Диапазон начинается с A3, потому что у меня есть логотип в строке 1 и заголовки в строке 2. Также вы можете применить столько условий, сколько вам нужно, поэтому окончательный setConditionalStyles заключен в массив.

Заморозить 1 столбец и 2 строки

 $sheet->freezePane('B2');
  

Это заморозит эту ячейку B2 и все, что слева и выше. Очень полезно для длинных и широких листов, позволяя вам постоянно держать ваш primary_key и заголовки в поле зрения.

Вставить логотип в 1-ю ячейку

 $spreadsheet->getActiveSheet()->insertNewRowBefore(1, 1);
$drawing = new PhpOfficePhpSpreadsheetWorksheetDrawing();
$drawing->setCoordinates('A1');
$drawing->getShadow()->setVisible(true);
$drawing->setName({{alt text}});
$drawing->setPath(resource_path().{{filepath}});
$drawing->setWorksheet($spreadsheet->getActiveSheet());
$spreadsheet->getActiveSheet()->getRowDimension('1')->setRowHeight(55);
  

Скрытие листа

 $spreadsheet->getActiveSheet()->setSheetState('veryHidden');
  

Это одна вещь, которую мне действительно нравится делать, поскольку я написал некоторую автоматизацию, которая зависит от пользовательского
редактирует электронную таблицу и возвращает лист на определенный адрес электронной почты, к которому я могу получить доступ через api, загрузить и обработать заново на основе изменений в листе. Я использую это в основном для хранения информации, необходимой нашей erp для доступа к записям, таким как customer_id или contract_number, чтобы при возврате листа мне не приходилось повторно запрашивать идентификационную информацию, я могу просто взять ее из скрытого листа. Бонус использования very hidden заключается в том, что обычный пользователь не может отобразить его, если он не знает достаточно, чтобы открыть окно разработки и войти в скрипт VB.

Наложите фильтры на все заголовки

 $dimensions = 'A2' . ':' . $spreadsheet->getActiveSheet()->getHighestDataColumn() . 
                           $spreadsheet->getActiveSheet()->getHighestDataRow();
$spreadsheet->getActiveSheet()->setAutoFilter($dimensions);
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
$autoFilter->showHideRows();
  

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

Столбцы автоматической ширины

 $colNumber = PhpOfficePhpSpreadsheetCellCoordinate::columnIndexFromString(
             $spreadsheet->getActiveSheet()->getHighestDataColumn);
for ($col = 1; $col <= $colNumber; $col  ) {
    $colAlpha = PhpOfficePhpSpreadsheetCellCoordinate::stringFromColumnIndex($col);
    $spreadsheet->getActiveSheet()->getColumnDimension($colAlpha)->setAutoSize(true);
}
$sheet->calculateColumnWidths();
  

Создание электронных таблиц с несколькими вкладками

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

 $report = json_encode([
        'filepath' => 'Program Size/',
        'filename' => $customer_name->company_name.' Program Size '.Carbon::parse('now')->format('Ymd').'.xlsx',
        'Type' => 'buildMultiSheet',
        '1' => [
            'request' => [
                'TabName' => 'Program Size',
                'header' => array_keys($source[0]),
                'body' => $source,
                'formatArray'=> [
                    'aboveHeader'=>['Total Value:',$sum],
                    'zebra' => 'stripe',
                    'F:G' => '"$"#,##0.00_-'
                ]
            ]
        ],
        '2' => [
            'request' => [
                'TabName' => 'config_sheet',
                'header' => [],
                'body' => $queryLog,
                'formatArray'=> [
                    'hidden'=> 1
                ]
            ]
        ]
    ]);
  

В этой структуре есть все необходимое для создания электронной таблицы с несколькими вкладками. Источник для меня обычно является результатом вызова DB. Это не полная информация, например, имя вкладки длиной более 31 символа будет сбивать с толку, поэтому вам нужно проверить это. В один прекрасный день я мог бы привести все в порядок и опубликовать пакет, чтобы перейти на сторону phpspreadsheet, но мы посмотрим, произойдет ли это когда-нибудь.

 $spreadsheet = new Spreadsheet();
$filename = $requestD["filename"];
unset($requestD["filename"]);
$filepath = $requestD["filepath"];
unset($requestD["filepath"]);
$tabCounter = 0;
$spreadsheet->setActiveSheetIndex($tabCounter);
        
foreach ($requestD as $tab) {
    $sheet = $spreadsheet->getActiveSheet();
    $body = $tab["request"]["body"];  
    $spreadsheet->getActiveSheet()->setTitle($tab["request"]["TabName"]);
    $headers = $tab["request"]["header"];
    $sheet->fromArray($headers, NULL, 'A1');
    $sheet->fromArray($body, NULL, 'A2', false);  

    //processing here, sheet formatting , etc.
        
    $tabCounter  ;
    $spreadsheet->createSheet();
    $spreadsheet->setActiveSheetIndex($tabCounter);
}
    
//remove last empty sheet before resetting index
$spreadsheet->setActiveSheetIndex(0);
$spreadsheet->removeSheetByIndex($tabCounter);
  

Ну, это все советы, которые у меня есть. Если я сделал что-то действительно глупое, пожалуйста, дайте мне знать, как я могу улучшить.