#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);
Ну, это все советы, которые у меня есть. Если я сделал что-то действительно глупое, пожалуйста, дайте мне знать, как я могу улучшить.