🙄

PDFKITがwkhtmltopdfを見つけられないことがある

2022/10/12に公開約1,800字

ここからの移植です。

Pythonのライブラリ、pdfkitを使っていると、wkhtmltopdfがインストール済みの環境にもかかわらず、「No wkhtmltopdf executable found」というエラーでPDF作成に失敗することがあります。

答えはPDFKITの構成ファイルにあります。

pdfkit\configuration.py
        if not self.wkhtmltopdf:
            if sys.platform == 'win32':
                self.wkhtmltopdf = subprocess.Popen(
                    ['where', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].strip()
            else:
                self.wkhtmltopdf = subprocess.Popen(
                    ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].strip()

Windows環境では、whereコマンドを使ってwkhtmltopdfを探しています。このため、wkhtmltopdfにパスが通っていない環境では、処理に失敗します(というか、whereコマンドなんてあったんだ・・・)。
そして、2022/10/12現在最新のバージョン0.12.6では、wkhtmltopdf.exeにパスを通してくれません(ナンテコッタイ)
そのため、以下の二通りの方法で解決が可能です。

  • wkhtmltopdf.exeにパスを通す
  • pdfkitのConfigureオブジェクトを作り、そこでwkhtmltopdf.exeのパスを指定する

自分で使う環境ならともかく、他者に使ってもらうことを考えると、パスを自力で探したほうが早いという気もします(どうせパスの情報はレジストリにも書かれていますし)

というわけで、wkhtmltopdf.exeのパスを検索して、設定してみた

wkhtmltopdfのパスは、インストール済みであれば、HKEY_LOCAL_MACHINE\SOFTWARE\wkhtmltopdf\PdfPathに格納されています。

program.py
    import winreg
    try:
      with winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\wkhtmltopdf', 
        access=winreg.KEY_READ | winreg.KEY_WOW64_64KEY) as k:
        data, regtype = winreg.QueryValueEx(k, "PdfPath")
        configure = pdfkit.configuration(wkhtmltopdf=data)
        regtype = regtype

        pdfkit.from_file(html, "output.pdf", configuration=configure)    
    except FileNotFoundError:
      pass

winreg.KEY_WOW64_64KEYは、Pythonインタプリタ自体のアーキテクチャにかかわらず、64bitのレジストリビューのデータを確認するというフラグです。64bit版のPythonを使用している場合は省略可能です(64bit版のPythonを使っているときに指定しても害はないので、そのままにしてあります)

Discussion

ログインするとコメントできます