เพราะว่า word นั้นมีความสามารถปรับแต่งรูปแบบได้ซับซ้อนมากกว่า excel อยู่มาก อย่างน้อยแค่ตำแหน่งของส่วนต่างๆ ในแบบฟอร์มก็มีมากกว่า excel ที่เลือกตำแหน่งได้แค่ว่าจะใส่ column / row ไหน
การใช้ PHP สร้างไฟล์ word ขึ้นมาการสร้างไฟล์แม่แบบขึ้นก่อน โดยการสร้างตัว word template ขึ้นมาก่อนโดยใช้โปรแกรม Microsoft Word สร้างเอกสารไปตามปกติ จึงง่ายกว่า จากนั้นก็แก้เพียงแต่ในส่วนที่่ต้องการจะแทนค่าให้ใส่ ${key name} ลงไป ( ระวังเรื่องช่องว่างด้วยนะครับ ) หรือส่วนที่ต้องการ repeat ก็เพิ่ม ${key name} … ${/key name} เข้าไปเท่านั้นจะง่ายกว่า ไฟล์ในตัวอย่างนี้สามารถโหลดได้จาก template.docx
จากนั้นก็เขียน code
PHPWord/template.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <?php ini_set('max_execution_time', 0); ini_set('memory_limit', '-1'); include '../vendor/autoload.php'; use PhpOffice\PhpWord; $title = 'Template Render ' . date('Y-m-d H:i:s'); /* load template */ $templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('template.docx'); /* fill data */ $templateProcessor->setValue('header', $title); /* random data */ $scores = []; for ($a = 0; $a < 10; $a++) { $scores[$a + 1] = rand(0, 100); } /* clone table row and fill */ $templateProcessor->cloneRow('student_id', count($scores)); foreach ($scores as $key => $value) { $templateProcessor->setValue('score#' . $key, htmlspecialchars($value, ENT_COMPAT, 'UTF-8')); $templateProcessor->setValue('student_id#' . $key, htmlspecialchars($key, ENT_COMPAT, 'UTF-8')); } /* clone all block */ $templateProcessor->cloneBlock('repeater', 5); header("Content-Description: File Transfer"); header('Content-Disposition: attachment; filename="' . $title . '.docx"'); header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document'); header('Content-Transfer-Encoding: binary'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Expires: 0'); $templateProcessor->saveAs('php://output'); |
อธิบาย code
- การทำงานโดยจะโหลด ตัว PHPWord มาใช้ก่อน จะสังเกตว่าจะมีการใช้ namespaces แทนที่จะใช้ include เข้ามาเหมือน PHPExcel
- กำหนดจุดที่จะกรอกข้อมูลโดยใส่ ${key name} ใน word เช่น ${header} จากนั้นใน PHP ก็ส่งค่าตัวแปรไปแทนที่โดยใช้
fill data to template1$templateProcessor->setValue('header', $title);
- สามารถ repeat ตารางได้โดยการใส่ ${key name} ใน column ที่ต้องการคัดลอกแถวทั้งแถว เช่น ${student_id} และสั่งให้คัดลอกแถวโดยใช้
clone row1$templateProcessor->cloneRow('student_id', จำนวนครั้ง);
- สามารถเติมช้อมูลให้คอลัมน์ที่เพิ่มมาใหม่นี้โดยใช้เพิ่มขึ้นมาเพิื่อจะแทนที่ลำดับที่เพิ่มขึ้นมานั่นเอง
fill array to template1234foreach ($scores as $key => $value) {
$templateProcessor->setValue('score#' . $key, htmlspecialchars($value, ENT_COMPAT, 'UTF-8'));
$templateProcessor->setValue('student_id#' . $key, htmlspecialchars($key, ENT_COMPAT, 'UTF-8'));
}
สังเกตว่ามี
เพิ่มขึ้นมาเพื่อจะแทนที่ลำดับที่เพิ่มขึ้นมานั่นเอง
1#' . $key
- ในรูปแบบตารางที่ซับซ้อน เช่น ตาราง “ใบขออนุญาตสอบซ่อม” ที่ต้องทำซ้ำหลายแถวและหลายคอลัมน์พร้อม ๆ กัน ทั้งตารางจะไม่สามารถใช้
clone rowแทน แต่จะไม่สามารถใส่ตัวแปรลงไปแทนที่ได้ใน version นี้ ( PHPWord version 0.13.0 )1$templateProcessor->cloneBlock('repeater', จำนวนครั้ง);