Wicket で、Python Pdfkit実行してPDFダウンロードさせる方法を考えました。
このメリットは、
・作成するPDFが、PdfkitがHTMLからPDFへの変換であることから
WicketでブラウザにWeb Page 表示してPDF作成イメージを確認できること。
・HTMLでPDFのテンプレートを構成できることです。
実行する Pytyon スクリプトは標準入力で、URL、ページ種別(A4 等)、縦横の向きを
認識して、標準出力でPDFを出力します。
呼出し元のJava 側では、プロセス起動で Pythonスクリプト実行して、
標準出力ストリーム → Pytyon スクリプト標準入力
標準入力ストリーム ← Pytyon スクリプト標準出力
になるようにします。
これは、yipuran-core にある ScriptExecutor.runStream を使用します。
↓↓↓
https://github.com/yipuran/yipuran-core/wiki/Script_exec
URL,ページ種別, 縦横の向き(Portrait or Landscape)を受信してPDFを標準出力するスクリプト
WebPageToPdf.py
# -*- coding: UTF-8 -*- import sys import pdfkit def pageToPdf(url, pagesize='A4', orientation='Portrait'): options = { 'page-size': pagesize, 'orientation': orientation, 'margin-top': '0.4in', 'margin-right': '0.4in', 'margin-bottom': '0.4in', 'margin-left': '0.4in', 'encoding': "UTF-8", 'no-outline': None } pdf = pdfkit.from_url("%s" % url, False, options=options) sys.stdout.buffer.write(pdf) inlist = [] try: while True: inp = input('') if inp == '': break inlist.append(inp) except EOFError: sys.stdout.buffer.write("ERROR") pass if inlist.__len__()==2: pageToPdf(inlist[0], inlist[1]) elif inlist.__len__()==3: pageToPdf(inlist[0], inlist[1], inlist[2]) else: pageToPdf(inlist[0])
WicketPage AJAX Dowanload Behavior として、記述するコード例
この中の AJAXDownload は、以下を参照
https://github.com/yipuran/yipuran-wicketcustom/wiki
ボタンクリックで実行する SerialThrowableConsumer は、以下を参照
https://github.com/yipuran/yipuran-wicketcustom/blob/master/src/main/java/org/yipuran/wicketcustom/function/SerialThrowableConsumer.javayipuran-wicketcustom/SerialThrowableConsumer.java at master · yipuran/yipuran-wicketcustom · GitHub
final AJAXDownload sampleDownload = AJAXDownload.of(out->{ // Python スクリプト String script = "python " + dirctorypath + "/WebPageToPdf.py"; // URL セット list.add( urlstring ); list.add("\n"); list.add("A4"); list.add("\n"); list.add("Portrait"); list.add("\n"); list.add("\n"); int sts = ScriptExecutor.runStream(()->script, ()->list, inst->{ try{ inst.transferTo(out); out.flush(); out.close(); }catch(Exception ex){ throw new RuntimeException(ex); } }, (e, x)->{ logger.error(x.getMessage(), x); }); }, ()->"application/pdf", ()->"test.pdf"); queue(new Button("pdfdownload").add(AjaxFormSubmitBehavior.onSubmit("click" , SerialThrowableConsumer.of(t->{ // callback!! sampleDownload.callBackDownload(t); }, (u, x)->{ logger.error(x.getMessage(), x); }))).add(sampleDownload) );
Python スクリプトが、PDF変換前のURL、ページ種別、向きだけを受信するように
書いていますが、動的に変化するPDF作成なら、
Java からのPython スクリプト実行の入力リストにパラメータを追加して、
Python スクリプトで、PDF変換前のURL受信したパラメータをURLパラメータに
追加すれば、動的なWebPage→ 動的に変化するPDF作成
になるはずです。
PDFの改ページを自由に配置するには、
PDF に変換される WebPage のHTML で
<div style="page-break-after:always;"></div>
を差し込みます。
つまり、CSSで、
page-break-after : always;
を効かせてあげれば良いわけです。
pdfkit が内部で、wkhtmltopdf を実行するからです。
wkhtmltopdf もインストールして置く必要あります。