Jasper Report Server

Report , Form PDF เจ้าปัญหา

การเขียนโปรแกรม CRUD นั้นไม่ได้วุ่นวายอะไรเลยสำหรับโปรแกรมเมอร์ทั่วทั้งสากลโลก แต่มันเริ่มมามีปัญหาตรงที่ลูกค้าเพิ่ม Requirement ตาม Field งานที่ตัวเองจะเอาไปใช้ เช่น เอาไปทำโปรแกรมบัญชี บัญชีบ้าบอคอแตกหักเงินโน่นนี่นั่น แล้วมันมีวิธีคิดประหลาดๆ หรือ เอาไปใช้กับการนำเข้าส่งออก ที่เงื่อนไขมันเยอะแยะเหลือเกิน แบบโน้นแบบนี้แบบนั้น และหนึ่งในปัญหาที่น่าปวดหัวอย่างหนึ่งคือ Report, Form PDF

คือไอพวก Report, Form PDF นี้มันจะเป็นความต้องการของลูกค้าที่อยากได้กระดาษออกมา ประหลาดตรงที่อยากลดกระดาษ ลดขั้นตอน แต่ยังอยากได้กระดาษออกจากระบบ ซึ่งผมก็พอใจนะว่าเขาก็อยากได้อะไรที่มันเอาไปเป็นหลักฐานในโลกความเป็นจริง แต่บางทีเขาให้ความสำคัญกับไอพวกเวรนี่มากกว่าการทำงานของระบบว่ามันจะเสถียร ข้อมูลถูกต้อง บางทีอยากได้ Report Form ก่อนโปรแกรมจะมี Flow สมบูรณ์เสียอีก

ลูกค้าอยากได้อะไรก็ต้องได้

ในโลกที่หมุนด้วยเงิน เทคโนโลยีก็หมุนด้วยเงิน โปรแกรมเมอร์ก็ต้องมีชีวิตอยู่ได้ด้วยเงิน ดังนั้นเขาจ่ายเงินก็ต้องทำให้ ในการสร้าง Form หรือ Report ที่เป็น PDF น้ันเป็นเรื่องน่าปวดหัวเพราะมันทำยาก แต่ไม่ถึงขนาดต้องเขียน Lib วาด PDF เองนะครับ จริงๆมันมี Lib ให้เราใช้อยู่

  1. Lib ประเภทให้เราสร้าง PDF ขึ้นมาจากศูนย์เลย

    Lib ประเภทนี้จะให้เราเริ่มสร้าง PDF จากลากเส้น วาดวงกลม วาดสี่เหลี่ยม วาดตัวอักษรที่ตำแหน่งต่างๆ แบบนี้จะโคตร Dynamic เราสามารถเล่นลูกเล่นแปลกๆได้เต็มที่ซึ่งเป็นข้อดีแบบสุดๆ แต่ก็แลกมาด้วยความยากในการสร้าง PDF อันนึงขึ้นมา นึกถึงตอนเริ่มทำที่เราต้อง เขียน Code เขียนเสร็จแล้วก็ Run ว่าได้อย่างที่เราอยากได้ไหม ทำวนไปเรื่อยๆจนกว่าจะเสร็จ

  2. Lib ที่ทำการสร้าง Template Form ขึ้นมาแล้วค่อยเอาค่าไปใส่

    Lib ประเภทนี้จะมีการให้สร้าง Template ขึ้นมา คล้ายๆกับสร้างไฟล์ Word ขึ้นมาแต่เว้นช่องว่างให้ใส่ตัวแปร หรือใส่เงื่อนไขบางอย่างเพื่อให้ได้ค่าออกมา โดย Lib ประเภทนี้มีข้อดีคือมันมีตัว Designer ทำให้เราเห็นตัวอย่างคร่าวๆของ Report หรือ Form ที่เป็น PDF ก่อนได้ อีกทั้งยังมีให้ลากเส้น วาง Layout แต่ถ้าจะพูดจริงๆแล้ว ไอตัว Lib ประเภทนี้มันเกิดมาจากประเภทที่แล้วนั่นแหละ แต่เขาพัฒนาตัว Designer มาครอบให้เราอีกทีทำให้เราทำงานง่าย (แล้วจะแบ่งทำซากอะไร)

หมายเหตุ การแบ่งประเภทของผมนั้นไม่เป็นมาตรฐานแต่แบ่งตาม Lib ที่เคยเจอตอนทำงาน

ซึ่งจากการที่ผู้หลักผู้ใหญ่ในบริษัทที่ผมทำงานได้ทดลองมาหลายๆ Lib และหลายสถานการณ์แล้วพบว่า Lib แบบที่เป็น Template มี Designer ช่วยให้ทำงานนั้นมีข้อดีมากกว่าเพราะตัว Template และ Designer นั้นเราสามารถแบ่งงานไปให้คนอื่นที่ไม่จำเป็นมีความรู้เกี่ยวกับ Lib ตัวนั้นมากสามารถเอางานไปทำได้ วาง Layout วางค่าตัวแปรไว้ได้

