เนื้อหาต่อไปนี้เราจะมาเพิ่มความสามารถสำหรับให้ DataTable ที่ใช้งานใน Codeigniter นั้น
รองรับการออกรายงานอย่างง่ายเป็นไฟล์ PDF หรือ Excel ได้ โดยจะเป็นการใช้งานสำหรับ
ข้อมูลที่มีจำนวนไม่มากนัก เช่น ข้อมูลหลักร้อยนิดๆ โดยประมาณ เราจะประยุกต์เนื้อหานี้กับ
บทความของเนื้อหาด้านล่างนี้
ใช้งาน Server side processing สำหรับ DataTable ร่วมกับ Codeigniter ตอนที่ 3
https://www.ninenik.com/content.php?arti_id=815 via @ninenik
ส่วนแรกคือไฟล์ js และ css เพิ่มเติมที่จำเป็นในการใช้งาน
<link rel="stylesheet" href="//cdn.datatables.net/buttons/1.4.1/css/buttons.dataTables.min.css"> <script src="//cdn.datatables.net/buttons/1.4.1/js/dataTables.buttons.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script> <script src="//cdn.datatables.net/buttons/1.4.1/js/buttons.html5.min.js"></script> <script src="//cdn.datatables.net/buttons/1.4.1/js/buttons.print.min.js"></script>
หมายเหตุ: เรามีการเรียกใช้งาน jquery อยู่แล้ว ในส่วน header ของ Project Codeigniter ถ้ายังไม่ได้
เรียกใช้งาน ต้องเรียกใช้งานด้วย
ส่วนที่สองคือการกำหนดให้แสดงปุ่ม และการเรียกใช้งาน เพื่อทำงานในการออกรายงาน หรือทำคำสั่ง
ที่ต้องการ
"dom": 'Bfrtip', "buttons": [ 'copy', 'csv', 'excel', 'pdf', 'print' ]
รูปแบบข้างต้นเป็นการกำหนด property สำหรับใช้งานปุ่มใน DataTable
dom คือ การจัดวางตำแหน่งของส่วนต่างๆ โดยใช้ในลักษณะของตัวย่อ
- B - Button
- l - Length changing
- f - Filtering input
- t - The Table!
- i - Information
- p - Pagination
- r - pRocessing
ลักษณะการเรียงจากซ้ายไปขวา บนลงล่าง
อย่าง Bfrtip ก็คือ เริ่มต้นด้วยแสดงปุ่ม (B) ต่อส่วนของการค้นหา (f) ต่อด้วยส่วนแสดงการประมวลผล
เมื่อเรียกข้อมูล (r) ต่อด้วยตารางข้อมูล (t) ต่อด้วยข้อมูลของตารางมุมล่างซ้าย (i) และปิดท้ายด้วย
ส่วนของการแบ่งหน้า (p) ตรงมุมล่างขวา เป็นต้น
ดูเพิ่มเติมได้ที่ https://datatables.net/examples/basic_init/dom.html
ต่อด้วยส่วนของการกำหนดเรียกใช้ปุ่มออกรายงานหรือคำสั่งเบื้องต้น
- buttons ในตัวอย่างเราจะมี
- copy ทำการ copy ข้อมูลที่แสดงในหน้านั้นๆ ไว้ใน clipboad
- csv ส่งออกเป็นไฟล์ csv
- excel ส่งออกเป็นไฟล์ excel
- pdf ส่งออกเป็นไฟล์ pdf
- และ print ส่งไปหน้าสำหรับพิมพ์
ลองนำไปใช้งานกับโค้ดจากบทความก่อนหน้า จะได้ดังนี้
<link rel="stylesheet" href="//cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css"> <link rel="stylesheet" href="//cdn.datatables.net/buttons/1.4.1/css/buttons.dataTables.min.css"> <script src="//cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script> <script src="//cdn.datatables.net/buttons/1.4.1/js/dataTables.buttons.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script> <script src="//cdn.datatables.net/buttons/1.4.1/js/buttons.html5.min.js"></script> <script src="//cdn.datatables.net/buttons/1.4.1/js/buttons.print.min.js"></script> <table id="table_server_id" class="display"> <thead> <tr> <th>#</th> <th>Province ID</th> <th>Province Name TH</th> <th>Province Name ENG</th> </tr> </thead> </table> <script type="text/javascript"> $(function(){ $('#table_server_id').DataTable( { "processing": true, // แสดงข้อความกำลังดำเนินการ กรณีข้อมูลมีมากๆ จะสังเกตเห็นง่าย "serverSide": true, // ใช้งานในโหมด Server-side processing "order": [], // กำหนดให้ไม่ต้องการส่งการเรียงข้อมูลค่าเริ่มต้น จะใช้ค่าเริ่มต้นตามค่าที่กำหนดในไฟล์ php "ajax": { "url": "<?=base_url("ajaxdata")?>", // ไฟล์ Server script php "data":{ // เพิ่มตัวแปรที่ต้องกาส่งเข้าไปแบบกำหนดเอง "page":function(){ // ใข้ข้อมูลตัวแปรชื่อ page var dataTable1 = $('#table_server_id').DataTable(); // จะใช้ข้อมูลอ้างอิงจาก dataTable return dataTable1.page.info().page; // ส่งค่าเลขหน้าปัจจุบันไปไว้ในตัวแปร page ค่าเรี่มต้นนับจาก 0 } }, "type": "POST" // ส่งข้อมูลแบบ post }, "columnDefs": [ // กำหนดลักษณะพิเสษเฉพาะสำหรับคอลัมน์ตารางที่ต้องการ { "targets": [ 0 ], // เราต้องการกำหนดคอลัมน์แรก ค่าเริ่มต้นที่ 0 "orderable": false, // ให้ไม่ต้องสามารถเรียงข้อมูลได้ เพราะเป็นลำดับรายการเฉยๆ } ], "dom": 'Bfrtip', "buttons": [ 'copy', 'csv', 'excel', 'pdf', 'print' ] } ); }); </script>
เรามาดูผลลัพธ์ที่ได้ จะเป็นดังรูปต่อไปนี้
ตัวอย่างกรณีส่งออกเป็นไฟล์ excel
ตัวอย่างกรณีส่งออกเป็นไฟล์ csv
ตัวอย่างกรณีส่งออเป็นไฟล์ pdf
ดูตัวอย่าง และทดสอบ ได้ท้ายบทความ demo1
เราจะเห็นว่า ส่วนของไฟล์ csv นั้นภาษาไทยจะเพี้ยนหรือแสดงไม่ถูกต้อง แต่กรณีไฟล์ excel นั้น
แสดงข้อมูลภาษาไทยได้ถูกต้อง ดังนั้นเวลาใช้งาน เราสามารถเลือกใช้เฉพาะส่งออกเป็นไฟล์ excel
แทนไฟล์ csv ได้
ส่วน pdf นั้น ก็จะมีปัญหาเกี่ยวกับภาษาไทยเช่นกัน ร่วมถึงรูปแบบกรแสดง ยังดูไม่ค่อยมีสัดส่วนที่เหมาะสม
เท่าไหร่ แต่ปัญหานี้สามารถแก้ไขได้
ก่อนจะอธิบายวิธีการส่งออกไฟล์ PDF ที่รองรับภาษาไทย ขอเพิ่มเติมเนื้อหาก่อนว่า ข้อมูลที่ใช้ในการสร้าง
ไฟล์นั้นมาจากข้อมูลในส่วนของ html ของตารางที่แสดงในขณะนั้น ดังนั้นถ้าต้องการให้ส่งออกข้อมูลในทุกๆ
หน้า เราจำเป็นต้องกำหนดให้แสดงข้อมูลทั้งหมดออกมาก่อน ถึงจะค่อยเรียกใช้ปุ่มส่งออกไฟล์ ทั้งนี้ก็เพราะ
ว่า เรามีใช้งาน pdfmake ในการสร้าง pdf ไฟล์ โดยทำงานผ่าน javascript ที่ฝั่งของผู้ใช้งาน ไม่ได้เป็นการ
สร้างไฟล์ pdf จากคำสั่งทางฝั่ง server ทำให้การทำงานในส่วนนี้ยังมีข้อจำกัด
อย่างที่กล่าวไปแล้วข้างต้นว่า การส่งออกไฟล์ PDF ที่นั้นใช้ pdfmake library ในการทำงาน โดยส่วนที่
จัดการสำหรับ font ตัวอักษร เรามีการเรียกใช้จากไฟล์ vfs_fonts.js
<script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script>
ที่ใช้ร่วมกับ pdfmake ซึ่งไฟล์จากลิ้งค์ข้างต้นนี้ จะไม่รองรับภาษาไทย วิธีการคือ เราต้องสร้างไฟล์ vfs_fonts.js
ที่เป็นชุด font ภาษาไทยก่อน (วิธีการทำจะอธิบายเพิ่มเติมภายหลัง) ในที่นี้ให้เราโหลดไฟล์ที่ใช้ font ตัวอย่าง
ที่รองรับภาษาไทย ชื่อ THSarabun ได้ที่ลิ้งค์นี้
คลิกขวาที่ลิ้งค์แล้วเลือก save as เพื่อบันทึก vfs_fonts.js
หลังจากดาวน์โหลดมาแล้ว ก็นำมาไว้ในโฟลเดอร์ js แล้วเรียกใช้งานจากไฟล์ของเราแทน
ต่อไปก็กำหนดชื่อ font ที่ต้องการใช้งานกับ pdfmake ในส่วนของ javascript ในที่นี้เราใช้
เป็น THSarabun
pdfMake.fonts = { THSarabun: { normal: 'THSarabun.ttf', bold: 'THSarabun-Bold.ttf', italics: 'THSarabun-Italic.ttf', bolditalics: 'THSarabun-BoldItalic.ttf' } }
และส่วนสุดท้ายการตั้งค่าการใช้งาน ในที่นี้เราจะเน้นไปในส่วนการจัดการกับการส่งออกไฟล์เป็น PDF
และเราจะตัดปุ่ม csv ออกเราสามารถใช้ปุ่ม excel แทนได้
"dom": 'Bfrtip', "buttons": [ 'copy', 'excel', { // กำหนดพิเศษเฉพาะปุ่ม pdf "extend": 'pdf', // ปุ่มสร้าง pdf ไฟล์ "text": 'PDF', // ข้อความที่แสดง "pageSize": 'A4', // ขนาดหน้ากระดาษเป็น A4 "customize":function(doc){ // ส่วนกำหนดเพิ่มเติม ส่วนนี้จะใช้จัดการกับ pdfmake // กำหนด style หลัก doc.defaultStyle = { font:'THSarabun', fontSize:16 }; // กำหนดความกว้างของ header แต่ละคอลัมน์หัวข้อ doc.content[1].table.widths = [ 50, 'auto', '*', '*' ]; doc.styles.tableHeader.fontSize = 16; // กำหนดขนาด font ของ header var rowCount = doc.content[1].table.body.length; // หาจำนวนแะวทั้งหมดในตาราง // วนลูปเพื่อกำหนดค่าแต่ละคอลัมน์ เช่นการจัดตำแหน่ง for (i = 1; i < rowCount; i++) { // i เริ่มที่ 1 เพราะ i แรกเป็นแถวของหัวข้อ doc.content[1].table.body[i][0].alignment = 'center'; // คอลัมน์แรกเริ่มที่ 0 doc.content[1].table.body[i][1].alignment = 'center'; doc.content[1].table.body[i][2].alignment = 'left'; doc.content[1].table.body[i][3].alignment = 'right'; }; console.log(doc); // เอาไว้ debug ดู doc object proptery เพื่ออ้างอิงเพิ่มเติม } }, // สิ้นสุดกำหนดพิเศษปุ่ม pdf 'print' , 'pageLength' ]
คำสั่งต่างๆ ในฟังก์ชั่น ส่วนของ customize เป็นรูปแบบการใช้งานของ pdfmake สามารถดูการปรับค่าต่าง
เพิ่มเติมได้ที่ลิ้งค์นี้
ต่อไปมาดูโค้ดเต็มที่เราเรียกใช้งาน
<link rel="stylesheet" href="//cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css"> <link rel="stylesheet" href="//cdn.datatables.net/buttons/1.4.1/css/buttons.dataTables.min.css"> <script src="//cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script> <script src="//cdn.datatables.net/buttons/1.4.1/js/dataTables.buttons.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script> <script src="<?=base_url('js/vfs_fonts.js')?>"></script> <script src="//cdn.datatables.net/buttons/1.4.1/js/buttons.html5.min.js"></script> <script src="//cdn.datatables.net/buttons/1.4.1/js/buttons.print.min.js"></script> <table id="table_server_id" class="display"> <thead> <tr> <th>#</th> <th>Province ID</th> <th>Province Name TH</th> <th>Province Name ENG</th> </tr> </thead> </table> <script type="text/javascript"> pdfMake.fonts = { THSarabun: { normal: 'THSarabun.ttf', bold: 'THSarabun-Bold.ttf', italics: 'THSarabun-Italic.ttf', bolditalics: 'THSarabun-BoldItalic.ttf' } } $(function(){ $('#table_server_id').DataTable( { "processing": true, // แสดงข้อความกำลังดำเนินการ กรณีข้อมูลมีมากๆ จะสังเกตเห็นง่าย "serverSide": true, // ใช้งานในโหมด Server-side processing "order": [], // กำหนดให้ไม่ต้องการส่งการเรียงข้อมูลค่าเริ่มต้น จะใช้ค่าเริ่มต้นตามค่าที่กำหนดในไฟล์ php "ajax": { "url": "<?=base_url("ajaxdata")?>", // ไฟล์ Server script php "data":{ // เพิ่มตัวแปรที่ต้องกาส่งเข้าไปแบบกำหนดเอง "page":function(){ // ใข้ข้อมูลตัวแปรชื่อ page var dataTable1 = $('#table_server_id').DataTable(); // จะใช้ข้อมูลอ้างอิงจาก dataTable return dataTable1.page.info().page; // ส่งค่าเลขหน้าปัจจุบันไปไว้ในตัวแปร page ค่าเรี่มต้นนับจาก 0 } }, "type": "POST" // ส่งข้อมูลแบบ post }, "columnDefs": [ // กำหนดลักษณะพิเสษเฉพาะสำหรับคอลัมน์ตารางที่ต้องการ { "targets": [ 0 ], // เราต้องการกำหนดคอลัมน์แรก ค่าเริ่มต้นที่ 0 "orderable": false, // ให้ไม่ต้องสามารถเรียงข้อมูลได้ เพราะเป็นลำดับรายการเฉยๆ } ], "dom": 'Bfrtip', "buttons": [ 'copy', 'excel', { // กำหนดพิเศษเฉพาะปุ่ม pdf "extend": 'pdf', // ปุ่มสร้าง pdf ไฟล์ "text": 'PDF', // ข้อความที่แสดง "pageSize": 'A4', // ขนาดหน้ากระดาษเป็น A4 "customize":function(doc){ // ส่วนกำหนดเพิ่มเติม ส่วนนี้จะใช้จัดการกับ pdfmake // กำหนด style หลัก doc.defaultStyle = { font:'THSarabun', fontSize:16 }; // กำหนดความกว้างของ header แต่ละคอลัมน์หัวข้อ doc.content[1].table.widths = [ 50, 'auto', '*', '*' ]; doc.styles.tableHeader.fontSize = 16; // กำหนดขนาด font ของ header var rowCount = doc.content[1].table.body.length; // หาจำนวนแะวทั้งหมดในตาราง // วนลูปเพื่อกำหนดค่าแต่ละคอลัมน์ เช่นการจัดตำแหน่ง for (i = 1; i < rowCount; i++) { // i เริ่มที่ 1 เพราะ i แรกเป็นแถวของหัวข้อ doc.content[1].table.body[i][0].alignment = 'center'; // คอลัมน์แรกเริ่มที่ 0 doc.content[1].table.body[i][1].alignment = 'center'; doc.content[1].table.body[i][2].alignment = 'left'; doc.content[1].table.body[i][3].alignment = 'right'; }; console.log(doc); // เอาไว้ debug ดู doc object proptery เพื่ออ้างอิงเพิ่มเติม } }, // สิ้นสุดกำหนดพิเศษปุ่ม pdf 'print' , 'pageLength' ] } ); }); </script>
ผลลัพธ์ที่ได้จะเป็นดังนี้
เราทดสอบออกรายงานเป็น pdf ดู โดยก่อนออกรายงานให้เลือกตรงปุ่มสุดท้าย แล้วแล้วแสดงทั้งหมด 100 รายการ
เพื่อทดสอบดูกรณีแสดงข้อมูลทั้งหมด จะได้ผลลัพธ์ดังนี้
จะเห็นว่ามีการแบ่งรายการใน PDF ไฟล์ ออกเป็น 3 หน้า และแต่ละหน้าก็จะแสดงหัวข้อของรายการกับไว้ด้วย
ในส่วนของภาษาไทยก็แสดงไม่มีปัญหา การจัดตำแหน่งก็เป็นไปตามตัวอย่างทดสอบ เท่านี้ เราก็สามารถออก
รายงานเป็น PDF ได้อย่างสวยงาม อย่างไรก็ตาม เราสามารถจัดรูปแบบอื่นๆ เท่าที่ pdfmake จะรองรับได้โดย
ดูได้ที่ลิ้งค์ที่กล้าวไปแล้วด้านบน
ทดสอบตัวอย่างได้ที่ demo2 ในท้ายบทความ