2013年8月2日

Java 使用 Acrobat Reader 列印 PDF

以 Java 要列印 PDF document 基本上來說並不是什麼大問題,無論是用 AWT PrintJob 或 print service 的 DocPrintJob。

但對於字體/字型的處理,除非買授權的商用套件或統一規範產生 PDF 時的方法,不然想要以 opensource package(ex. Apache PDFBox) 來處理 PDF 中各種造字字體/字型的問題,可以說是一件殺死腦細胞的工作。(雖然我已經幹了)

除此之外,最常見的解決方法是:利用 Windows 平台,以 Acrobat Reader 來印製;好處是,字型檔的處理與前端使用者的 PC 無異。 而程式通常使用 Runtime / Process 或 ProcessBuilder class 來 invoke Acrobat Reader。

不過,依過去發生的案例發現,大體上會發生幾個狀況:
  • 要不要處理 DOS 視窗輸出的訊息
  • 如何取得 return code
  • Acrobat Reader 因發生狀況而未結束 process

解決的策略是:[避免] 發生上述狀況, 取而代之的是去 [控制] 這些狀況
方法是 Java code ----> bat/cmd file ----> Acrobat Reader ;而在 bat/cmd 中加一些基本的處理:
  • 檢查 pdf file 是否存在
  • 檢查 printer (name) 是否存在

例如:
SET PDFFILE=%~1
...
IF NOT EXIST "%PDFFILE%" GOTO PDFNOTFOUND
...
GOTO END

:PDFNOTFOUND
echo file(%PDFFILE%) not found

:END
而檢查 printer 的方法:
rundll32 printui.dll PrintUIEntry /q /Xg /n"{printer name}"

結合上述判斷後再執行 Acrobat Reader 來列印:
"C:\Program Files\Adobe\Reader 10.0\Reader\AcroRd32.exe" /h /o /s /t /n "%PDFFILE%" "{printer name}"

但機車的事發生了,依 AcriRd32.exe 說明而加的參數,理當在執行它之後會結束 bat/cmd ,而回到 Java code 繼續處理;但事實並非如此,無論使用了什麼 cmd.exe 或 start 指令相關參數的功能。

目前唯一測試 OK 的方式是:

  • 在 Java code 運作之前,先啟用 Acrobat Reader 並把它縮小視窗擱在旁邊。

我只能想像的是 Acrobat Reader 是 Windows  program,要控制它除非拿到它的 handle,否則很難與 DOS 視窗的 process 結合,而該 process 只是負責 launch Acrobat Reader 而已。 XD

ps.
(1) Rundll32 printui.dll PrintUIEntry 適用平台 : http://technet.microsoft.com/zh-tw/library/ee624057(v=ws.10).aspx
(2) Apache PDFBox 近年來更新開始頻繁了,好事!

沒有留言: