简体   繁体   English

如何解决 python pdfkit 中的“wkhtmltopdf 报告错误:由于网络错误退出代码 1:ProtocolUnknownError”

[英]How to solve "wkhtmltopdf reported an error: Exit with code 1 due to network error: ProtocolUnknownError" in python pdfkit

I'm using Django.我正在使用 Django。 This is code is in views.py.这是代码在views.py 中。

def download_as_pdf_view(request, doc_type, pk):
    import pdfkit
    file_name = 'invoice.pdf'
    pdf_path = os.path.join(settings.BASE_DIR, 'static', 'pdf', file_name)

    template = get_template("paypal/card_invoice_detail.html")
    _html = template.render({})
    pdfkit.from_string(_html, pdf_path)

    return FileResponse(open(pdf_path, 'rb'), filename=file_name, content_type='application/pdf')

Traceback is below.追溯如下。


[2022-09-05 00:56:35,785] ERROR [django.request.log_response:224] Internal Server Error: /paypal/download_pdf/card_invoice/MTE0Nm1vamlva29zaGkz/
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/project/app/paypal/views.py", line 473, in download_as_pdf_view
    pdfkit.from_string(str(_html), pdf_path)
  File "/usr/local/lib/python3.8/site-packages/pdfkit/api.py", line 75, in from_string
    return r.to_pdf(output_path)
  File "/usr/local/lib/python3.8/site-packages/pdfkit/pdfkit.py", line 201, in to_pdf
    self.handle_error(exit_code, stderr)
  File "/usr/local/lib/python3.8/site-packages/pdfkit/pdfkit.py", line 155, in handle_error
    raise IOError('wkhtmltopdf reported an error:\n' + stderr)
OSError: wkhtmltopdf reported an error:
Exit with code 1 due to network error: ProtocolUnknownError

[2022-09-05 00:56:35,797] ERROR [django.server.log_message:161] "GET /paypal/download_pdf/card_invoice/MTE0Nm1vamlva29zaGkz/ HTTP/1.1" 500 107486

This is work file.这是工作文件。

pdfkit.from_url('https://google.com', 'google.pdf')

However pdfkit.from_string and pdfkit.from_file return "ProtocolUnknownError"但是pdfkit.from_stringpdfkit.from_file返回“ProtocolUnknownError”

Please help me!请帮我!

Update更新

I tyied this code.我绑定了这段代码。

    _html = '''<html><body><h1>Hello world</h1></body></html>'''
    pdfkit.from_string(_html), pdf_path)

It worked fine.它工作得很好。 I saved above html as sample.html.我将上面的 html 保存为 sample.html。 Then run this code然后运行这段代码

  • I added this parameter options={"enable-local-file-access": ""}我添加了这个参数options={"enable-local-file-access": ""}
    _html = render_to_string('path/to/sample.html')
    pdfkit.from_string(str(_html), pdf_path, options={"enable-local-file-access": ""})

It worked fine!效果很好! And the "ProtocolUnknownError" error is gone thanks to options={"enable-local-file-access": ""} .由于options={"enable-local-file-access": ""} ,“ProtocolUnknownError”错误消失了。

So, I changed the HTML file path to the one I really want to use.因此,我将 HTML 文件路径更改为我真正想要使用的路径。

    _html = render_to_string('path/to/invoice.html')
    pdfkit.from_string(_html, pdf_path, options={"enable-local-file-access": ""})
    return FileResponse(open(pdf_path, 'rb'), filename=file_name, content_type='application/pdf')

It does not finish convert pdf.它没有完成转换 pdf。 When I run the code line by line.当我逐行运行代码时。

stdout, stderr = result.communicate(input=input) does not return. stdout, stderr = result.communicate(input=input)不返回。

It was processing long time.它处理了很长时间。

