ป้ายกำกับ: Technical Seo

PHPExcel แสดงตัวเลขเป็นวันที่PHPExcel แสดงตัวเลขเป็นวันที่

ในฐานะนักพัฒนาระบบที่ต้องจัดการข้อมูลขนาดใหญ่ การส่งออกข้อมูลจากฐานข้อมูล (เช่น PostgreSQL) ไปยังรูปแบบไฟล์ Spreadsheet (เช่น Excel) เป็นงานที่พบได้บ่อย แต่ปัญหาที่พบบ่อยและสร้างความสับสนให้กับผู้ใช้งานคือ การที่ตัวเลขหรือวันที่ที่ควรแสดงผลอย่างถูกต้อง กลับถูก PHPExcel แสดงเป็นตัวเลขลำดับ (Serial Number) หรือรูปแบบวันที่ที่ไม่เข้าใจ

ปัญหานี้ไม่ได้เกิดจากความผิดพลาดของฐานข้อมูล PostgreSQL โดยตรง แต่เกิดจากวิธีการที่ PHPExcel (หรือไลบรารี PHPExcel เวอร์ชันเก่า) ตีความประเภทข้อมูล (Data Type) ที่ได้รับมา เมื่อข้อมูลวันที่ถูกส่งมาในรูปแบบ Object หรือ Timestamp PHPExcel มักจะแปลงมันเป็นค่าตัวเลขภายใน (Integer) ซึ่งเป็นค่าที่ Excel ใช้ในการจัดเก็บวันที่

สาเหตุหลัก: การตีความประเภทข้อมูล (Data Type Interpretation)

เมื่อ PHPExcel ได้รับค่าวันที่ในรูปแบบ PHP `DateTime` Object หรือค่า Timestamp ที่ไม่ได้ถูกจัดรูปแบบเป็น String มาก่อน มันจะมองเห็นว่าเป็นตัวเลขจำนวนเต็ม (Integer) ซึ่งเป็นค่าที่ถูกต้องในทางเทคนิค แต่เมื่อผู้ใช้เปิดไฟล์ใน Microsoft Excel โดยที่ไม่ได้ตั้งค่า Format Cell ให้เป็น Date อย่างชัดเจน ตัวเลขนั้นก็จะปรากฏเป็นตัวเลขดิบๆ เช่น 44445 หรือ 45000 แทนที่จะเป็นวันที่ที่อ่านง่ายอย่าง 2022-01-01

แนวทางแก้ไขระดับสถาปัตยกรรม: การจัดรูปแบบที่แหล่งกำเนิด (Source Formatting)

ในมุมมองของ Senior Architect การแก้ไขปัญหานี้ที่ต้นทาง (Source) คือวิธีที่มีประสิทธิภาพและยั่งยืนที่สุด เราไม่ควรปล่อยให้ PHPExcel มาจัดการการจัดรูปแบบวันที่ที่ซับซ้อนด้วยตัวเอง แต่ควรให้ PostgreSQL ทำหน้าที่จัดรูปแบบข้อมูลให้เป็น String ที่พร้อมใช้งานก่อนส่งออก

การใช้ฟังก์ชัน TO_CHAR ใน PostgreSQL

PostgreSQL มีฟังก์ชันที่ทรงพลังอย่าง TO_CHAR() ซึ่งช่วยให้เราสามารถแปลงค่า Date/Timestamp ให้เป็น String ตามรูปแบบที่เราต้องการได้อย่างแม่นยำ การทำเช่นนี้จะทำให้ข้อมูลที่ถูกดึงออกมาใน PHP เป็นเพียง String ธรรมดา ทำให้ PHPExcel ไม่ต้องตีความผิดพลาดว่าเป็นตัวเลขลำดับ

สมมติว่าเรามีคอลัมน์ created_at ที่เป็นประเภท TIMESTAMP เราควรปรับคำสั่ง SQL ให้ใช้ TO_CHAR() ดังตัวอย่างต่อไปนี้:

SQL

SELECT 1, 2, 3, TO_CHAR(created_at, 'YYYY-MM-DD HH24:MI:SS') AS formatted_date FROM subscriptions;

คำอธิบาย:

  • TO_CHAR(created_at, 'YYYY-MM-DD HH24:MI:SS') คือการบังคับให้ PostgreSQL แปลงค่าวันที่และเวลาให้เป็น String ที่มีรูปแบบ ‘ปี-เดือน-วัน ชั่วโมง:นาที:วินาที’
  • เมื่อ PHP ดึงข้อมูลนี้มา จะได้เป็น String ที่มีรูปแบบที่ถูกต้องทันที ทำให้ PHPExcel เขียนลงไฟล์ Excel ได้อย่างสมบูรณ์

สรุปและข้อแนะนำทางเทคนิค

เพื่อหลีกเลี่ยงปัญหา PHPExcel แสดงตัวเลขเป็นวันที่อย่างถาวร แนวทางที่ดีที่สุดคือการยกระดับการจัดการข้อมูลให้เป็นหลักการ ‘Format at Source’ เสมอ ไม่ว่าจะเป็นการใช้ฟังก์ชัน TO_CHAR() ใน PostgreSQL หรือการใช้ฟังก์ชันการจัดรูปแบบข้อมูลในระดับฐานข้อมูลอื่น ๆ ก่อนที่จะส่งข้อมูลเหล่านั้นผ่าน API หรือการส่งออกไฟล์

การทำเช่นนี้ไม่เพียงแต่แก้ไขปัญหาการแสดงผลเท่านั้น แต่ยังเป็นการออกแบบระบบที่แข็งแกร่ง (Robust Architecture) เพราะข้อมูลที่ส่งออกไปจะเป็น String ที่มีรูปแบบที่กำหนดไว้ล่วงหน้า ทำให้โค้ดส่วน PHP ไม่ต้องกังวลกับการแปลงประเภทข้อมูลที่ซับซ้อนอีกต่อไป