หลังจากพร่ำเพ้อมายาวนานหลายบรรทัดก็มาถึงพระเอกของบทความนี้ซึ่งก็คือ Jasper Report นั่นเอง โดยตัว Jasper นั้นรองรับได้ทุก Platform (ก็เป็น Java นี่หว่า Write once bug anywhere) สามารถสร้าง Form , Report PDF ได้ อีกทั้ง Form ยังขึ้นหน้าใหม่ มี Header Footer แบบกำหนดได้ ทำ Summary ทำ Report ซ้อน Report ทำกราฟ และข้อดีที่สุดหอมหวลสำหรับบริษัทเล็กๆที่ไม่ได้มีเงินมากมายคือมันฟรีครับ

*หมายเหตุ ตัว Designer ชื่อ Jasper Studio

งานและปัญหา งานและปัญหา งานและปัญหา …. ที่คนนอกไม่เห็น

โดยปกติตัว Jasper นั้นสามารถทำการสร้าง Report, Form PDF ออกมาได้โดยการใช้ Java ทำการ Render ออกมา ซึ่งถ้าคุณโชคดีพัฒนา Application ที่ต้องการสร้าง PDF ด้วยภาษา JAVA คุณสามารถใช้ Lib ของ Jasper มาใส่ใน Application ของคุณ แล้วทำการสร้าง Report ได้เลย แต่ถ้าคุณโชคไม่ดีใช้ภาษาอื่นพัฒนา คุณอาจต้องไปหา Lib ที่เขียนมา Intregrate กับตัว Java ซึ่งส่วนใหญ่ก็เป็นการใช้ commandline เรียกไฟล์ jar แล้วส่ง parameter เข้าไป ซึ่งการทำแบบนี้ก็เป็นปัญหาเหมือนกันเพราะคุณต้องควบคุมการเรียกใช้งานไฟล์ jar นี้เพราะทุกครั้งที่คุณเรียกใช้ jar ก็ต้องสร้าง process ใหม่ขึ้นมา ถ้ามีคนเรียกใช้หลายๆคนก็กลายเป็นการสร้าง Process จำนวนมหาศาลขึ้นมา ซึ่งเมื่อสร้าง Process ขึ้นมาเยอะๆจะเกิดปรากฏการ Thrashing ซึ่งคือการไม่ต้องทำอะไรนอกจากสลับไปทำงานไปมาระหว่าง Process ไปๆมาๆไม่เสร็จสักตัว

ปัญหาต่อไปคือไอพวก Report PDF เนี่ยมันมีแบบที่ให้สร้างแบบ รายวัน รายเดือน ทุกวันที่ 5 ทุกวันที่ 13 หรือ ทุกวันที่ x แล้วแต่ความต้องการของลูกค้าที่จะพิสดารได้มากแค่ไหน ซึ่งนั่นทำให้โปรแกรมเมอร์ต้องปวดหัวเพราะต้องมาคอย Design ตัว Application ให้สามารถทำงานแบบนั้นได้ อีกทั้งยังมีเรื่องการกำหนดให้มันเริ่มสร้าง Report PDF ตอนกี่โมง เพราะถ้าเราทำให้มันเป็น Reprot แบบออกเมื่อไหร่ก็ได้มันจะส่งผลกระทบกับ Performance ของระบบ ลองนึกภาพการอยากได้ Report รายเดือนแล้วมันมีจำเป็นต้องใช้ข้อมูลในการสร้าง Report เป็น 1 ล้าน Row ซึงมันกระทบต่อ Performance ซึ่งนั่นทำให้โปรแกรมเมอร์อย่างเราต้องมาทำการ Design ว่าจะทำยังไงให้ทำการสร้าง Report แบบ Cron ได้อีก

ยังยังไม่จบ ปัญหามันเยอะเหลือเกิน หากคุณต้องการทำการสร้าง Form, Report , PDF ที่มีจำนวนมากมายมหาศาล คุณคงต้องเปลี่ยนจากการออกแบบ Synchonous เลย มาใช้เป็นแบบ Asynchonous แทน พอมาใช้แบบ Asnychonous ตัว Application ก็ต้องทำตัว Schedule คอยจัด Queue การสร้าง PDF สร้างความยุ่งยากให้กับโปรแกรมเมอร์ที่งานเยอะอยู่แล้วเข้าไปอีก

ยังยังไม่จบ (เรื่องที่เราต้องทำมันมีมากกว่าที่คนนอกมองเห็นเสมอ) ไอพวก Report PDF เนี่ยหลังจากสร้างเสร็จแล้วลูกค้าเขาอยากให้ส่งเข้าเมลล์นั่น เมลล์นี่อีก ซึ่งนั่นทำให้เราทำส่วนนั้นเพิ่มเติมเข้าไปอีก ทำตัวส่งเมลล์ที่สามารถ Config ได้ว่าส่งให้ใคร ทำหน้าจอให้ config ได้อีก คงเป็นเรื่องที่เพิ่มเวลาในการ Dev