I solved this problem.我解决了这个问题。 Theare are 3 step to pass this problems.有 3 个步骤可以解决这个问题。

  1. You need to set options {"enable-local-file-access": ""} .您需要设置选项{"enable-local-file-access": ""} pdfkit.from_string(_html, pdf_path, options={"enable-local-file-access": ""})

  2. pdfkit.from_string() can't load css from URL. pdfkit.from_string()无法从 URL 加载 css。 It's something like this.是这样的。 <link rel="stylesheet" href="https://path/to/style.css"> css path should be absolute path or write style in same file. <link rel="stylesheet" href="https://path/to/style.css"> css 路径应为绝对路径或在同一文件中写入style

  3. If css file load another file.如果 css 文件加载另一个文件。 ex: font file.例如:字体文件。 It will be ContentNotFoundError .它将是ContentNotFoundError

My solution我的解决方案

I used simple css file like this.我使用了这样的简单 css 文件。

body {
    font-size: 18px;
    padding: 55px;
}

h1 {
    font-size: 38px;
}

h2 {
    font-size: 28px;
}

h3 {
    font-size: 24px;
}

h4 {
    font-size: 20px;
}

table, th, td {
    margin: auto;
    text-align: center;
    border: 1px solid;
}

table {
    width: 80%;
}

.text-right {
    text-align: right;
}


.text-left {
    text-align: left;
}

.text-center {
    text-align: center;
}

This code insert last css file as style in same html.此代码将最后一个 css 文件插入为相同 html 中的样式。

import os

import pdfkit
from django.http import FileResponse
from django.template.loader import render_to_string

from paypal.models import Invoice
from website import settings


def download_as_pdf_view(request, pk):
    # create base invoice html from template file.
    invoice = Invoice.objects.get(pk=pk)
    context = {
        # please set your contexts as dict.
    }
    _html = render_to_string('paypal/card_invoice_detail.html', context)
     # remove header
    _html = _html[_html.find('<body>'):]  

    # create new header
    new_header = '''<!DOCTYPE html>
    <html lang="ja">
    <head>
    <meta charset="utf-8"/>
    </head>
    <style>
'''
    # add style from css file. please change to your css file path.
    css_path = os.path.join(settings.BASE_DIR, 'paypal', 'static', 'paypal', 'css', 'invoice.css')
    with open(css_path, 'r') as f:
        new_header += f.read()
    new_header += '\n</style>'
    print(new_header)

    # add head to html
    _html = new_header + _html[_html.find('<body>'):]
    with open('paypal/sample.html', 'w') as f: f.write(_html)  # for debug

    # convert html to pdf
    file_name = 'invoice.pdf'
    pdf_path = os.path.join(settings.BASE_DIR, 'static', 'pdf', file_name)
    pdfkit.from_string(_html, pdf_path, options={"enable-local-file-access": ""})
    return FileResponse(open(pdf_path, 'rb'), filename=file_name, content_type='application/pdf')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 pdfkit 错误:由于网络错误,退出代码 1:ProtocolUnknownError - pdfkit error: Exit with code 1 due to network error: ProtocolUnknownError wkhtmltopdf - 由于网络错误而退出代码 1:ContentNotFoundError - wkhtmltopdf - Exit with code 1 due to network error: ContentNotFoundError 带有django的pdfkit由于网络错误而给出错误退出,代码为1:ContentOperationNotPermittedError - pdfkit with django gives error Exit with code 1 due to network error: ContentOperationNotPermittedError Pdfkit / wkhtmltopdf-OSError:[Errno 8] Exec格式错误 - Pdfkit/wkhtmltopdf - OSError: [Errno 8] Exec format error 为什么通过python-pdfkit调用时出现wkhtmltopdf IO错误? - Why am I getting wkhtmltopdf IO Error when invoking via python-pdfkit? 无法使用 python PDFKIT 错误创建 pdf:“找不到 wkhtmltopdf 可执行文件:” - Can't create pdf using python PDFKIT Error : " No wkhtmltopdf executable found:" python代码错误,不确定如何解决? - Error in python code, not sure how to solve it? 如何解决多态和继承的python代码中的错误 - How to solve error in this python code of polymorphism and inheritance 如何解决我的python代码中的导入错误? - how to solve import error in my python code? 如何解决由于pandas中的chunksize而导致的错误? - how to solve error due to chunksize in pandas?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM