update
This commit is contained in:
344
inc/Hura8/System/Controller/aExcelDownloadController.php
Normal file
344
inc/Hura8/System/Controller/aExcelDownloadController.php
Normal file
@@ -0,0 +1,344 @@
|
||||
<?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();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user