Java→Python Pdfkit実行→PDF受け取る

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 もインストールして置く必要あります。