Tag Archive เอ็กเซล

PHPExcel: จัดรูปแบบ format ข้อมูล

เมื่อวานเขียน export ข้อมูลออกเป็นไฟล์ excel โดยใช้เวลาไม่นาน เพราะโครงสร้างการทำงานมันเหมือนๆ งานที่เคยทำมา แต่มาตกม้าตายเอาที่การฟอร์เมตของแต่ละ column ให้ตรงกับชนิดข้อมูล เช่น type เป็น date ก็ควรให้เห็นเป็นวันที่ไม่ใช่เลข 1234155 อะไรก็ไม่ทราบ

<?php

include '../vendor/phpoffice/phpexcel/Classes/PHPExcel.php';

set_time_limit(0);

$objPHPExcel = new PHPExcel();

/* Set default style */
$defaultStyle = $objPHPExcel->getDefaultStyle();

$defaultStyle->getFont()
    ->setName('Arial')
    ->setSize(11);

$defaultStyle->getNumberFormat()
    ->setFormatCode('yyyy-mm-dd');

/* Set document properties */
$title = 'columnsType_' . date('Y-m-d_H:i');
$objPHPExcel->getProperties()->setCreator('CMS')
    ->setCategory('Exports Datas')
    ->setDescription($title)
    ->setKeywords('Exports Datas ' . date('Y-m-d'))
    ->setSubject($title)
    ->setTitle($title);

/* create new sheet */
$objWorkSheet = $objPHPExcel->getActiveSheet();
$objWorkSheet->setTitle('Exports Datas');

$columns = [
    'row_number' => ['title' => 'No.', 'type' => 'row_number'],

    'price' => ['title' => 'ราคา', 'type' => 'currency'],

    'dateEnd' => ['title' => 'เริ่มจำหน่าย', 'type' => 'date'],
    'dateStart' => ['title' => 'เริ่มจำหน่าย', 'type' => 'date'],

    'dateApproved' => ['title' => 'เวลาอนุมัติ', 'type' => 'datetime'],

    'height' => ['title' => 'สูง (เมตร)', 'type' => 'float'],
    'width' => ['title' => 'กว้าง (เมตร)', 'type' => 'float'],

    'calculate' => ['title' => 'สูตรคํานวณหวย', 'type' => 'formula'],

    'image' => ['title' => 'ภาพ', 'type' => 'image'],

    'items' => ['title' => 'จำนวน', 'type' => 'integer'],

    'productName' => ['title' => 'ชื่อสินค้า', 'type' => 'string'],

    'timeEnd' => ['title' => 'เวลาขาย', 'type' => 'time'],
    'timeStart' => ['title' => 'เวลาปิดการขาย', 'type' => 'time'],

    'url' => ['title' => 'page', 'type' => 'url'],
];

/* header */
$colNo = -1;
$rowNo = 1;
$colStrings = [];
foreach ($columns as $fieldId => $field) {
    $colNo++;
    $colStrings[$colNo] = $colString = PHPExcel_Cell::stringFromColumnIndex($colNo);
    $objWorkSheet->setCellValue($colString . '1', $field['title']);
    $objWorkSheet->setCellValue($colString . '2', 'type = ' . $field['type']);
}
$headerHeight = $rowNo = 2;

$objPHPExcel->getActiveSheet()->freezePane($colString . ($headerHeight + 1));

/* random data */
$datas = [];
for ($a = 0; $a < 10; $a++) {
    $temp = [];

    $temp['calculate'] = '=RAND()';
    $temp['dateApproved'] = date(DATE_ISO8601, mt_rand(0, 1499291999));
    $temp['dateEnd'] = date('Y-m-d', mt_rand(0, 1499291999));
    $temp['dateStart'] = date('Y-m-d', mt_rand(0, 1499291999));
    $temp['height'] = mt_rand(0, 10) / 10;
    $temp['image'] = 'http://lorempixel.com/400/200/sports/?st=' . mt_rand(1, 500);
    $temp['items'] = mt_rand(999, 9999999);
    $temp['price'] = mt_rand(100, 10000);
    $temp['productName'] = substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil(10 / strlen($x)))), 1, 10);
    $temp['timeEnd'] = date('H:i:s', mt_rand(0, 1499291999));
    $temp['timeStart'] = date('H:i:s', mt_rand(0, 1499291999));
    $temp['url'] = 'https://plusmagi.com/?s=' . mt_rand(1, 500);
    $temp['width'] = mt_rand(0, 10) / 10;

    array_push($datas, $temp);
}

/* add data */
$row_number = 0;
foreach ($datas as $item) {
    $colNo = -1;
    $row_number++;
    $rowNo++;
    foreach ($columns as $fieldId => $field) {
        $colNo++;

        $coordinate = $colStrings[$colNo] . $rowNo;

        switch ($field['type']) {
            case 'date':
            case 'datetime':
            case 'time':{
                    $ts = strtotime($item[$fieldId]);
                    $value = PHPExcel_Shared_Date::PHPToExcel($ts);
                }break;

            case 'image':{
                    $value = $item[$fieldId];

                    $gdImage = imagecreatefromjpeg($value);
                    $objDrawing = new PHPExcel_Worksheet_MemoryDrawing(); /*create object for Worksheet drawing*/

                    $objDrawing->setCoordinates($coordinate); /*set image to cell*/
                    $objDrawing->setDescription('Customer Signature'); /*set description to image*/
                    $objDrawing->setHeight(50);
                    $objDrawing->setImageResource($gdImage);
                    $objDrawing->setName('Customer Signature'); /*set name to image*/
                    $objDrawing->setOffsetX(25); /*setOffsetX works properly*/
                    $objDrawing->setOffsetY(10); /*setOffsetY works properly*/
                    $objDrawing->setWidth(100); /*set width, height*/

                    $objDrawing->setWorksheet($objWorkSheet); /*save*/

                    $objWorkSheet->getRowDimension($rowNo)->setRowHeight(60); /* set row height*/
                }break;

            case 'row_number':{
                    $value = $row_number;
                }break;

            case 'url':{
                    $value = str_replace('http://', '', $item[$fieldId]);
                    $objWorkSheet->getCell($coordinate)
                        ->getHyperlink()
                        ->setTooltip('Click here to access page')
                        ->setUrl($item[$fieldId]);
                }break;

            default:{
                    $value = $item[$fieldId];
                }break;
        }

        $objWorkSheet->setCellValue($coordinate, $value);
    }
}

/* auto width column */
$cellIterator = $objWorkSheet->getRowIterator()->current()->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(true);
foreach ($cellIterator as $cell) {
    $objWorkSheet->getColumnDimension($cell->getColumn())->setAutoSize(true);
}

/* format for columns */
$colNo = -1;
foreach ($columns as $fieldId => $field) {
    $colNo++;

    $coordinate = $colStrings[$colNo] . ($headerHeight + 1) . ':' . $colStrings[$colNo] . $rowNo;

    switch ($field['type']) {

        case 'currency':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode('#,##0.00');
                /*->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER);*/
            }break;

        case 'date':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH);
            }break;

        case 'datetime':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME);
                /*->setFormatCode('Y-m-d H:i:s');*/
            }break;

        case 'float':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1);
            }break;

        case 'integer':
        case 'row_number':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode('#,##');
            }break;

        case 'time':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4);
                /*->setFormatCode('Y-m-d H:i:s');*/
            }break;

        default:{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL);
            }break;
    }

}

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $title . '.xlsx"');
header('Cache-Control: max-age=0');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
$objWriter->save('php://output');

หลักการต้องทำงานคู่กัน 2 ส่วนคือ

  1. ส่วนใส่ข้อมูล บางชนิดต้องแปลงข้อมูลก่อน เช่น date, datetime, timestamp และ time ต้องเปลี่ยนเป็น unix timestamp ก่อน
  2. ส่วนกำหนด cell format (ในตัวอย่างให้วิธีกำหนดทั้ง column ไปเลย) ต้องเลือกรูปแบบที่เหมาะสมโดยจะกำหนดเอง
    ->setFormatCode('Y-m-d H:i:s');

    หรือจะใช้ตามมาตราฐานก้ได้ Class PHPExcel_Style_NumberFormat ก็ได้

PHPExcel: ใส่ภาพในไฟล์

บางครั้งการ export ข้อมูลออกไปเป็นไฟล์ excel ก็ต้องการใส่ภาพลงไปด้วย อาจจะเป็นโลโก้บริษัท หรือว่าเป็นภาพตัวอย่างสินค้า PHPExcel สามารถแทรกภาพได้ทั้งจาก file หรือ url ของภาพที่ออนไลน์อยู่

<?php

include 'vendor/phpoffice/phpexcel/Classes/PHPExcel.php';

$objPHPExcel = new PHPExcel();

/* Set default style */
$defaultStyle = $objPHPExcel->getDefaultStyle();

$defaultStyle->getFont()
    ->setName('Arial')
    ->setSize(11);

/* Set document properties */
$title = 'Exports_Datas_' . date('Y-m-d_H:i');
$objPHPExcel->getProperties()->setCreator('Pitt Phunsanit')
    ->setCategory('Exports Datas')
    ->setDescription($title)
    ->setKeywords('Exports Datas ' . date('Y-m-d'))
    ->setSubject($title)
    ->setTitle($title);

