สร้างเอกสาร PDF ภาษาไทย ใน PHP ด้วย mPDF + การแก้ไขปัญหาการตัดคำภาษาไทยเพี้ยน
เมื่อผมลองสร้างไฟล์ PDF ใน PHP โดยใช้ mPDF ปัญหาที่พบคือ พอใช้ภาษาไทยแล้วมันตัดคำผิด ตามรูปเลยครับ
บทความนี้จะพูดถึงการแก้ปัญหานี้ ผมจะแยกเนื้อหาออกเป็น 2 ส่วน ส่วนแรกจะเป็นการติดตั้ง mPDF และใช้งาน Font ภาษาไทย (มีคนเขียนอธิบายเยอะแล้ว) ส่วนที่สองจะพูดถึงการแก้ปัญหาการตัดคำภาษาไทย
Part 1: การติดตั้ง mPDF และใช้งาน Font ภาษาไทย
1. ลง mPDF โดยใช้ composer ถ้าเครื่องยังไม่มี composer ก็ไปโหลดมาลงนะครับ https://getcomposer.org/download/ ลงไว้ใช้สอยตาม os นะครับ
composer require mpdf/mpdf
2. สร้างโฟลเดอร์ fonts แล้วคัดลอกไฟล์ Font ภาษาไทยที่จะใช้มาเก็บไว้ ผมใช้ TH Sarabun New ดาวน์โหลดได้ตามลิงค์นี้เลยครับ https://www.f0nt.com/release/th-sarabun-new/
ก็จะได้หน้าตาของโปรเจ็กต์ตามรูปครับ
3. สร้างไฟล์ thai_pdf_test.php (ตั้งชื่ออื่นก็ได้นะ)แล้วเขียนโค๊ดตามนี้เพื่อเรียกใช้ Font และแสดงภาษาไทย
4. รันหน้าเว็บทดสอบจะได้ตามรูปครับ
จากรูปจะมีปัญหาอยู่ 2 อย่าง การจัดวางข้อความ เพี้ยนๆ ไม่ค่อยสวย ช่องว่างมันไม่ค่อยโอเค และการตัดคำมันผิดตอนขึ้นบรรทัดใหม่บางคำ
Part 2: การแก้ไขปัญหาการตัดคำภาษาไทยเพี้ยน
สาเหตุที่ผลลัพธ์มันออกมาเพี้ยน มันเกิดเนื่องจากตัดตัดคำของ mPDF ไม่ค่อยดี เพื่อประปรุงให้ดีขึ้น ผมจะแก้ไขโดยการกำหนดขอบเขตของคำเองโดยใช้ไลบรารี https://github.com/moohooooo/thsplitlib เป็นการตัดคำโดยใช้ดิกชันารี วิธีการตัดคำมันมีหลายรูปแบบนะครับ ใช้อันนี้ไปก่อนแล้วกันง่ายดี
1. ไปดาวน์โหลดไลบรารีสำหรับตัดคำที่เว็บ https://github.com/moohooooo/thsplitlib คัดลอกมาวางในโปรเจ็กต์ จะได้โครงสร้าง ประมาณนี้
2. แก้ไขโค๊ด thai_pdf_test.php เพื่อสั่งให้ตัดคำก่อนแสดงผล ดังนี้
3. รันหน้าเว็บเพื่อทดสอบจะได้ผลลัพธ์ ดังรูป
จะเห็นว่ามันจัดได้สวยขึ้นแต่ อ้าว!!!! ซวยหล่ะทำไม่ได้ผลลัพธ์แบบนี้ อันนี้ผมลองทดลองแล้วนะครับ คือ ถ้าใช้ Font ภาษาไทยที่มากับ mPDF คือ Garuda มันจะไม่มีปัญหา แต่พอผมใช้ Font Sarabun แล้วมีปัญหา เนื่องจากมีเวลาไม่มากพอที่จะหาสาเหตุ เลยจะใช้วิธีขอบเขตของคำผมจะใช้ | คั่นแทน U+200B คือตาม คู่มือมันบอกไว้นะแต่ Font เรามันไม่ซับพอต หรืออะไรไม่รู้นะ https://mpdf.github.io/what-else-can-i-do/line-breaking.html
คำสั่ง บรรทัดนี้ เอาไว้ปิดการใช้งานตัวตัดคำของ mPDF นะครับ
$mpdf->useDictionaryLBR = false;
4. เปลี่ยนคำสั่งให้ใช้ | คั่นแทน (บรรทัด 35)
$words = $segment->get_segment_array($text);
$text = implode("|",$words);
5. แก้ไขไฟล์ vendor/mpdf/mpdf/src/Mpdf.php (บรรทัดที่ 7939)คือจะเพิ่ม | สำหรับใช้เป็นขอบเขตคำ ตอนขึ้นบรรทัดใหม่ จะได้ไม่เพี้ยน
if ($prevchar == '|') {
$breakfound = [$contentctr, $charctr, $cutcontentctr, $cutcharctr, 'discard'];
}
5. ถ้าลองรันดูเราก็จะได้หน้าตาของ pdf ประมาณนี้ ซึ่ง | มันจะโผลมาด้วย ผมก็ไม่มีเวลาไปเช็คนะ เอาง่ายๆ คือ ไป replace ออก ตอนจะแสดงผลแล้วกัน
6. เพิ่มโค๊ด ในไฟล์ vendor/mpdf/mpdf/src/Mpdf.php ลงไปอีกสองที่ บรรรทัดประมาณตามรูปนะครับ คือเราจะทำการเอา | ออก แต่คือ ถ้าเอกสารเรามี | ก็จะซวย เดี่ยวค่อยมาหาวิธีเช็คแบบละเอียดกันอีกที
รันหน้าเว็บทดสอบจะได้ pdf อย่างแจ่มเลยที่เดียว
ผลลัพธ์มันก็ถือว่าโอเคกว่าตอนแรกอยู่ ตัวตัดคำที่ใช้การอาจจะยังความถูกต้องไม่ค่อยมากนัก กรณีที่เจอคำใหม่ๆ อาจจะมีเพี้ยนไปบ้าง ก็ต้องหาวิธีการใหม่ มาใช้ตัดครับ หวังว่าจะบทความนี้จะเป็นประโยชน์กับหลายๆ คนนะครับ