P2. Đọc & xuất file Excel với thư viên PHPExcel

PHP & MySQL 19/11/2017 07:00 1008
PHPExcel là một thư viện mở cho phép bạn làm việc với các loại bảng tính như Excel, CSV, OpenOffice, PDF...Có thể nói rằng PHPExcel là thư viện khá hoàn thiện và tốt nhất tính tới thời điểm này. Thì trong bài viết này mình sẽ chia sẻ với các bạn một số kinh nghiệm làm việc với PHPExcel của mình.

Đọc & xuất file Excel với thư viên PHPExcel

PHPExcel là một thư viện mở cho phép bạn làm việc với các loại bảng tính như Excel, CSV, OpenOffice, PDF...Có thể nói rằng PHPExcel là thư viện khá hoàn thiện và tốt nhất tính tới thời điểm này. Thì trong bài viết này mình sẽ chia sẻ với các bạn một số kinh nghiệm làm việc với PHPExcel của mình.

Ở phần trước thì mình đã gới thiệu tổng quan, các hàm hay được sử dụng trong PHPExcel rồi. Trong phần tiếp theo này mình sẽ hướng dẫn các bạn cách xuất dữ liệu ra một file Excel hoàn chỉnh nhé. Để có thể xuất được một file Excel nhìn nó sáng sủa hợp lý thì nó cần rất nhiều kỹ thuật, hay là còn mắt thẩm mỹ để thiết kế e.g: merge cột & dòng, độ rộng phù hợp cho mỗi cột, màu nên, màu chữ, border..vvv

1. Tạo một File Excel

Ví dụ 01: Xuất ra file Excel

<?php 
	require_once('./PHPExcel-path/Classes/PHPExcel.php');
	$excelData = array(
		0 => array('Hoàng Văn Thiệu','27','F','Gia Lâm, Hà Nội', 'abc@gmail.com', '+0983 070809', 'http://www.chiasephp.net/' ),
		1 => array('Hoàng Lão Tà','27','F','Nguyễn Trãi, Thanh Xuân, Hà Nội', 'hoanglaota@gmail.com', '+0983 070809', 'http://www.chiasephp.net/' ),
		2 => array('Đinh Đức Hạng','27','F','Mỹ Đức, Hà Nội', 'hangduc@gmail.com', '+0983 070809', 'http://www.chiasephp.net/' ),
		3 => array('Triệu Ngọc Ban','27','F','Yên Mỹ, Lạng Giang, Bắc Giang', 'ngocban@gmail.com', '+0983 070809', 'http://www.chiasephp.net/' ),
		4 => array('Ngô Đức Trung','27','F','TP. Bắc Giang, Bắc Giang', 'ductrung@gmail.com', '+0983 070809', 'http://www.chiasephp.net/' ),
		5 => array('Bùi Văn Thuấn','27','F','Tân Thanh, Lạng Sơn', 'thuan.bui@gmail.com', '+0983 070809', 'http://www.chiasephp.net/' ),
		6 => array('Trân Văn Vũ','27','F','Giao Thủy, Nam Định', 'tranvanvu@gmail.com', '+0983 070809', 'http://www.chiasephp.net/' ),
		7 => array('Trần Nghĩa Giáp','27','F','Cổ Lễ, Nam Định', 'trannghiagiap@gmail.com', '+0983 070809', 'http://www.chiasephp.net/' ),
		8 => array('Phạm Đức Thắng','27','F','Tam Trinh, Hà Nội', 'thtech@vietiso.com', '+0983 070809', 'http://www.chiasephp.net/' ),
	);
	
	// Khởi tạo đối tượng
	$objPHPExcel = new PHPExcel();
	define('EOL', (PHP_SAPI == 'cli') ? PHP_EOL : '<br />');
    $callStartTime = microtime(true);
	
	$creator = 'Admin www.chiasephp.net';
    $titlePage = 'PHPExcel Example';
    // Set document properties
    $objPHPExcel->getProperties()->setCreator($creator)
            ->setLastModifiedBy("")
            ->setTitle($titlePage)
            ->setSubject($titlePage)
            ->setDescription("Excel Sheet")
            ->setKeywords("Excel Sheet")
            ->setCategory($creator);
	
	// Thiết lập worksheet
	$objPHPExcel->setActiveSheetIndex(0);
	
	// Thêm tiêu đề cho từng cột
	$objPHPExcel->getActiveSheet()
				->setCellValue('A1', 'FullName')
				->setCellValue('C1', 'Age')
				->setCellValue('D1', 'Gender')
				->setCellValue('E1', 'Address')
				->setCellValue('E1', 'Email')
				->setCellValue('E1', 'Phone')
				->setCellValue('E1', 'Website');
	
	// Thực hiện thêm dữ liệu vào từng ô bằng vòng lặp.
	// Bắt đầu từ dòng thứ 2
	$ii = 1;
	for($i=0; $i<count($excelData); $i++){
		$ii += 1;
		$objPHPExcel->getActiveSheet()->setCellValue('A'.$ii, $excelData[$i][0]);
		$objPHPExcel->getActiveSheet()->setCellValue('B'.$ii, $excelData[$i][1]);
		$objPHPExcel->getActiveSheet()->setCellValue('C'.$ii, $excelData[$i][2]);
		$objPHPExcel->getActiveSheet()->setCellValue('D'.$ii, $excelData[$i][3]);
		$objPHPExcel->getActiveSheet()->setCellValue('E'.$ii, $excelData[$i][4]);
		$objPHPExcel->getActiveSheet()->setCellValue('F'.$ii, $excelData[$i][5]);
		$objPHPExcel->getActiveSheet()->setCellValue('G'.$ii, $excelData[$i][6]);
	}
	
	// Set Tạo tiêu đề cho worksheet
	$objPHPExcel->getActiveSheet()->setTitle($titlePage);