/* rename sheet */
$objWorkSheet = $objPHPExcel->getActiveSheet();
$objWorkSheet->setTitle('Exports Datas');

/* image path */
$images = [
    'https://raw.githubusercontent.com/PHPOffice/PHPExcel/1.8/Examples/images/officelogo.jpg',
    'https://raw.githubusercontent.com/PHPOffice/PHPExcel/1.8/Examples/images/paid.png',
    'https://raw.githubusercontent.com/PHPOffice/PHPExcel/1.8/Examples/images/phpexcel_logo.gif',
    'https://raw.githubusercontent.com/PHPOffice/PHPExcel/1.8/Examples/images/termsconditions.jpg',
    'vendor/phpoffice/phpexcel/Examples/images/officelogo.jpg',
    'vendor/phpoffice/phpexcel/Examples/images/paid.png',
    'vendor/phpoffice/phpexcel/Examples/images/phpexcel_logo.gif',
    'vendor/phpoffice/phpexcel/Examples/images/termsconditions.jpg',
];

$rowNo = 0;
foreach ($images as $image) {
    $rowNo++;

    $coordinate = 'A' . $rowNo;

    $objWorkSheet->getRowDimension($rowNo)->setRowHeight(90);
    $objWorkSheet->setCellValue($coordinate, $image);

    switch (strtolower(pathinfo($image, PATHINFO_EXTENSION))) {
        case 'gif':
            $gdImage = imagecreatefromgif($image);
            $mimetype = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_GIF;
            $render = PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF;
            break;

        case 'jpeg':
        case 'jpg':
            $gdImage = imagecreatefromjpeg($image);
            $mimetype = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG;
            $render = PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG;
            break;

        case 'png':
            $gdImage = imagecreatefrompng($image);
            $mimetype = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG;
            $render = PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG;
            break;
    }

    $objDrawing = new PHPExcel_Worksheet_MemoryDrawing();

    $objDrawing->setCoordinates($coordinate);
    $objDrawing->setImageResource($gdImage);
    $objDrawing->setWorksheet($objWorkSheet);

    /* optional */
    $objDrawing->setDescription($image);
    $objDrawing->setMimeType($mimetype);
    $objDrawing->setName(pathinfo($image, PATHINFO_FILENAME));
    $objDrawing->setRenderingFunction($render);
    $objDrawing->setResizeProportional(true);
    $objDrawing->setWidth(100);

}

$objWorkSheet->getColumnDimension('A')->setAutoSize(true);

/* write */
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $title . '.xlsx"');
header('Cache-Control: max-age=0');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
$objWriter->save('php://output');

อธิบาย

setCoordinates
ตำแหน่งที่ให้ภาพไปลอยอยู่
setDescription
รายละเอียด (optional)
setName
ชื่อภาพ (optional)
setResizeProportional
รักษาสัดส่วนของภาพเอาไว้
setWorksheet
อ้างถึง Active Sheet หรือ sheet ที่ใส่ข้อมูล
ถ้าเลือกใช้ PHPExcel_IOFactory::createWriter ผิด version เช่น ‘Excel5’ อาจจะทำให้ภาพมีสัดส่วนเพี้ยนได้

PHPExcel : กำหนด border

การใช้คำสั่ง border ตีเส้นตารางช่วยในการแบ่งขอบเขตุข้อมูลและช่วยให้อ่านให้ง่ายขึ้น

ตัวอย่าง

<?php

/* http://stackoverflow.com/questions/27764204/how-to-do-the-phpexcel-outside-border */
/* PHPExcel_IOFactory - Reader */
include 'vendor/phpoffice/phpexcel/Classes/PHPExcel.php';

$objPHPExcel = new PHPExcel();

/* Set default style */
$defaultStyle = $objPHPExcel->getDefaultStyle();

$defaultStyle->getFont()
    ->setName('Arial')
    ->setSize(11);

/* Set document properties */
$title = 'Exports_Datas_' . date('Y-m-d_H:i');
$objPHPExcel->getProperties()->setCreator('Pitt Phunsanit')
    ->setCategory('Exports Datas')
    ->setDescription($title)
    ->setKeywords('Exports Datas ' . date('Y-m-d'))
    ->setSubject($title)
    ->setTitle($title);

/* rename sheet */
$objWorkSheet = $objPHPExcel->getActiveSheet();
$objWorkSheet->setTitle('Exports Datas');

