<?php
namespace Api\PhpUtils\Common;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
/**
 * 根据给定数据生成excel文件,可选择生成本地临时文件或浏览器直接输出
 *
 * @author 
 * @since 2021-07-25
 */
class ExportExcel
{
   
    /**
     * 获取生成excel文件的绝对地址
     * 
     * @param 必填项 :items {要生成excel的二维数组,array}
     * @param 必填项 :keywords {生成excel使用的keywords数组(具体格式详见SendExportMail.class.php中keywords属性),array}
     * @param 必填项 :filename {要生成excel的文件名,string}
     * @return string {生成的excel文件的绝对地址}
     */
    public static function getExcelFilePath($items, array $keywords, $filename = false)
    {
        $objPHPExcel = self::getPHPExcelObj($items, $keywords, $filename);
        $writer = new Xlsx($objPHPExcel);
        $filename = "/tmp/" . $filename;
        if (file_exists($filename)) {
            unlink($filename);
        } else {
            //$fp = fopen($filename, 'a');
        }
        //$objWriter->save($filename);
        $writer->save($filename);
        return $filename;
    }

    /**
     * 生成PHPExcel object用于输出
     *
     * @param 必填项 :items {要生成excel的数组,array}
     * @param 必填项 :keywords {生成excel文件使用的keywords数组(具体格式详见本类中keywords属性),array}
     * @param 必填项 :filename {要生成excel的文件名,string}
     * @return object {PHPExcel object}
     */
    private static function getPHPExcelObj($items, array $keywords, $filename = false)
    {
        set_time_limit(0);
        // Create new PHPExcel object
        $objPHPExcel = new \PHPExcel();
        // Set document properties
        $objPHPExcel->getProperties()
            ->setCreator("yidian")
            ->setLastModifiedBy("yidian")
            ->setTitle("标题")
            ->setSubject("题目")
            ->setDescription("描述")
            ->setKeywords("关键字")
            ->setCategory("种类");
        $ActiveSheet = $objPHPExcel->getActiveSheet();
        
        $keywords = self::getKeywordsWithAlpha($keywords);
        foreach ($keywords as $key => $value) {
            // set the wdith of cloumn
            $ActiveSheet->getColumnDimension($key)->setWidth($value['column_width']);
            // set the value of first row
            $ActiveSheet->getStyle($key)
                ->getAlignment()
                ->setHorizontal('center');
            $ActiveSheet->setCellValue($key . '1', $value['column_name']);
        }
        $index = 2;
        if (is_array($items)) {
            foreach ($items as $item) {
                foreach ($keywords as $key => $value) {
                    if (0 && is_numeric($item[$value['key']]) && ! is_int($item[$value['key']])) {
                        $ActiveSheet->setCellValue($key . $index, floatval($item[$value['key']]));
                    } elseif (0 && is_numeric($item[$value['key']])) {
                        $ActiveSheet->setCellValue($key . $index, intval($item[$value['key']]));
                    } else {
                        $ActiveSheet->setCellValue($key . $index, $item[$value['key']] . ' ');
                    }
                    $Alignment = $ActiveSheet->getStyle($key . $index)->getAlignment();
                    // 换行
                    $Alignment->setWrapText(true);
                    // 垂直居中
                    $Alignment->setVertical('center');
                }
                $index ++;
            }
        }
        return $objPHPExcel;
    }
   
    /**
     * 获取生成多sheet页excel文件的绝对地址
     *
     * @param 必填项 :data {要生成excel的三维数组，sheet页为第一维,array}
     * @param 必填项 :filename {要生成excel的文件名,string}
     * @return string {生成的excel文件的绝对地址}
     */
    public static function getExcelFileForMultiSheet($data, $filename)
    {
        $objPHPExcel = self::getPHPExcelObjForMultiSheet($data);
        $writer = new Xlsx($objPHPExcel);
        //$objWriter = new \PHPExcel_Writer_Excel5($objPHPExcel);
        $filename = "/tmp/" . $filename;
        //$filename = "/Users/work/" . $filename;
        if (file_exists($filename)) {
            unlink($filename);
        } else {
            //$fp = fopen($filename, 'a');
        }
        //$objWriter->save($filename);
        $writer->save($filename);
        return $filename;
    }


