I am trying to create pdf from html page using pdfkit
inside Flask
application, but I have troubles to load the static files (stylesheets) when using pdfkit
.
I've tried to come up with minimal example. I've got this file structure
App
|_ static
| |- style.css
|_ templates
| |- base.html
|_ pdfs
| |- file.pdf
|_ application.py
Inside application.py
:
import flask
import pdfkit
app = flask.Flask(__name__)
@app.route('/')
def index():
page = flask.render_template('base.html')
pdfkit.from_string(page, 'pdfs/file.pdf')
return page
@app.route('/download', methods=['POST'])
def download():
if flask.request.method == 'POST':
flask.send_from_directory(
directory='pdfs', filename='file.pdf', as_attachment=True)
else:
flask.redirect(flaks.url_for('index'))
if __name__ == '__main__':
app.run()
Stylesheet just adds red background to the td elements:
td {
background-color: red;
}
And finally the base.html
:
<!DOCTYPE html>
<html>
<head>
<title>Test App</title>
<link href={{ url_for('static', filename='style.css') }} rel='stylesheet'>
</head>
<body>
<div id='to_pdf'>
<table>
<tr>
<th>Firstname</th>
</tr>
<tr>
<td>Jill</td>
</tr>
<tr>
<td>Eve</td>
</tr>
</table>
<form action='/download' method='POST'>
<button type="submit" value="Print" />PRINT</form>
</form>
</div>
</body>
</html>
Sorry for the loads of code, but it is actually pretty basic. All I want is to have button, which once clicked downloads a pdf file (this pdf is html file converted to pdf.
It sort of works, but the console output is the following:
Loading pages (1/6)
Warning: Failed to load file:///static/style.css (ignore)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
The problem
pdfkit
, which basically invokes wkhtmltopdf
cannot find the stylesheet files inside static
folder. The application, where I have this problem is more robust, uses boostrap etc. and having the pdf output badly formatted is very undesirable..
Assuming your app has config.py file you can add this config value.
ABS_PATH_STATIC_FOLDER = "var/www/.." #here is an absolute path to static dir
Then specify css file by:
css = os.path.join(app.config['ABS_PATH_STATIC_FOLDER'], 'pdfstyle.css')
This will work if the css file is placed in static folder or any other folder
Then pass on css to pdfkit fromstring function
pdfkit.from_string(page, 'pdfs/file.pdf', css=css)
Single CSS file
css = 'example.css'
pdfkit.from_file('file.html', css=css)
Multiple CSS files
css = ['example.css', 'example2.css']
pdfkit.from_file('file.html', css=css)
In your case try this:
css = "static/style.css"
page = flask.render_template('base.html')
pdfkit.from_string(page, 'pdfs/file.pdf', css=css)
return page
Your code results in a link that wkhtmltopdf tries to open as a regular file:
{{ url_for('static', filename='style.css') }}
becomes
/static/style.css
which wkhtmltopdf will look for at
file://static/style.css
Instead, add the _external=True
flag to point it towards the file on the server:
{{ url_for('static', filename='style.css', _external=True) }}
results in (something like)
http://localhost:5000/static/style.css
来源:https://stackoverflow.com/questions/40914546/how-to-link-stylesheet-files-to-pdfkit-in-flask-application