?>

Try In Out

Kết quả:

Oh nó đã chạy :). Nhưng nhìn nó xấu quá đúng không?? Bây giờ chúng ta bắt tay vào chỉnh sửa nó một ít nhé.

2. Thiết lập width cho các cột

Mình thấy có hai cách để làm việc này.

Cách 1: Thiết lập width cho từng cột

$objPHPExcel->getActiveSheet()->getColumnDimension("A")->setWidth(10);
$objPHPExcel->getActiveSheet()->getColumnDimension("D")->setWidth(15);
$objPHPExcel->getActiveSheet()->getColumnDimension("E")->setWidth(15);
$objPHPExcel->getActiveSheet()->getColumnDimension("F")->setWidth(10);
$objPHPExcel->getActiveSheet()->getColumnDimension("G")->setWidth(20);

Cách 2: Thiết lập width tự động cho các cột(autosize)

//PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);
foreach(range('A','G') as $column) {
	$objPHPExcel->getActiveSheet()->getColumnDimension($column)->setAutoSize(true);
}

Try In Out

Kết quả:

3. Căn lề cột/hàng/cell.

Trong PHPExcel để căn lề một cột/hàng/cell thì có hai hàm sau.

setHorizontal(): Căn lề hai bên LEFT,CENTER, RIGHT.

setVertical(): Căn lề trên dưới TOP, CENTER, RIGHT.

Ví dụ: Mình muốn cột C(Gender) căn về bên phải, ỏ giữa.

$objPHPExcel->getActiveSheet()->getStyle('C')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
$objPHPExcel->getActiveSheet()->getStyle('C')->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
// Hoặc cho một cột xác định
$objPHPExcel->getActiveSheet()->getStyle('C1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
// Hoặc từ 1->5
$objPHPExcel->getActiveSheet()->getStyle('C1:C5')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);

Try In Out

4. Border - Background- Color.

$tblBorderOutline = array(
	'borders' => array(
		'allborders' => array(
			'style' => PHPExcel_Style_Border::BORDER_THIN,
			'color' => array('argb' => '000000'),
		),
	),
);
$tblBackgroundHeader = array(
	'fill' => array(
		'type' => PHPExcel_Style_Fill::FILL_SOLID,
		'color' => array('rgb' => 'efefef')
	)
);
$objPHPExcel->getActiveSheet()->getStyle('A1:G1')->applyFromArray($tblBorderOutline);
$objPHPExcel->getActiveSheet()->getStyle('A1:G1')->applyFromArray($tblBackgroundHeader);

5. Thiết lập giá trị HTML cho Cell

Trong một số trường hợp bạn cần trình bày HTML trong dữ liệu. Và bạn muốn  nó vẫn dữ được 

Ví dụ: Mình sẽ chỉnh sửa một chút nhé.