/* add background */
$background = [
    'fill' => [
        'color' => [
            'rgb' => 'FF9',
        ],
        'type' => PHPExcel_Style_Fill::FILL_SOLID,
    ],
];

$borders = [
    'allborders' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
        ],
    ],
    'bottom' => [
        'borders' => [
            'bottom' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
        ],
    ],
    'diagonal (both)' => [
        'borders' => [
            'diagonal' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
            'diagonaldirection' => PHPExcel_Style_Borders::DIAGONAL_BOTH,
        ],
    ],
    'diagonal (down)' => [
        'borders' => [
            'diagonal' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
            'diagonaldirection' => PHPExcel_Style_Borders::DIAGONAL_DOWN,
        ],
    ],
    'diagonal (none)' => [
        'borders' => [
            'diagonal' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
            'diagonaldirection' => PHPExcel_Style_Borders::DIAGONAL_NONE,
        ],
    ],
    'diagonal (up)' => [
        'borders' => [
            'diagonal' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
            'diagonaldirection' => PHPExcel_Style_Borders::DIAGONAL_UP,
        ],
    ],
    'horizontal' => [
        'borders' => [
            'horizontal' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
        ],
    ],
    'inside' => [
        'borders' => [
            'inside' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
        ],
    ],
    'left' => [
        'borders' => [
            'left' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
        ],
    ],
    'outline' => [
        'borders' => [
            'outline' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
        ],
    ],
    'right' => [
        'borders' => [
            'right' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
        ],
    ],
    'top' => [
        'borders' => [
            'top' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
        ],
    ],
    'vertical' => [
        'borders' => [
            'vertical' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
        ],
    ],
];

$bordersLine = [
    'BORDER_DASHDOT' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
            ],
        ],
    ],
    'BORDER_DASHDOTDOT' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_DASHDOTDOT,
            ],
        ],
    ],
    'BORDER_DASHED' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_DASHED,
            ],
        ],
    ],
    'BORDER_DOTTED' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_DOTTED,
            ],
        ],
    ],
    'BORDER_DOUBLE' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_DOUBLE,
            ],
        ],
    ],
    'BORDER_HAIR' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_HAIR,
            ],
        ],
    ],
    'BORDER_MEDIUM' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_MEDIUM,
            ],
        ],
    ],
    'BORDER_MEDIUMDASHDOT' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT,
            ],
        ],
    ],
    'BORDER_MEDIUMDASHDOTDOT' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT,
            ],
        ],
    ],
    'BORDER_MEDIUMDASHED' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_MEDIUMDASHED,
            ],
        ],
    ],
    'BORDER_NONE' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_NONE,
            ],
        ],
    ],
    'BORDER_SLANTDASHDOT' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_SLANTDASHDOT,
            ],
        ],
    ],
    'BORDER_THICK' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_THICK,
            ],
        ],
    ],
    'BORDER_THIN' => [
        'borders' => [
            'allborders' => [
                'style' => PHPExcel_Style_Border::BORDER_THIN,
            ],
        ],
    ],

];

$objWorkSheet->setCellValue('C1', 'Borders');
$objWorkSheet->getStyle('C1')->getFont()->setBold(true);
$rowNo = -1;
foreach ($borders as $name => $style) {
    $rowNo += 4;

    $objWorkSheet->setCellValue('A' . $rowNo, $name);

    /* merge background */
    $style = array_merge($background, $style);

    $objWorkSheet->getStyle('D' . $rowNo . ':F' . ($rowNo + 2))->applyFromArray($style);

}

$objWorkSheet->getStyle('G3:G53')->applyFromArray($borders['right']);

$objWorkSheet->setCellValue('M1', 'Line');
$objWorkSheet->getStyle('M1')->getFont()->setBold(true);
$rowNo = 1;
foreach ($bordersLine as $name => $style) {
    $rowNo += 2;

    $objWorkSheet->setCellValue('I' . $rowNo, $name);

    /* merge background */
    $style = array_merge($background, $style);

    $objWorkSheet->getStyle('N' . $rowNo)->applyFromArray($style);
}

/* write */
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $title . '.xlsx"');
header('Cache-Control: max-age=0');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
$objWriter->save('php://output');

สร้าง grid ใน laravel แบบ advance

การใช้ Nayjest Grids แบบ advance เพื่อที่จะสามารถค้นหา filter ข้อมูล, export ไฟล์ ออกมาในรูปแบบ .csv และ excel ได้

