Phalcon PHPExcel, Create Excel file in Phalcon PHP Framework

อีกหนึง Library ที่สำคัญเวลาทำ Report คือการสร้างไฟล์ Excel ซึ่ง Library ที่ PHP Programmer นิยมใช้กันคือ PHPExcel ซึ่งวิธีใช้งานก็ไม่ยาก อ่านคู่มือในเว็บก็คิดว่าใช้กันได้ทุกคน แต่ถ้าจะเอามาใช้งานร่วมกันกับ Phalcon หล่ะ ต้องทำยังไงบ้าง?

ติดตั้ง PHPExcel ผ่าน Composer

ตามปกติเลย ไปหา package จาก packagist.org แล้วอันไหนที่เค้าใช้กันเยอะๆ ก็เลือกอันนั้นมา แปะใน composer.json

{
    "require": {
        ...
        "phpoffice/phpexcel": "dev-master",
        ...
    }
}

เอา Library มาใช้

เว็บต่างประเทศหลายเว็บจะบอกให้เอา PHPExcel ไปเก็บไว้ที่ /app/library/ แล้วค่อยใช้ registerDirs ผ่าน loader แต่เราจะไม่ทำแบบนั้น เพราะไม่อยากให้ขนาดของ Project ใหญ่เกินไป และที่สำคัญคือ ขี้เกียจมานั่ง update library ด้วยมือเอาเอง (ใช้ Composer สบายกว่าเยอะ)

สมมุติว่าเราจะสร้างไฟล์ Excel ผ่าน Action ที่ชื่อ exportExcelAction() ก็ทำตาม Step เลย

สร้าง Action ใน Controller

public function exportAction($kind = 'default', $filter = 'default') {  
    ...
}

include library จาก vendor

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

/** PHPExcel_Writer_Excel2005 */
include '../vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5.php';  

สร้าง instance

สร้าง instance ของ PHPExcel แล้วตั้งชื่อ Sheet ว่า Membership จุดที่น่าสังเกตคือเราจะใช้ new \PHPExcel();

$objPHPExcel = new \PHPExcel();
$objPHPExcel->getActiveSheet()->setTitle('Membership ' . date('Y-m-d'));

สร้างชื่อ Field ไว้ที่แถวแรกของ Sheet

ตรงนี้เราสามารถใช้ setCellValue เพื่อระบุตำแหน่งท่ีจะใส่ข้อมูลลงไป

$objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A1', 'No')
            ->setCellValue('B1', 'Name')
            ->setCellValue('C1', 'Name Eng')
            ->setCellValue('D1', 'Citizen ID')
            ->setCellValue('E1', 'Code')
            ->setCellValue('F1', 'Type')
            ->setCellValue('G1', 'Bloodgroup')
            ->setCellValue('H1', 'Image');

loop เขียนข้อมูล

query ข้อมูลออกมาตามปกติ แล้ว loop เพื่อเขียนข้อมูลทีละแถว โดยใช้ $rowMember เป็นตัวขยับแถว

$objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A' . ($rowMember + 1), ($rowMember))
            ->setCellValue('B' . ($rowMember + 1), $memberTitle . ' ' . $member->firstname . ' ' . $member->lastname)
            ->setCellValue('C' . ($rowMember + 1), $memberTitleEn . ' ' . ucwords(strtolower($memberMetaArray['firstname_en'])) . ' ' . ucwords(strtolower($memberMetaArray['lastname_en'])))
            ->setCellValue('D' . ($rowMember + 1), $member->citizenid)
            ->setCellValue('E' . ($rowMember + 1), $memberCode)
            ->setCellValue('F' . ($rowMember + 1), $memberType)
            ->setCellValue('G' . ($rowMember + 1), $member->bloodgroup)
            ->setCellValue('H' . ($rowMember + 1), $memberMetaImage);

สร้างไฟล์ Excel

ตอนนี้เราจะตั้งชื่อไฟล์ และสร้างไฟล์ on the fly เพื่อส่งต่อให้ download เราเลือกใช้ \PHPExcel_Writer_Excel5 เพราะ ลองใช้ \PHPExcel_Writer_Excel2007 แล้วเดี้ยง

// file name to output
$fname = date("Ymd_his") . ".xls";

// temp file name to save before output
$temp_file = tempnam(sys_get_temp_dir(), 'phpexcel');

$objWriter = new \PHPExcel_Writer_Excel5($objPHPExcel);
$objWriter->save($temp_file);

กำหนด header เพื่อให้ download ไฟล์อัตโนมัติ

$response = new \Phalcon\Http\Response();

// Redirect output to a client’s web browser (Excel2005)
$response->setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$response->setHeader('Content-Disposition', 'attachment;filename="' . $fname . '"');
$response->setHeader('Cache-Control', 'max-age=0');

// If you're serving to IE 9, then the following may be needed
$response->setHeader('Cache-Control', 'max-age=1');

//Set the content of the response
$response->setContent(file_get_contents($temp_file));

// delete temp file
unlink($temp_file);

//Return the response
return $response;  

ง่ายๆ แค่นี้ก็สามารถสร้างไฟล์ Excel ด้วย Phalcon โดยใช้ PHPExcel ได้แล้ว