345 lines
11 KiB
PHP
345 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* Created by Glee Ltd.
|
|
* User: Hieu
|
|
* Date: 20-Aug-19
|
|
* Time: 11:16 AM
|
|
* Description:
|
|
*/
|
|
|
|
namespace Hura8\System\Controller;
|
|
|
|
use Hura8\Interfaces\iExcelDownload;
|
|
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|
|
|
|
|
abstract class aExcelDownloadController implements iExcelDownload
|
|
{
|
|
protected static $column_names = [
|
|
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
|
|
'AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM',
|
|
'AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ',
|
|
//...
|
|
];
|
|
|
|
protected $work_sheet_title = "Danh sách"; //
|
|
protected $export_file_name = '';
|
|
|
|
/* @var $objExcel Spreadsheet */
|
|
protected $objExcel;
|
|
|
|
/* @var $currentActiveSheet Worksheet */
|
|
protected $currentActiveSheet;
|
|
|
|
protected $client_excel_col_config = [
|
|
/*"A" => array(
|
|
'name' => 'ID Sản phẩm Web',
|
|
'width' => '10',
|
|
'data_field_name' => 'id',
|
|
),
|
|
"B" => array(
|
|
'name' => 'Mã kho (SKU)',
|
|
'width' => '10',
|
|
'data_field_name' => 'storeSKU',
|
|
),*/
|
|
//...
|
|
];
|
|
|
|
protected $field_column_mappings = [
|
|
//'name' => "A",
|
|
//'price' => "B",
|
|
];
|
|
|
|
private $header_row_index = 2;
|
|
|
|
// hold cach for some operations
|
|
protected $cache = [];
|
|
|
|
protected $format_item_middlewares = []; // list of middleware object to format item
|
|
|
|
|
|
public function __construct($client_config_file_name='', $export_file_name='', $work_sheet_title = '')
|
|
{
|
|
if($client_config_file_name) {
|
|
$this->setColumnConfigUseConfigFile($client_config_file_name);
|
|
}
|
|
|
|
$this->export_file_name = ($export_file_name) ?: "file_".CURRENT_TIME;
|
|
$this->work_sheet_title = ($work_sheet_title) ?: "Danh sách";
|
|
}
|
|
|
|
|
|
protected function setColumnConfigUseConfigFile($client_config_file_name) {
|
|
//this from a config file for each client
|
|
$client_config_file = "config/client/excel/".$client_config_file_name;
|
|
if( ! file_exists(ROOT_DIR .'/'. $client_config_file)) {
|
|
die("Please create config file: ".$client_config_file);
|
|
}
|
|
$client_fields_config = include ROOT_DIR .'/'. $client_config_file;
|
|
|
|
// auto add excel column names based on fields' index
|
|
$this->client_excel_col_config = $this->_make_columns(array_values($client_fields_config));
|
|
|
|
// create field-col map
|
|
$this->createFieldColumnMappings();
|
|
}
|
|
|
|
|
|
private function createFieldColumnMappings() {
|
|
$field_column_mappings = [];
|
|
foreach ($this->client_excel_col_config as $column_name => $_prop) {
|
|
$field_column_mappings[$_prop['data_field_name']] = $column_name;
|
|
}
|
|
$this->field_column_mappings = $field_column_mappings;
|
|
}
|
|
|
|
|
|
public function setColumnConfigManually(array $col_config) {
|
|
$this->client_excel_col_config = $this->_make_columns($col_config);
|
|
// create field-col map
|
|
$this->createFieldColumnMappings();
|
|
}
|
|
|
|
|
|
protected function _make_columns($fields_config) {
|
|
$new_array = [];
|
|
$total_names = sizeof(static::$column_names);
|
|
foreach ($fields_config as $index => $config) {
|
|
if($index >= $total_names) break;
|
|
$new_array[static::$column_names[$index]] = $config;
|
|
}
|
|
|
|
return $new_array;
|
|
}
|
|
|
|
|
|
public function start(array $options = [
|
|
"debug_mode" => '', // show-item-list
|
|
"excelOption" => [],
|
|
"sheetOption" => [],
|
|
"sheetStartRowNumber" => 3,
|
|
"sheetHeaderRowNumber" => 2,
|
|
"getItemListOption" => [
|
|
"brand" => [],
|
|
"category" => [],
|
|
"page" => 1,
|
|
"limit" => 100,
|
|
],
|
|
"exportFileOption" => [],
|
|
]) {
|
|
|
|
$debug_mode = $options['debug_mode'] ?? false;
|
|
// debug mode
|
|
if($debug_mode) {
|
|
// show item list
|
|
if($debug_mode == 'show-item-list') {
|
|
$item_list = $this->getItemList($options['getItemListOption']);
|
|
print_r($item_list);
|
|
}
|
|
|
|
// show formatted list
|
|
if($debug_mode == 'show-formatted-list') {
|
|
$item_list = $this->formatItemList( $this->getItemList($options['getItemListOption']) );
|
|
print_r($item_list);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// setup
|
|
if(isset($options['sheetHeaderRowNumber']) && $options['sheetHeaderRowNumber']) {
|
|
$this->header_row_index = $options['sheetHeaderRowNumber'];
|
|
}
|
|
|
|
$this->createExcelObject($options['excelOption'] ?? []);
|
|
$this->createActiveSheet(0, $options['sheetOption'] ?? []);
|
|
|
|
// num beforeWriteList
|
|
$this->beforeWriteList();
|
|
|
|
// fetch all items and write till the end
|
|
$has_fetch_all_items = false;
|
|
$start_row = (isset($options["sheetStartRowNumber"])) ? $options["sheetStartRowNumber"] : 3;
|
|
|
|
$item_list = $this->formatItemList( $this->getItemList($options['getItemListOption']) );
|
|
|
|
//debug_var($item_list);
|
|
//exit;
|
|
|
|
$has_fetch_all_items = true;
|
|
$this->writeItemsToExcel($start_row, $item_list);
|
|
|
|
/*$getItemListOption = $options['getItemListOption'];
|
|
$pageIndex = 0;
|
|
|
|
while (!$has_fetch_all_items) {
|
|
// run from page 1->end
|
|
$pageIndex += 1;
|
|
$getItemListOption["page"] = $pageIndex;
|
|
$item_list = $this->getItemList($getItemListOption);
|
|
|
|
// flag
|
|
if(!sizeof($item_list)) {
|
|
$has_fetch_all_items = true;
|
|
}
|
|
|
|
// else, start write
|
|
$last_row = $this->writeItemsToExcel($start_row, $item_list);
|
|
|
|
// update $start_row
|
|
$start_row = $last_row;// + 1
|
|
}*/
|
|
|
|
// export
|
|
if($has_fetch_all_items) {
|
|
$this->getExcelFile($options['exportFileOption']);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// abstract methods
|
|
protected function beforeWriteList() { }
|
|
abstract protected function getItemList(array $options);
|
|
abstract protected function defaultFormatItemInfo(array $item_info, $index =0);
|
|
|
|
protected function registerFormatItemInfoMiddleware($middleware_ojb) {
|
|
$this->format_item_middlewares[] = $middleware_ojb;
|
|
}
|
|
|
|
protected function formatItemInfo(array $item_info, $index = 0) {
|
|
|
|
// apply middleware
|
|
if(sizeof($this->format_item_middlewares)) {
|
|
foreach ($this->format_item_middlewares as $_middleware) {
|
|
$item_info = call_user_func($_middleware, $item_info);
|
|
}
|
|
} else {
|
|
$item_info = $this->defaultFormatItemInfo($item_info, $index);
|
|
}
|
|
|
|
return $item_info;
|
|
}
|
|
|
|
|
|
protected function createExcelObject(array $options)
|
|
{
|
|
// Create new Spreadsheet object
|
|
$this->objExcel = new Spreadsheet();
|
|
|
|
// Set properties
|
|
$this->objExcel->getProperties()->setCreator("Hurasoft");
|
|
$this->objExcel->getProperties()->setLastModifiedBy("Hurasoft");
|
|
$this->objExcel->getProperties()->setTitle("Excel Document");
|
|
$this->objExcel->getProperties()->setSubject("Excel Document");
|
|
$this->objExcel->getProperties()->setDescription("Tao file excel");
|
|
}
|
|
|
|
|
|
protected function createActiveSheet($sheet_index = 0, array $options=[]) {
|
|
// Create a first sheet, representing sales data
|
|
$this->objExcel->setActiveSheetIndex($sheet_index);
|
|
$this->currentActiveSheet = $this->objExcel->getActiveSheet();
|
|
$this->currentActiveSheet->setCellValueExplicit('A1', $this->work_sheet_title, DataType::TYPE_STRING);
|
|
$this->currentActiveSheet->getStyle('A1')->getFont()->setSize(16);
|
|
$this->currentActiveSheet->getStyle('A1')->getFont()->setBold(true);
|
|
|
|
// Set header row
|
|
$row_index = $this->header_row_index;
|
|
foreach ($this->client_excel_col_config as $col_name => $_prop) {
|
|
$col_width = (isset($_prop['width']) && intval($_prop['width']) > 0) ? intval($_prop['width']) : 15;
|
|
$this->currentActiveSheet->getColumnDimension($col_name)->setWidth($col_width);
|
|
$this->currentActiveSheet->setCellValueExplicit($col_name. $row_index, $_prop["name"], DataType::TYPE_STRING);
|
|
$this->currentActiveSheet->getStyle($col_name . $row_index)->getFont()->setBold(true);
|
|
}
|
|
}
|
|
|
|
protected function formatItemList(array $item_list)
|
|
{
|
|
$new_list = [];
|
|
foreach ( $item_list as $index => $item_info ) {
|
|
$new_list[$index] = $this->formatItemInfo($item_info, $index);
|
|
}
|
|
|
|
return $new_list;
|
|
}
|
|
|
|
|
|
protected function writeItemsToExcel($start_row = 1, array $item_list=[])
|
|
{
|
|
$write_row = $start_row;
|
|
foreach ( $item_list as $index => $item_info ) {
|
|
|
|
// write each field to its corresponding columns
|
|
foreach ($item_info as $_field => $_value) {
|
|
if( !isset($this->field_column_mappings[$_field])) continue;
|
|
|
|
if(is_array($_value)) $_value = serialize($_value);
|
|
|
|
$write_column = $this->field_column_mappings[$_field];
|
|
|
|
$this->currentActiveSheet->setCellValueExplicit($write_column . $write_row, $_value, DataType::TYPE_STRING);
|
|
$this->currentActiveSheet->getStyle($write_column . $write_row)->getAlignment()->setWrapText(true);
|
|
}
|
|
|
|
// next rows
|
|
$write_row += 1;
|
|
}
|
|
|
|
// get the last row
|
|
return $write_row;
|
|
}
|
|
|
|
|
|
protected function getExcelFile(array $options)
|
|
{
|
|
// write to a local file
|
|
$local_file = $options['local_file'] ?? '';
|
|
if($local_file) {
|
|
$this->_save_to_file($local_file);
|
|
return true;
|
|
}
|
|
|
|
// default: export to browser to download
|
|
$this->_export_to_browser();
|
|
|
|
return true;
|
|
}
|
|
|
|
protected function cleanUp(){
|
|
// clean up
|
|
$this->objExcel->disconnectWorksheets();
|
|
unset($this->objExcel);
|
|
}
|
|
|
|
protected function _save_to_file($file_path){
|
|
|
|
// delete old file if exist
|
|
if(file_exists($file_path)) {
|
|
@unlink($file_path);
|
|
}
|
|
|
|
$writer = new Xlsx($this->objExcel);
|
|
$writer->save($file_path);
|
|
$this->cleanUp();
|
|
}
|
|
|
|
protected function _export_to_browser(){
|
|
// Rename sheet
|
|
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
|
header('Content-Disposition: attachment;filename="'.$this->export_file_name.'.xlsx"');
|
|
header('Cache-Control: max-age=0');
|
|
|
|
$writer = new Xlsx($this->objExcel);
|
|
ob_end_clean();
|
|
$writer->save('php://output');
|
|
|
|
$this->cleanUp();
|
|
exit();
|
|
}
|
|
|
|
}
|