    /**
     * 生成多sheet页 PHPExcel object用于输出
     *
     * @param 必填项 :data {要生成excel的三维数组，sheet页为第一维,array}
     * @param 必填项 :keywords {生成excel文件使用的keywords数组(具体格式详见本类中keywords属性),array}
     * @param 必填项 :filename {要生成excel的文件名,string}
     * @return object {PHPExcel object}
     */
    private static function getPHPExcelObjForMultiSheet($data)
    {
        set_time_limit(0);
        // Create new PHPExcel object
        $objPHPExcel = new Spreadsheet();
 
        // Set document properties
        $objPHPExcel->getProperties()
            ->setCreator("yidian")
            ->setLastModifiedBy("yidian")
            ->setTitle("标题")
            ->setSubject("题目")
            ->setDescription("描述")
            ->setKeywords("关键字")
            ->setCategory("种类");
    
        $sheetIndex = 0;
        foreach ($data as $sheet) {
            $sheetName = !empty($sheet['sheetName']) ? $sheet['sheetName'] : 'sheet'.$sheetIndex;
            $topHeader = !empty($sheet['topHeader']) ? $sheet['topHeader'] : '';
            $keywords = !empty($sheet['keywords']) ? $sheet['keywords'] : '';
            $items = !empty($sheet['items']) ? $sheet['items'] : '';
            
            //创建一个新的工作空间(sheet)
            ($sheetIndex > 0) && $objPHPExcel->createSheet();
            $objPHPExcel->setActiveSheetIndex($sheetIndex);
            $activeSheet = $objPHPExcel->getActiveSheet();
            $activeSheet->setTitle($sheetName);


            
            $index = 1;
            $keywords = self::getKeywordsWithAlpha($keywords);
            if ($topHeader) {
                $indexAlpha = array_keys($keywords);
                $endAlpha   = end($indexAlpha);
                $activeSheet->setCellValue('A1', $topHeader);
                $activeSheet->mergeCells('A1:' . $endAlpha . '1');
                $activeSheet->getRowDimension(1)->setRowHeight(30);
                $activeSheet->getStyle('A1:' . $endAlpha . '1')
                    ->getAlignment()
                    ->setHorizontal('center')
                    ->setVertical('center');
                $index++;
            }
            foreach ($keywords as $key => $value) {
                // set the wdith of cloumn
                $activeSheet->getColumnDimension($key)->setWidth($value['column_width']);
                // set the value of first row
                $activeSheet->getStyle($key)
                    ->getAlignment()
                    ->setHorizontal('center');
                $activeSheet->setCellValue($key . $index, $value['column_name']);
            }

            $index++;
            if (empty($items) || !is_array($items)) {
                continue;
            }
            foreach ($items as $item) {
                foreach ($keywords as $key => $value) {
                    if (0 && is_numeric($item[$value['key']]) && ! is_int($item[$value['key']])) {
                        $activeSheet->setCellValue($key . $index, floatval($item[$value['key']]));
                    } elseif (0 && is_numeric($item[$value['key']])) {
                        $activeSheet->setCellValue($key . $index, intval($item[$value['key']]));
                    } else {
                        $activeSheet->setCellValue($key . $index, $item[$value['key']] . ' ');
                    }
                    $alignment = $activeSheet->getStyle($key . $index)->getAlignment();
                    // 换行
                    $alignment->setWrapText(true);
                    // 垂直居中
                    $alignment->setVertical('center');
                }
                $index ++;
            }
            $sheetIndex++;
        }
        
        return $objPHPExcel;
    }


     /**
     * 将keywords数组索引转为excel英文列名
     *
     * @param 必填项 :keywords {keywords数组中下标,array}
     * @return array {英文下标的数组(下标类似A,AA,BA)}
     */
    private static function getKeywordsWithAlpha($keywords)
    {
        $keywordsWithAlpha = array();
        if (is_array($keywords)) {
            foreach ($keywords as $key => $value) {
                $keywordsWithAlpha[self::intToUpperAlpha($key)] = $value;
            }
        }
        return $keywordsWithAlpha;
    }

    /**
     * 将数组int索引转化为excel列的列名字符串(A,AA,BA)
     *
     * @param 必填项 :ord {keywords数组中下标,int}
     * @return string {excel列的列名字符串}
     */
    private static function intToUpperAlpha($ord)
    {
        $baseOrd = ord('A');
        $mod = floor($ord/26);
        if ($mod == 0) {
            $retAphla = chr($baseOrd + $ord);
        } else {
            $retAphla = chr($baseOrd + $mod-1);
            $retAphla .= chr($baseOrd + $ord%26);
        }
        return $retAphla;
    }

    
}