ติดตั้งโดย

  1. เปิดไฟล์ composer.json เพิ่ม
    ...
            "laravelcollective/html": "^5",
            "maatwebsite/excel": "~2.1.0",
            "nayjest/grids": "^1.3.1"
    ...
    
  2. Command
    composer update
  3. เปิดไฟล์ \config\app.php เพิ่ม
        'providers' => [
    ...
            'Collective&#92;Html&#92;HtmlServiceProvider',
            'Maatwebsite&#92;Excel&#92;ExcelServiceProvider',
            'Nayjest&#92;Grids&#92;ServiceProvider',
    ...
    
        'aliases' => [
    ...
            'Excel' => 'Maatwebsite&#92;Excel&#92;Facades&#92;Excel',
            'Form' => 'Collective&#92;Html&#92;FormFacade',
            'Grids' => 'Nayjest&#92;Grids&#92;Grids',
            'HTML' => 'Collective&#92;Html&#92;HtmlFacade',
            'Input' => 'Illuminate&#92;Support&#92;Facades&#92;Input',
    ...
    ]

สร้าง grid โดย

  1. <?php
    
    namespace App\Http\Controllers;
    
    use App\user;
    use HTML;
    use Nayjest\Grids\Components\Base\RenderableRegistry;
    use Nayjest\Grids\Components\ColumnHeadersRow;
    use Nayjest\Grids\Components\ColumnsHider;
    use Nayjest\Grids\Components\CsvExport;
    use Nayjest\Grids\Components\ExcelExport;
    use Nayjest\Grids\Components\FiltersRow;
    use Nayjest\Grids\Components\Filters\DateRangePicker;
    use Nayjest\Grids\Components\HtmlTag;
    use Nayjest\Grids\Components\Laravel5\Pager;
    use Nayjest\Grids\Components\OneCellRow;
    use Nayjest\Grids\Components\RecordsPerPage;
    use Nayjest\Grids\Components\RenderFunc;
    use Nayjest\Grids\Components\ShowingRecords;
    use Nayjest\Grids\Components\TFoot;
    use Nayjest\Grids\Components\THead;
    use Nayjest\Grids\EloquentDataProvider;
    use Nayjest\Grids\FieldConfig;
    use Nayjest\Grids\FilterConfig;
    use Nayjest\Grids\Grid;
    use Nayjest\Grids\GridConfig;
    
    class UsersController extends Controller
    {
    
        public function Index()
        {
    
            $query = (new User)
                ->query();
    
            $grid = new Grid(
                (new GridConfig)
                    ->setDataProvider(
                        new EloquentDataProvider($query)
                    )
                    ->setName('UserIndex') /* grid unque id */
                    ->setPageSize(20)
                    ->setColumns([
                        (new FieldConfig)
                            ->addFilter(
                                (new FilterConfig)
                                    ->setOperator(FilterConfig::OPERATOR_LIKE)
                            )
                            ->setLabel('ID')
                            ->setName('id') /* field */
                            ->setSortable(true)
                            ->setSorting(Grid::SORT_DESC)
                        ,
                        (new FieldConfig)
                            ->addFilter(
                                (new FilterConfig)
                                    ->setOperator(FilterConfig::OPERATOR_LIKE)
                            )
                            ->setLabel('Name')
                            ->setName('name')
                            ->setSortable(true)
                        ,
                        (new FieldConfig)
                            ->addFilter(
                                (new FilterConfig)
                                    ->setOperator(FilterConfig::OPERATOR_LIKE)
                            )
                            ->setLabel('Email')
                            ->setName('email')
                            ->setSortable(true)
                        ,
                        (new FieldConfig)
                            ->addFilter(
                                (new FilterConfig)
                                    ->setOperator(FilterConfig::OPERATOR_LIKE)
                            )
                            ->setLabel('Update Information')
                            ->setName('count_update')
                            ->setSortable(true)
                        ,
                        (new FieldConfig)
                            ->setLabel('Created')
                            ->setName('created_at')
                            ->setSortable(true)
                        ,
                        (new FieldConfig)
                            ->setLabel('Last Update')
                            ->setName('updated_at')
                            ->setSortable(true),
                    ])
                    ->setComponents([
                        (new THead)
                            ->setComponents([
                                (new ColumnHeadersRow),
                                (new FiltersRow)
                                    ->addComponents([
                                        (new RenderFunc(function () {
                                            return HTML::style('js/daterangepicker/daterangepicker-bs3.css')
                                            . HTML::script('js/moment/moment-with-locales.js')
                                            . HTML::script('js/daterangepicker/daterangepicker.js')
                                                . "<style>
                                                    .daterangepicker td.available.active,
                                                    .daterangepicker li.active,
                                                    .daterangepicker li:hover {
                                                        color:black !important;
                                                        font-weight: bold;
                                                    }
                                               </style>";
                                        }))
                                            ->setRenderSection('filters_row_column_created_at'),
                                        (new DateRangePicker)
                                            ->setName('created_at')
                                            ->setRenderSection('filters_row_column_created_at')
                                            ->setDefaultValue(['1990-01-01', date('Y-m-d H:i:s')]),
                                        (new DateRangePicker)
                                            ->setName('created_at')
                                            ->setRenderSection('filters_row_column_updated_at')
                                            ->setDefaultValue(['1990-01-01', date('Y-m-d H:i:s')]),
                                    ])
                                ,
                                (new OneCellRow)
                                    ->setRenderSection(RenderableRegistry::SECTION_END)
                                    ->setComponents([
                                        new RecordsPerPage,
                                        new ColumnsHider,
                                        (new CsvExport)
                                            ->setFileName('usersExport_' . date('Y-m-d'))
                                        ,
                                        (new ExcelExport())
                                            ->setFileName('usersExport_' . date('Y-m-d'))
                                        ,
                                        (new HtmlTag)
                                            ->setContent('<span class="glyphicon glyphicon-refresh"></span> Filter')
                                            ->setTagName('button')
                                            ->setRenderSection(RenderableRegistry::SECTION_END)
                                            ->setAttributes([
                                                'class' => 'btn btn-success btn-sm',
                                            ]),
                                    ]),
                            ])
                        ,
                        (new TFoot)
                            ->setComponents([
                                (new OneCellRow)
                                    ->setComponents([
                                        new Pager,
                                        (new HtmlTag)
                                            ->setAttributes(['class' => 'pull-right'])
                                            ->addComponent(new ShowingRecords)
                                        ,
                                    ]),
                            ])
                        ,
                    ])
            );
            $grid = $grid->render();
    
            return view('users.index', [
                'grid' => $grid,
            ]);
        }
    
    }
    
  2. สร้าง view \resources\views\users\index.blade.php
    @extends('layouts.app')
    
    @section('title', 'Users')
    
    @section('main-content') <a href="{{ url('/excels/form') }}">
    <button class="btn btn-success btn-sm"><span class="glyphicon glyphicon-upload"></span> Import Datas</button>
    </a> @if(!empty($text))
    <div class="container">{!! $text !!}</div>
    @endif
    <?=$grid;?>
    @stop
  3. สร้าง route โดยไปที่ \app\Http\routes.php
    ...
    Route::get('/users/index', 'UsersController@index');
    ...

ทดลองโดยเรียก /users/index ในเครื่องผมคือ http://localhost/laravel52/public/users/index grid แสดงข้อมูลออกมาแล้วแต่ จะส่งออกเป็นไฟล์ csv หรือ excel ยังไงละ ใจเย็นๆครับ อ่าน สร้าง grid ใน laravel แบบ advance ครับ

สร้างไฟล์ csv จาก phpexcel

phpexcel สร้างไฟล์ excel ได้สะดวกมาก แต่ไม่ใช่ทุกระบบจะสามารถ import ข้อมูลจากไฟล์แบบเอ็กเซลได้ การส่งออกไฟล์แบบตัวอักษรล้วนๆ และใช้เครื่องหมายคั่นแบบไฟล์ csv จึงยังจำเป็นอยู่

ที่สำคัญคือสามารถแก้หรือเพิ่มเงื่อนไขจาก code ส่งออกข้อมูลเป็น excel โดย phpexcel ที่มีอยู่เดิม โดยดัดแปลงเล็กน้อยในส่วน header และการ write data

<?php

/* PHPExcel_IOFactory - Reader */
include 'PHPOffice/PHPExcel/Classes/PHPExcel.php';

$objPHPExcel = new PHPExcel();

/* Set default style */
$defaultStyle = $objPHPExcel->getDefaultStyle();

$defaultStyle->getFont()
    ->setName('Arial')
    ->setSize(11);

$defaultStyle->getNumberFormat()
    ->setFormatCode('yyyy-mm-dd');

/* Set document properties */
$title = 'Exports_Datas_' . date('Y-m-d_H:i');
$objPHPExcel->getProperties()->setCreator('Pitt Phunsanit')
    ->setCategory('Exports Datas')
    ->setDescription($title)
    ->setKeywords('Exports Datas ' . date('Y-m-d'))
    ->setSubject($title)
    ->setTitle($title);

/* rename sheet */
$objWorkSheet = $objPHPExcel->getActiveSheet();
$objWorkSheet->setTitle('Exports Datas');

for ($rowNo = 1; $rowNo < 10; $rowNo++) {
    for ($colNo = 0; $colNo < 5; $colNo++) {

        $insert = rand(0, 1);
        if($insert == 1) {

            $colString = PHPExcel_Cell::stringFromColumnIndex($colNo);

            $coordinate = $colString . $rowNo;

            $objWorkSheet->setCellValue($coordinate, 'ส่งออกข้อมูล -> '.$coordinate);
        }
    }
}

header('Cache-Control: max-age=0');
header('Content-Encoding: UTF-8');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment;filename="'.$title.'.csv"');
echo "\xEF\xBB\xBF"; /* UTF-8 BOM */

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');

/* set Delimiter, (defaults ,) */
//$objWriter->setDelimiter('|');
//$objWriter->setEnclosure('');
/* Set line ending (defaults PHP_EOL) */
//$objWriter->setLineEnding('0x0d0a');

$objWriter->save('php://output');

ถ้าสังเกตุจะมี $insert = rand(0, 1); และ if($insert == 1) { ทำให้บาง cell ไม่มีข้อมูล เพื่อที่จะแสดงให้เห็นว่าการใช้ phpexcel จะดีกว่าการใช้ echo ส่งออกข้อมูลแบบที่ง่ายที่สุด (CSV) ในกรณีที่บางคอลัมข้อมูลไม่มี เราไม่จำเป็นต้อง echo ค่าว่าง หรือมานับ , ว่าครบมั๋ย phpexcel จะจัดการให้เอง

ถ้าเปลี่ยนรูปแบบอื่นเช่น

  • ต้องการใช้เครื่องหมายอื่นเช่น pipe | ก็สามารถกำหนดโดยใช่ setDelimiter
  • ต้องการ wrap ข้อมูลก็ใช้ setEnclosure จะปิดหัว ปิดท้ายข้อมูลแต่ละ cell ให้
  • ต้องการใช้เครื่องมายอื่นในการแบ่งข้อมูลออกเป็นชุดๆ ก็ setLineEnding

เขียนครั้งเดียวส่งออกข้อมูลได้ 2 รูปแบบ ส่วนคำสั่งที่ไม่ได้ใช้ในรูปแบบ csv เช่น setTitle ก็ไม่ทำให้มี error ดีจริงๆ phpexcel

ส่งออกข้อมูลแบบที่ง่ายที่สุด (CSV)

วิธีที่ส่งออกข้อมูลที่ง่ายที่สุด และอิมพอร์ตเข้าโปรแกรมต่างๆได้มากที่สุดคือ comma-separated values (CSV) แปลง่ายๆว่า ไฟล์ตารางที่คั่นด้วยคอมม่า แปลบ้านๆไปอีกคือ text file ที่ข้อมูลถูกแบ่งโดย , หรือเครื่องหมายอื่นเช่น pipe | โดยข้อมูลต่ละ record จะแบ่งโดยการขึ้นบรรทัดใหม่ (ใน php คือ \n)

เขียนง่ายๆ แค่มีการเพิ่ม header เข้าไปว่ามันเป็น csv นะและ echo ธรรมดาๆ

<?php

$filename = 'Exports_Datas_' . date('Y-m-d_H:i');

header('Cache-Control: max-age=0');
header('Content-Encoding: UTF-8');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment;filename="'.$filename.'.csv"');
echo "\xEF\xBB\xBF"; /* UTF-8 BOM */

/* random add datas */
for($a = 0; $a < 10; $a++) {
	$datas = [];
	for($b = 0; $b < 5; $b++) {
		$datas[$b] = 'ส่งออกข้อมูล '.rand(1, 100);
	}
	echo implode(',', $datas)."\n";
}

หลังจากเรียกไฟล์ php ก็จะเห็นว่ามีการให้ download ขึ้นมาให้ save ลองคลิกเปิดดูถ้าเครื่องมี excel อยู่ก็จะเปิดอ่านข้อมูลได้ทันที หรือจะใช้ text editor เปิดขึ้นมาดูก็ได้ ทดลองเปลี่ยนเป็นให้ดึงข้อมูลจาก database ดูครับ

จัด PHPExcel สวยๆ

การจัดแต่งเล็กน้อย จะทำให้รายงานออกมาดูน่าสนใจ จะยกตัวอย่างการใช้ style, การ merge cells, pinned (freeze) cell ไว้ไม่ให้ขยับ เช่น fixed หัวตารางไว้ให้อยู่กับที่ และการ flip กลับตัวอักษร

<?php

/* PHPExcel_IOFactory - Reader */
include 'PHPOffice/PHPExcel/Classes/PHPExcel.php';

$objPHPExcel = new PHPExcel();

/* Set default style */
$defaultStyle = $objPHPExcel->getDefaultStyle();

$defaultStyle->getFont()
    ->setName('Arial')
    ->setSize(11);

/* Set document properties */
$title = 'Exports_Datas_' . date('Y-m-d_H:i');
$objPHPExcel->getProperties()->setCreator('Pitt Phunsanit')
    ->setCategory('Exports Datas')
    ->setDescription($title)
    ->setKeywords('Exports Datas ' . date('Y-m-d'))
    ->setSubject($title)
    ->setTitle($title);

/* rename sheet */
$objWorkSheet = $objPHPExcel->getActiveSheet();
$objWorkSheet->setTitle('Exports Datas');

$styles = [

    'tableHeader1' => [
        'alignment' => [
            'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
        ],
        'fill' => [
            'color' => [
                'rgb' => 'C00000'
            ],
            'type' => PHPExcel_Style_Fill::FILL_SOLID,
        ],
        'font' => [
            'color' => [
                'rgb' => 'ffffff'
            ],
            'name' => 'Arial',
        ],
        'name' => 'Arial',
    ],

    'tableHeader2' => [
        'alignment' => [
            'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
        ],
        'fill' => [
            'color' => [
                'rgb' => '00c000'
            ],
            'type' => PHPExcel_Style_Fill::FILL_SOLID,
        ],
        'font' => [
            'color' => [
                'rgb' => 'ffffff'
            ],
            'name' => 'Arial',
        ],
        'name' => 'Arial',
    ],

    'tableRow' => [
        'alignment' => [
            'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT,
        ],
        'bold' => true,
        'fill' => [
            'color' => [
                'rgb' => '0000c0'
            ],
            'type' => PHPExcel_Style_Fill::FILL_SOLID,
        ],
        'font' => [
            'color' => [
                'rgb' => 'ffffff'
            ],
            'name' => 'Arial',
        ],
        'name' => 'Arial',
    ],

];

/* raw datas */
$headers1 = ['2557', '2558', '2559'];
$headers2 = ['Shop A', 'Shop B'];
$headersRows = ['มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'];

/* make table */
$header1ColNo = 1;
$header2ColNo = 1;
$header2PerHeaders1 = count($headers2);
foreach($headers1 as $header1)
{
    $header1CoordinateStart = PHPExcel_Cell::stringFromColumnIndex($header1ColNo) . '1';
    $header1CoordinateEnd = PHPExcel_Cell::stringFromColumnIndex($header1ColNo + $header2PerHeaders1 - 1) . '1';

    $objWorkSheet->getStyle($header1CoordinateStart)->applyFromArray($styles['tableHeader1']);
    $objWorkSheet->mergeCells($header1CoordinateStart . ':' . $header1CoordinateEnd);
    $objWorkSheet->setCellValue($header1CoordinateStart, $header1);

    /* set column */
    $header1ColNo += $header2PerHeaders1;

    foreach($headers2 as $header2)
    {
        $coordinate = PHPExcel_Cell::stringFromColumnIndex($header2ColNo) . '2';

        $objWorkSheet->getStyle($coordinate)->applyFromArray($styles['tableHeader2']);
        $objWorkSheet->setCellValue($coordinate, $header2);

        $header2ColNo++;
    }
}

$rowNo = 3;
foreach($headersRows as $header)
{
    $coordinate = 'A' . $rowNo;

    $objWorkSheet->getStyle($coordinate)->applyFromArray($styles['tableRow']);
    $objWorkSheet->setCellValue($coordinate, $header);

    $rowNo++;
}

/* random add datas */
$highestColumn = 1 + (count($headers1) * count($headers2));
$highestRow = 2 + count($headersRows);
for ($rowNo = 3; $rowNo <= $highestRow; $rowNo++) {
    for ($colNo = 1; $colNo < $highestColumn; $colNo++) {

        $colString = PHPExcel_Cell::stringFromColumnIndex($colNo);

        $coordinate = $colString . $rowNo;

        $objWorkSheet->setCellValue($coordinate, rand(0 , 100));
    }
}

/* right label */
$colString = PHPExcel_Cell::stringFromColumnIndex($colNo);
$rowNo--;

$objWorkSheet->getStyle($colString . '3')->getAlignment()
    ->setTextRotation(-90)
    ->setVERTICAL(PHPExcel_Style_Alignment::VERTICAL_TOP);

$objWorkSheet->mergeCells($colString . '3:' . $colString . $rowNo);
$objWorkSheet->setCellValue($colString . '3', 'Gross Income Per Month');

/* freeze pinned head column */
$objPHPExcel->getActiveSheet()->freezePane($colString.'3');

$objWriter =PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $title . '.xlsx"');
header('Cache-Control: max-age=0');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
$objWriter->save('php://output');