ยังยังไม่จบ (ยังจะมีอีกเหรอวะ) ทั้งหมดที่พูดมาคือเวลาที่อยู่ในแผนก Dev แต่อย่าลืมว่าการพัฒนา Application ไม่ได้จบที่แค่แผนก Dev มันต้องส่งต่อไปแผนก QA ที่ต้องทำการ Test อีก ซึ่งกว่าจะได้ทั้งหมดนี้อาจกินเวลาและงบประมาณจำนวนมาก และไปๆมาๆงานที่ไม่ใช่งานหลักอย่าง Report , Form PDF นั้นใช้เวลาทำนานกว่าตัว Flow หลักของโปรแกรมเสียอีก

Jasper server

งาน ปัญหา ด้านบนที่ว่ามานั้นโปรแกรมเมอร์ในสากลโลกได้เจอและปวดหัวกับมันจนมีกลุ่มคนร่วมกันสร้างตัว Jasper server ขึ้นมาเพื่อแก้ปัญหาที่ผมกล่าวมาทั้งหมดข้างบน ซึ่งตัว Jasper server ซึ่งตัวนี้ฟรีด้วยนะครับ (ของฟรียังมีในโลก แต่ต้องอ่าน Manual เอง Support ตัวเอง) แต่แบบเสียเงินก็มีแถม Feature จะดีกว่าแบบฟรีแบบหลายขุมเลยทีเดียว

ชักแม่น้ำจนไม่เป็นเรื่องราว จริงๆอยากจะถามว่าเธอน่ะรักฉันไหม

หลังจากชักแม่น้ำเล่าเรื่องไร้สาระสำหรับชาวโปรแกรมเมอร์มายาวนานแล้ว เรามาเริ่มใช้งานตัว Jasper server เลยดีกว่า

เนื่องจากในป้จจุบันมีเทคโนโลยี Container ซึ่งง่ายในการพัฒนา Application ดังนั้นจึงขอใช้ Docker ในการพัฒนา

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: '3'
services:
mariadb:
image: "bitnami/mariadb:latest"
environment:
ALLOW_EMPTY_PASSWORD : "yes"
MARIADB_USER : "bn_jasperreports"
MARIADB_DATABASE : "bitnami_jasperreports"
volumes:
- /root/jasper_server/maria:/bitnami

jasperreports:
image: bitnami/jasperreports:latest
environment:
JASPERREPORTS_DATABASE_USER : "bn_jasperreports"
JASPERREPORTS_DATABASE_NAME : "bitnami_jasperreports"
ALLOW_EMPTY_PASSWORD : "yes"
depends_on:
- mariadb
ports:
- 4080:8080
volumes:
- /root/jasper_server/jasper:/bitnami
1
2
3
4
5
6
7
8
9
10
11
12
13
*หมายเหตุในตรงส่วน
volumes:
- /root/jasper_server/maria:/bitnami
คือส่วนที่ทำการ map ข้อมูลที่อยู่ใน database ของ container maria มาไว้กับเครื่องจริง เวลาลบ container ไปแล้วข้อมูลจะได้ยังคงอยู่

volumes:
- /root/jasper_server/jasper:/bitnami
คือส่วนที่ทำการ map ข้อมูลที่อยู่ใน app ของ container jasperreports มาไว้กับเครื่องจริง เวลาลบ container ไปแล้วข้อมูลจะได้ยังคงอยู่

ports:
- 4080:8080

อันนี้เป็นส่วนที่ map port ครับ โดยผม map เข้า port เครื่องจริง 4080 เข้ากับ port 8080 เครือ่ง container

จากนั้นสั่ง

1
docker-compose up

ตัว docker-compose จะทำการ container ให้เราตามที่ต้องการ

จากนั้นลองเข้าไปใช้งานโดยเข้าผ่าน Browser เพียงเท่านี้คุณก็มี jasper server ให้ใช้งานแล้ว ผ่าน http://your_ip:4080/jasperserver/ โดยของผมจะเป็น http://192.168.56.101:4080/jasperserver/

ในส่วนนี้ขอตัดจบเพียงเท่านี้ ในตอนหน้าจะทำการสอนใช้งานกับตัว Server

"สิ่งที่ผมเขียนขึ้นเป็นเพียงความรู้และความเข้าใจของบุคคลเพียงบุคคลเดียว ดังนั้นอย่าเพิ่งเชื่อในสิ่งที่ผมเขียนและอธิบาย ลองทำความเข้าใจว่ามันเป็นจริงอย่างนั้นไหมและลองหาแหล่งอ้างอิงอื่นๆว่าเขามีแนวคิดอย่างไร เรื่องการ Design และวิธีการใช้งานไม่มีถูกไม่มีผิดมีแต่เหมาะสมกับงานนั้นไหม"

ref :
https://hub.docker.com/r/bitnami/jasperreports/
https://community.jaspersoft.com/

เพลงเพราะๆของพี่แอนธิติมา :