私は Django を使用しています。このコードは 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')
トレースバックは以下の通りです。
[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
これは作業ファイルです。
pdfkit.from_url('https://google.com', 'google.pdf')
ただしpdfkit.from_string
、pdfkit.from_file
「ProtocolUnknownError」を返します
私を助けてください!
アップデート
このコードを結びました。
_html = '''<html><body><h1>Hello world</h1></body></html>'''
pdfkit.from_string(_html), pdf_path)
うまくいきました。上記のhtmlをsample.htmlとして保存しました。次にこのコードを実行します。
- このパラメータを追加しました
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": ""})
うまくいきました! のおかげで「ProtocolUnknownError」エラーはなくなりましたoptions={"enable-local-file-access": ""}
。
そこで、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')
コードを1行ずつ実行しても、PDF 変換が完了しません。
stdout, stderr = result.communicate(input=input)
戻りません。
処理に長い時間がかかりました。
ベストアンサー1
この問題を解きました。この問題をクリアするには 3 つのステップがあります。
オプションを設定する必要があります
{"enable-local-file-access": ""}
。pdfkit.from_string(_html, pdf_path, options={"enable-local-file-access": ""})
pdfkit.from_string()
URL から CSS を読み込むことができません。次のようになります。CSS<link rel="stylesheet" href="https://path/to/style.css">
パスは絶対パスにするか、style
同じファイルに書き込む必要があります。css ファイルが別のファイルを読み込む場合。例: フォント ファイル。次のようになります
ContentNotFoundError
。
私の解決策
私は次のようなシンプルな 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;
}
このコードは、最後の 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 PDF from HTML template file with context.
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')