python - 引导程序不渲染
问题描述
问题分为不同的部分:
- 小序言和分享的尝试
- 重现问题的文件夹结构和代码
- 显示和解释问题
- 问题
前言
我在 Raspbian 上使用 Python 3.8 创建了一个简单的 Flask 1.1.1 应用程序。
我正在尝试使用PdfKit实现 PDF 文件的生成,但我在引导渲染方面遇到了一些问题。
我已经尝试在谷歌上搜索,我发现了两篇文章:
- 首先没有有用的答案。
- 第二个在 github上引用这个 SO 问题,但接受的答案不起作用(我下载了 BS,但没有检查打印媒体样式)。在评论中阅读有人指出这个答案,但与背景颜色有关。
正如 repo README.md 中所说,我已经安装了 wkhtmltopdf 的静态二进制文件:
警告!debian/ubuntu repos 中的版本减少了功能(因为它在没有 wkhtmltopdf QT 补丁的情况下编译),例如添加大纲、页眉、页脚、TOC 等。要使用此选项,您应该从 wkhtmltopdf 站点安装静态二进制文件,或者您可以使用此脚本.
有一个选项被称为--user-style-sheet
用作解决方法:
警告 这是 wkhtmltopdf 中此错误的解决方法。您应该先尝试 --user-style-sheet 选项。
问题是我不知道哪个错误,因为参考页面处于脱机状态。
代码和文件夹
项目文件夹结构如下:
WebServer/
├── Rembe
│ ├── __init__.py
│ ├── static
│ │ ├── content
│ │ │ ├── bootstrap.css
│ │ │ ├── bootstrap.min.css
│ │ ├── fonts
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ ├── glyphicons-halflings-regular.woff2
│ │ ├── scripts
│ │ │ ├── bootstrap.js
│ │ │ ├── bootstrap.min.js
│ ├── templates
│ │ ├── test_page.html
│ │ └── test_pdf_report.html
│ └── views.py
└── runserver.py
重现问题的代码(避免引导程序的东西,你可以从官方网站下载它,我有它的代码):
初始化.py
from flask import Flask
app = Flask(__name__)
db = SQLAlchemy(app)
import Rembe.views
运行服务器.py
from os import environ, path, walk
from Rembe import app
if __name__ == '__main__':
# Folder to monitor and check if the server needs to be reloaded
extra_dirs = ['/home/pi/WebServer/', '/home/pi/WebServer/Rembe/', '/home/pi/WebServer/Rembe/templates/']
extra_files = extra_dirs[:]
for extra_dir in extra_dirs:
for dirname, dirs, files in walk(extra_dir):
for filename in files:
filename = path.join(dirname, filename)
if path.isfile(filename):
extra_files.append(filename)
app.run('0.0.0.0', 80, False, extra_files=extra_files)
视图.py
from flask import render_template, url_for, send_from_directory
from Rembe import app
import pdfkit
@app.route('/')
@app.route('/test_page')
def test_page():
return render_template(
'test_page.html', title='test'
)
@app.route('/test_view', methods=['GET', 'POST'])
def test_view():
return render_template('test_pdf_report.html', my_custom_value='TEST PARAMETER')
@app.route('/test_download', methods=['GET', 'POST'])
def test_download():
filename = 'report.pdf'
string_page = render_template('test_pdf_report.html', my_custom_value='TEST PARAMETER')
options = {'enable-local-file-access': ""}
pdfkit.from_string(string_page, f'/tmp/{filename}')
return send_from_directory(directory='/tmp/', filename=filename)
test_page.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }} - TEST</title>
<link rel="stylesheet" type="text/css" href="/static/content/bootstrap.min.css" />
</head>
<body>
<div class="container body-content">
<a href="{{url_for('test_view')}}">test</a>
<label> | </label>
<a href="{{url_for('test_download')}}">Download</a>
</div>
</body>
</html>
test_pdf_report.html
<html>
<head>
<link href="{{ url_for('static', filename='content/bootstrap.min.css', _external=True) }}" rel="stylesheet">
</head>
<body>
<div class="row">
<div class="col-sm-12">
<h2 style="text-align: center">REPORT TITLE - {{my_custom_value}}</h2>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<p>ROW 1 - COLUMN 1</p>
</div>
<div class="col-sm-6">
<p>ROW 1 - COLUMN 2</p>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<p>ROW 2 - COLUMN 1</p>
</div>
<div class="col-sm-6">
<p>ROW 2 - COLUMN 2</p>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<p>ROW 3 - COLUMN 1</p>
</div>
<div class="col-sm-6">
<p>ROW 3 - COLUMN 2</p>
</div>
</div>
</body>
</html>
问题
该项目生成一个带有两个可点击文本的白页:测试和下载
单击文本测试呈现的页面是否正确并且引导程序正常工作,行/列在正确的位置。
单击文本下载pdf 打开,但未呈现引导程序,并且行/列与页面左侧对齐。
服务器的输出告诉我一切都很好:
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
我还尝试使用wkhtmltopdf
库直接生成 PDF,如下所示:
wkhtmltopdf --enable-local-file-access test_pdf_report.html /tmp/mypdf.pdf
该命令在不渲染引导程序的情况下执行并生成 PDF,控制台输出为:
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
问题
我有两个问题:
PdfKit 模块与引导程序兼容?
有一种方法可以解决我的问题并下载呈现为 HTML 页面且行/列格式正确的 PDF 文件?
感谢您的时间。
解决方案
我今天遇到了同样的问题。此外,我观察到它确实加载并使用了一些引导程序。像你一样,我所有的专栏都是全宽的效果图。我相信我发现问题实际上出在 wkhtmltopdf 中。媒体查询似乎有问题。这并不能解决他们的问题,但它解释了正在发生的事情。有些人已经找到了针对他们特定情况的解决方法,但我目前还没有找到适合我的方法。
使用 wkhtmltopdf 将 Twitter 引导页面转换为 PDF:跨度问题
https://github.com/barryvdh/laravel-snappy/issues/258
更新
我能够降级到 Bootstrap 3 并更新我的标记以解决类名的这种变化,并获得了更好的结果。我相信问题是在 Bootstrap 4 中添加了 Flexbox,这在 wkhtmltopdf 中不起作用
推荐阅读
- arrays - grep 哈希值是数组的数组
- python - 了解 Axes.transData 如何依赖 xlim 和 ylim 更新
- javascript - 如何更改视频默认选项
- mongodb - 如何检测 mongodb 领域触发器中替换操作的更改字段?
- c# - Blazor 将表绑定到列表
- java - Android Java在上传前压缩视频大小
- url - 将域路径重定向到与主域不同的站点
- javascript - Vue.js 多选组件错误:属性或方法“isOpen”未在实例上定义,但在渲染期间引用
- javascript - 带参数的 Typeorm 监听器
- c# - ASP.NET MVC C# - 显示类属性名称而不是 JSON 中的属性名称