12/08/2018, 10:52

[CakePHP] Xuất dữ liệu ra Excel sử dụng thư viện PHPExcel (p2)

Ở phần 1 tôi đã trình bày sơ qua về cách tích hợp PHPExcel vào CakePHP. Bài này tôi xin chia sẻ thêm một vài tính năng khác như cách thiết lập awidth, height của dòng cột, cố định vị trí dòng cột, hay style cho cell dữ liệu để nội dung được thân thiện hơn, hay phục vụ cho việc in ấn file. Việc ...

Ở phần 1 tôi đã trình bày sơ qua về cách tích hợp PHPExcel vào CakePHP. Bài này tôi xin chia sẻ thêm một vài tính năng khác như cách thiết lập awidth, height của dòng cột, cố định vị trí dòng cột, hay style cho cell dữ liệu để nội dung được thân thiện hơn, hay phục vụ cho việc in ấn file.

Việc thiết lập độ rộng cột hay chiều cao hàng thực hiện rất đơn giản, chỉ việc gọi đến các hàm tương ứng rồi cho đối số vào là hoàn thành, đó chính là setWidth() và setRowHeight(), cách dùng như đoạn code này ví dụ bạn chắc chắn ko có sản phẩm nào có giá từ chục triệu trở lên thì tối đa số các con số là 7, vậy hãy set là 10 cho rộng rãi cửa nhà :

/*
 * now i will set awidth for Price column to 10 (can fill 8 number characters) * or you can set auto awidth for it by using setAutoSize(true)
*/
$this->PhpExcel->getActiveSheet()->getColumnDimension('D')->setWidth(10);

Vậy còn height? trong demo này có thể lấy minh hoạ rằng dòng trống sau bảng dữ liệu phải rộng hơn để cho nhìn cảm giác thoải mái hơn chút :

// set that blank row's height to 30pt by using setRowHeight()
$this->PhpExcel->getActiveSheet()->getRowDimension($next2Row - 1)->setRowHeight(25);

Căn lề dữ liệu

Đầu tiên là header của bảng dữ liệu, tôi sẽ thiết lập để nó được căn lề giữa cho cả 2 chiều ngang (dùng setHorizontal) và dọc (dùng setVertical). Nhưng trước đó, phải cần xem là căn cho cell nào hay là một dải các cell, vùng các cell bằng getStyle(), rồi sẽ getAlignment() để cho PHPExcel biết ta sẽ style về lề dữ liệu :

// then align heading to center
$this->PhpExcel->getActiveSheet()->getStyle('A7:F7')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$this->PhpExcel->getActiveSheet()->getStyle('A7:F7')->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);

Như bạn thấy chỉ cần truyền hằng số về căn lề đã đươc định sẵn thì cell đã được style lề, ngoài căn giữa thì còn có thể chọn right hay left theo đúng cú pháp trên.

Tiếp theo là style cho bảng dữ liệu sau header, trong demo này thì ta biết chắc dữ liệu sẽ được fill vào từ dòng 8 còn dòng cuối của bảng có thể lấy qua biến $$ext2Row trừ đi 2 sẽ ra kết quả. Hai cột đầu tiên là số thứ tự (No) và mã sản phẩm (Code) sẽ canh giữa theo cả 2 chiều :

// ok, we have $next2Row so we know current row.
// we will style from row 8 for cell table
// firstly, column A (No) will be centered
$this->PhpExcel->getActiveSheet()->getStyle('A8:A' . (string)($next2Row - 2))->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$this->PhpExcel->getActiveSheet()->getStyle('A8:A' . (string)($next2Row - 2))->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);

Mặc định cột Product được căn lề trái nên nếu cần thiết thì chỉ set lề chiều dọc nữa mà thôi

$this->PhpExcel->getActiveSheet()->getStyle('C8:C' . (string)($next2Row - 2))->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);

Cuối cùng là 3 cột cuối Price, Quantity và Sub Total đều chứa dữ liệu kiểu số nên ta sẽ để căn lề phải chiều ngang và căn giữa chiều dọc :

$this->PhpExcel->getActiveSheet()->getStyle('D8:F' . (string)($next2Row - 2))->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
$this->PhpExcel->getActiveSheet()->getStyle('D8:F' . (string)($next2Row - 2))->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);

Bạn hẳn nhận thấy rằng đang thừa code một chút, bởi vì dải A8:F(cuối) đều căn lề giữa chiều dọc nên cần thu gọn bớt như sau là đủ :

$this->PhpExcel->getActiveSheet()->getStyle('A8:F' . (string)($next2Row - 2))->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
Chú ý :
+ bạn để ý rằng phải ép kiểu string vì getStyle() nhận vào đối số dạng chuỗi
+ nếu dùng bản dưới 1.7.0 thì sẽ chỉ set được style cho 1 cell

Border

Giờ đến lúc thiết lập các border cần thiết để khi in ra nhìn sẽ đẹp hơn, rõ ràng với khung viền bao quanh bảng dữ liệu. Để thiết lập thì bạn cần gọi getBorders() trước tiên, sau đó là border nào bạn định format (trái, phải, trên dưới hay tất cả) và cuối cùng sẽ là loại border nào bạn muốn. Các loại border được hỗ trợ rất nhiều, cơ bản có THIN, THICK, DOTTED, DASHED, DOUBLE, DASHDOT ...

// header's borders should be bold so i use BORDER_THICK for all borders
$this->PhpExcel->getActiveSheet()->getStyle('A7:F7')
->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK);
// and data table should be THIN
$this->PhpExcel->getActiveSheet()->getStyle('A8:F' . (string)($next2Row - 2))
->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
// but outside border should be THICK
$this->PhpExcel->getActiveSheet()->getStyle('A8:F' . (string)($next2Row - 2))
->getBorders()->getBottom()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK);
$this->PhpExcel->getActiveSheet()->getStyle('A8:F' . (string)($next2Row - 2))
->getBorders()->getLeft()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK);
$this->PhpExcel->getActiveSheet()->getStyle('A8:F' . (string)($next2Row - 2))
->getBorders()->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK);

Trong demo này chỗ thích hợp để link nhất chắc là tên khách hàng, chẳng hạn gắn vào đó email của khách hàng và khi click vào đó sẽ khởi động trình soạn thảo mail gửi cho khách hàng. Hoặc là URL dẫn đến chính invoice đó trên giao diện web             </div>
            
            <div class=

0