$excelData = array(
	0 => array('Họ và tên:<strong>Hoàng Văn Thiệu</strong><br/>A:<strong>...Hà Nội</strong><br/>E:<u>abc@gmail.com</u><br/>P:<strong>+0983 070809</strong>'),
	1 => array('Họ và tên:<strong>Bùi Văn Thuấn</strong><br/>A:<strong>...Lạng Sơn</strong><br/>E:<u>thuan.bui@gmail.com</u><br/>P:<strong>+0983 070809</strong>')
);

Try In Out

Để giải quyết việc này trong trong PHPExcel cho phép bạn làm được điều này bằng cách sử dụng Helper HTML hàm toRichTextObject().

$wizard = new PHPExcel_Helper_HTML();
$objPHPExcel->getActiveSheet()->setCellValue('A'.$ii, $wizard->toRichTextObject($excelData[$i][0]));

Try In Out

Okey. HTML đã được xử lý rồi đúng không. Nhưng 100% bạn sẽ bị lỗi font nếu bạn viết tiếng việt vào đó. Để giải quyết vấn đề đó mình có một giải pháp sau.

Bạn tìm hepler HTML với path như sau PHPExcel/Classes/PHPExcel/Helper/HTML.php và tới hàm toRichTextObject() tìm dòng 

 $loaded = @$dom->loadHTML($html);

Thay bằng dòng code.

$loaded = @$dom->loadHTML('<?xml encoding="UTF-8">' . $html);

6. Chèn hình ảnh vào File Excel

Trong một số trường hợp bạn cần chèn một cái logo hay một cái biểu đồ hay một hình ảnh bất kỳ vào File Excel. PHPExcel cung cấp cho chúng ta một đối tượng PHPExcel_Worksheet_Drawing cho phép chúng ta xử lý việc này.

Ví dụ: Chèn logo vào File Excel

$objDrawing = new PHPExcel_Worksheet_Drawing();
$objDrawing->setName($titlePage);
$objDrawing->setDescription($titlePage);
$logo_URL = ABSPATH."/isocms/skin/images/chiasephp_logo_tryit.png"; // DIR chứ không phải URL
$objDrawing->setPath($logo_URL);
$objDrawing->setCoordinates('A'.$ii);                      
//setOffsetX works properly
$objDrawing->setOffsetX(5); 
$objDrawing->setOffsetY(5);                
//set width, height
$objDrawing->setWidth(165); 
$objDrawing->setHeight(52); 
$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());

Try In Out

7. Dropdown List

Nếu bạn muốn tại một cell bất kỳ sẽ hiển thị một menu Dropdown cho phép người dùng lựa chọn một trong các giá trị. Thích hợp trong các trường hợp bạn làm một template mẫu cho phép người dùng nhập liệu.

Ví dụ: Hiển thị các dropdown list cho cột C.

$listOptions = 'F,M';
for($i=2; $i<$objPHPExcel->getActiveSheet()->getHighestRow(); $i++){
	$objValidation = $objPHPExcel->getActiveSheet()->getCell('C'.$i)->getDataValidation();
	$objValidation->setType(PHPExcel_Cell_DataValidation::TYPE_LIST);
	$objValidation->setErrorStyle(PHPExcel_Cell_DataValidation::STYLE_INFORMATION);
	$objValidation->setAllowBlank(true);
	$objValidation->setShowDropDown(true);
	$objValidation->setErrorTitle('Input error');
	$objValidation->setError('Value is not in list');
	$objValidation->setFormula1('"'.$listOptions.'"');
}

Lưu ý: Các option cách nhau bởi dấu ,

Try In Out

8. Tổng kết

Nói chung kiến thức về PHPExcel thì rất nhiều trong một hai bài viết mình không thể nói hết được. Bạn có thể vào website của nó tìm phần Docs để tìm hiểu thêm. Trong bài viết này mình chỉ liệt kê một số chức năng mình hay sử dụng khi làm việc với thư viện này.

Xem Thêm

Profile photo of adminTheHalfHeart

B.V.T

Sinh ra và lớn nên ở Bắc Giang. Hiện tại thì tôi đang là một lập trình viên tại VietISO. Tôi lập website này với mục đích là bookmark những gì tôi đã đọc qua và mong muốn chia sẻ những gì tôi biết.