เพื่อทำ Java application เพื่อที่จะออกรายงานเป็นไฟล์ pdf
พบว่าการสร้าง PDF ตรงๆค่อนข้างจะยุ่งยากเหมือนกัน library ที่จะเอามาใช้ก็ซับซ้อนอยู่ อย่าง jasper report แต่คิดว่าถ้าใช้ได้หน้าตาน่าจะออกมาดี แต่กว่าจะใช้ได้น่าจะนาน
เพื่อที่จะให้ใช้งานได้เร็วหน่อย แล้วเราก็เคยสร้าง report เป็นไฟล์ docx อยู่แล้ว เลยคิดว่าถ้าแค่ convert เป็น pdf ได้ก็น่าจะจบ แต่พอลองเช็ค ก็ดูจะมีรายละเอียดให้เราเลือกหลายอันเหมือนกัน แถมบาง library ก็ดูจะทำงานไม่ได้ ต้อง set อะไรหลายอย่าง
สรุบ ตอนนี้ได้ทดลองใช้งาน เพื่อทำการ convert ไฟล์ docx เป็น pdf แล้วเจอ Library ที่ทำงานได้ – ง่ายๆ – อยู่ 2 ตัว + 1 วิธี
- documents4j
- Jodconverter
- Libreoffice – headless
Documents4j
ทำงานค่อนข้างไว เท่าที่ลอง แต่ใช้งานได้แค่เครื่องที่มี MS Office
ตอนแรก Gemini บอกว่าใช้งานกับ Libreoffice ได้ แถมบอก ชื่อ library มาเสร็จสรรพ แต่สรุปคือมั่วชื่อมาให้เลย ตอนจบก็สรุปได้ว่าทำงานได้แค่กับ MS Office เท่านั้น
หลักๆคือ ตัว documents4j local จะเป็นตัวจัดการ
ส่วน documents4j transformer msoffice word จะเป็น bridge
ถ้าเราจะ convert file อื่น เช่น xlsx หรือ pptx เราก็ไปดึง bridge นั้นๆมาใช้ได้
implementation 'com.documents4j:documents4j-local:1.1.13' implementation 'com.documents4j:documents4j-transformer-msoffice-word:1.1.13'
//working fine on computer with MS Office only
IConverter converter = LocalConverter.builder().build();
converter.convert(docxFile).as(DocumentType.DOCX)
.to(pdfFile).as(DocumentType.PDF)
.execute();
converter.shutDown();
System.out.println("แปลง PDF สำเร็จแล้ว!");
Jodconverter
ทำงานได้กับเครื่องที่มี Libreoffice ติดตั้งอยู่ โดยตัวมันจะไปค้นหาเองจาก program file (ถ้าบน linux ไม่รู้ว่าอยู่ตรงไหน) ทำงานกับ MS Office ได้หรือเปล่า ยังไม่แน่ใจ แต่ยังงัย Libreoffice ก็ฟรีอยู่แล้ว ไม่น่าจะมีปัญหา
ถ้าเข้าใจไม่ผิด เราน่าจะกำหนด path ของ Libreoffice ให้ Jodconverter ได้อยู่ เผื่อจะใช้แบบ portable
ข้อเสียคือตอนสั่ง start OfficeManager ดูมันจะ Load ค่อนข้างนาน ถ้านานๆจะ convert ซักไฟล์จะรู้สึกว่าทำงานช้า
แต่ถ้า start OfficeManager ค้างไว้ ไฟล์ต่อไป น่าจะไวขึ้น
implementation 'org.jodconverter:jodconverter-local:4.4.11'
//Working fine for BATCH converter
//Because it take long time to start office manager
//waiting around 30second before start convertion
LocalOfficeManager officeManager = LocalOfficeManager.install();
try {
officeManager.start();
// 2. สั่งแปลงไฟล์
JodConverter.convert(docxFile)
.to(pdfFile)
.execute();
System.out.println("แปลง PDF สำเร็จแล้วด้วย JODConverter!");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 3. ปิด Office Manager เมื่อใช้งานเสร็จ
try {
officeManager.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
Libreoffice CLI
อันนี้คือการที่เราใช้ external program ก็คือ Libreoffice (แต่ถ้าใช้บน Windows ไฟล์ที่เราจะเรียกใช้ จะเป็น soffice.exe)
ProcessBuilder processBuilder = new ProcessBuilder(
"c:\\program files\\libreoffice\\program\\soffice.exe",
"--headless",
"--convert-to", "pdf",
inputPath,
"--outdir", outputDirPath
);
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("output pdf with LibreOffice complete!");
} else {
System.err.println("output pdf fail with Exit Code: " + exitCode);
}
command line ที่ใช้ก็คือ
“C:\program files\Libreoffice\program\soffice.exe” –headless –convert-to pdf file.docx
หรือ
“C:\program files\Libreoffice\program\soffice.exe” –headless –convert-to pdf file.docx –outdir “C:\tmp”
กำหนดได้แค่ output folder
ยังไม่แน่ใจว่ากำหนดชื่อไฟล์ตรงๆได้มั้ย
เท่าที่ใช้งานบน local ก็ค่อนข้างไว
แต่เอาไปใช้จริง บางครั้งก็ค่อนข้างนาน เหมือนเครื่องมันทำการ load command นานไป
บางจังหวะนานราวๆ 1 – 2 นาที
แต่ตอนที่ทำงาน local นี่คือเสร็จทันที
ก็ไม่รู้ว่าทำไม
แต่โดยรวมๆ 3 วิธีนี้ก็โอเคแล้ว