Ram*_*iro 1 pdf-generation pdfkit flask python-3.x pythonanywhere
我的网络应用程序是用 Flask 编写的。我想将 jinja 模板(HTML 格式)转换为 PDF 文件。我使用 pythonanywhere.com 作为我的应用程序的主机。
我已经使用 Flask 使用在开发环境 fedora31 上运行的 pdfkit、wkhtmltopdf、jinja2 成功生成了动态 PDF。当尝试在 pythonanywhere 环境中安装 pdfkit 时,我收到消息权限被拒绝。
对于 weasyprint,还需要安装库;这也是 pythonanywhere.com 的限制。
xhtml2pdf 的情况也是如此,无法在 pythonanywhere.com 安装
总结:pdfkit、weasyprint、xhtml2pdf 目前不是可行的替代方案,但需要在 pythonanywhere.com 安装这些库
pythonanywhere.com 安装新库有此限制。
我的问题是:
知道我的 Flask 应用程序需要 pythonanywhere.com 提供的环境才能运行,我必须采取哪些可行的替代方案将 jinja 模板转换为 PDF 格式?
任何解决这种情况的指导将不胜感激。谢谢。
pythonanywhere bash 控制台中发送的消息特别指出:“考虑使用 \'--user\' 选项或检查权限”
\n因此安装 pdfkit 库的命令是:
\npip3安装--用户pdfkit
\n\n因此,要在 pythonanywhere 环境中安装 wkhtmltopdf 库,命令类似:
\npip3安装--用户wkhtmltopdf
\n\n有趣的是,我发现网站上\n https://pypi.org/project/Flask-WkHTMLtoPDF/ Flask-WkHTMLtoPDF 0.1.0 库将依赖 JavaScript 的 Flask 模板转换为 PDF。
\n使用命令 pip3 install --user 命令安装pdfkit、wkhtmltopdf和WkHTMLtoPDF库后。
\n这些库位于/home/todonatacion/.local/lib/python3.7/site-packages目录中。在 Flask 中执行应用程序时,出现以下错误消息: 2020-07-08 07:17:54,963: ModuleNotFoundError: No module named \'pdfkit\' 2020-07-08 07:17:54,964: File "/var /www/todonatacion_pythonanywhere_com_wsgi.py”,第 16 行,位于
\n\n\n这些库安装在我的网站/home/todonatacion/.local/lib/python3.7/site-packages的本地目录中
\npython 中的指令:import pdfkit找不到库在哪里。显然,有必要在导入语句中包含正确的路径名,应用程序才能找到该库。
\n由于 import pdfkit 语句无法找到库的位置,问题是:如何告诉应用程序在哪里可以找到 pdfkit 库?任何帮助,将不胜感激。谢谢。
\n我的 Flask 应用程序在 pythonanywhere.com 中使用的版本是 Python 3.8,如以下屏幕截图所示:
\n\n我登录到 pythonanywhere.com 提供的 bash 控制台,仔细检查分配给我的帐户的环境中可用的 python 版本。我执行的检查是在运行以下命令来调用 python 解释器时检查 python 的确切版本:python3.8、python3.7、python3.6、python3.5 和 python2.7
\n\n我发现当输入python3.8命令时python解释器的版本是3.8.0
\n当输入python3.7命令时,python解释器的版本是3.7.5
\n对于python3.6命令,版本是3.6.9;对于 python3.5,版本是 3.5.9,对于 python2.7 命令,版本是 2.7.12
\n这个分析的有趣之处让我想知道。如果我使用 python3 命令调用 python 解释器会发生什么?
\n从 pythonanywhere bash 控制台运行python3命令确认 python 解释器的版本为 3.7.5
\n\n这证实了如果我想调用 python 3.8 版本的解释器,我应该执行命令 python3.8
\n当pdfkit库安装在pythonanywhere环境中时。这是通过分配给我的帐户的 bash 控制台完成的。使用命令pip3 install --user pdfkit完成安装
\n执行命令pip3 install --user pdfkit时验证库已成功安装
\n\n由于python3调用了python 3.7.5版本的解释器,我们可以推断当使用pip3命令安装pdfkit库时,该库安装在pythonanywhere的python 3.7.5版本环境中!可以通过随附的屏幕截图进行确认:
\n\n有了这些信息,可以确定 Flask 应用程序正在 pythonanywhere 提供的 python v3.8 (3.8.0) 解释器环境中运行,并且 pdfkit 库安装在由 pythonanywhere 提供的 python3.7 环境 (3.7.5) 中pythonanywhere -当然这可能会导致运行 pdfkit 库(运行版本 3.7.5)和 Flask 中的应用程序(运行版本 3.8.0)之间可能出现问题
\npdfkit 库已在本地为用户帐户安装在路径 /home/todonatacion/ .local /lib/python3.7/site-packages中
\n为了缓解报告的错误ModuleNotFoundError: No module named \'pdfkit\'我们需要告诉 Flask 中的 app.py 在哪里可以找到 pdfkit 库。
\n另一种可行的方法是在 app.py 中包含以下代码:
\n\n此代码询问该库是否在路径名中,如果不在,则包含它。这样导入pdfkit就可以完成了。
\n为了减少在 python3.8 上运行的 app.py 和在 python3 (3.7.5) 上运行的库之间不兼容的可能性,因此,最好使用 pip3.8 命令在本地执行库安装。#SEE 在 pythonanywhere.com 安装 python 模块(例如库/包)的必读内容位于以下链接:
\nhttps://help.pythonanywhere.com/pages/InstallingNewModules
\nPythonanywhere.com 声明:
\n“您可以使用 Bash 控制台在 PythonAnywhere 中安装新模块。” \n示例:要安装Python 3.6 的pwhich模块,您需要在 Bash 控制台(而不是 Python 控制台)中运行它:
\n例子:
\npip3.6 install --user pwhich
\n“如果您创建一个 virtualenv,您可以安装您想要的各种软件包的任何版本。但是,在 virtualenv 中,不需要上面提到的 --user。\n一旦您进入 virtualenv,要安装软件包,您只需使用没有 Python 版本号或 --user 标志的 pip:”
\n例子:
\n(my-virtualenv) $ pip install pwhich
\n\n因此,当使用命令pip3.8 install --user pdfkit执行 pdfkit 库的安装时
\n使用 pythonanywhere bash 控制台你会得到:
\n\n现在我们已经在python3.8环境的本地路径中安装了pdfkit库
\n\n为了确保app.py能够与python3.8环境中安装的pdfkit库配合使用,我们更新app.py源码中的路径名,以便根据python3的版本添加pdfkit库的路径名.8
\n\n因此,要在 pythonanywhere 环境中安装 wkhtmltopdf 库,命令类似:
\npip3.8安装--用户wkhtmltopdf
\n\n\n本次通话的问题是如何从 Flask 中的 jinja 模板创建 PDF 文件?好吧,一旦解决了pdfkit和wkhtmltopdf库的安装问题,我在 Flask 中的应用程序就可以在 Pythonanywhere 中运行。具体来说,我得到了主屏幕。当我选择打印报告时。它专门调用路由 @app.route(\'/ print_report001\') 我收到错误消息:
\nOSError:wkhtmltopdf 退出并显示非零代码 -6。错误:\nQxcbConnection: 无法连接到显示器\n** 不匹配
\n\n# pdfkit implementation\n@app.route(\'/print_report001\')\ndef print_report001():\n\n\n now = datetime.now()\n current_report_date = now.strftime("%Y-%m-%d %H:%M:%S")\n\n rendered = render_template(\n \'report_001.html\', \n report_title = "Report 001", \n current_report_date = current_report_date\n )\n\n pdf = pdfkit.from_string(rendered, False)\n response = make_response(pdf)\n response.headers[\'Content-Type\']=\'application/pdf\'\n response.headers[\'Content-Disposition\']=\'inline; filename=report_001.pdf\'\n return response\nRun Code Online (Sandbox Code Playgroud)\n相同的代码在我的本地开发站 fedora31 和 python3.8 以及 pdfkit 和 wkhtmltopdf 库上完美运行。由于某种原因,@app.route(\'/print_report001\') 在 pythonanywhere.com 服务器上运行时不起作用。是否遗漏了一些我没有考虑到的内容?任何解决此错误的指示将不胜感激。谢谢。
\n通过在 pythonanywhere.com 搜索 Flask 应用程序运行环境,发现 Flask 应用程序运行在“Ubuntu”版本“16.04.6 LTS (Xenial Xerus)”上
\n\n调查 ***QxcbConnection 错误:无法连接到显示 ** NO MATCH ***** 技术文档表明该错误可能与 xvfb 有关,这会导致问题:如何 在 Ubuntu 版本 16.04.6 中安装 xvfb LTS (Xenial Xerus) 由 pythonanywhere.com 托管?
\n根据 Ubuntu 文档,“ Xvfb 是一个 X 服务器,可以在没有显示硬件和物理输入设备的机器上运行。它使用虚拟内存模拟哑帧缓冲区。” (#SEE来源:http://manpages.ubuntu.com/manpages/xenial/man1/Xvfb.1.html并选择选项卡16.04 LTS)建议安装xvfb模块是必要的。
\n安装xvfb
\n“在 Ubuntu 16.04 (Xenial Xerus) 上安装 xvfb 软件包就像在终端上运行以下命令一样简单:”(#SEE:https://howtoinstall.co/en/ubuntu/xenial/xvfb)
\nsudo apt-get 更新
\nsudo apt-get install xvfb
\npythonanywhere.com 帐户中没有超级用户权限来执行这些命令,这让我们回到了问题如何在 pythonanywhere.com 托管的 Ubuntu 版本 16.04.6 LTS (Xenial Xerus) 中安装 xvfb?
\n\n解决这种情况的指南将不胜感激。谢谢你!
\nPythonanywhere.com 创建了一个新的虚拟系统。我们继续在新的虚拟系统上测试 app.py。并观察是否仍然存在相同的错误。
\n我已查看文件“pythonanywhere.com/user/todonatacion/files/var/log/\xe2\x80\xa6”,并再次生成相同的错误。“OSError:wkhtmltopdf 退出并显示非零代码 -6。错误:QXcbConnection:无法连接以显示 NO MATCH”
\n\n错误消息明确指出 *“OSError:wkhtmltopdf退出,并显示非零代码 -6。错误:\nQXcbConnection:无法连接到显示器\n** NO MATCH ***
\n当从 pythonanywhere bash 控制台执行命令:dpkg -s wkhtmltopdf时,您可以从 wkhthmltopdf 库中获取信息,包括:包名称 (wkhtmltpdf)、包安装状态、其依赖项以及使用包的建议。
\n\n寻找解决方案的重点是确定是否安装了 wkhtmltopdf 软件包的所有依赖项和建议。
\n从 pythonanywhere bash 控制台命令行运行命令wkhtmltopdf report 001.html report 001.pdf会收到消息: QXcbConnection: 无法连接到显示\n已中止
\n\n\n为了演示目的,在本地开发系统 fedora31 上从控制台命令行执行命令:wkhtmltopdf report_001.html report_001.pdf
\n$ wkhtmltopdf 报告_001.html 报告_001.pdf
\n加载页面 (1/2)
\n打印页数 (2/2)
\n完毕
\n$
\n成功获取pdf格式的report_001.pdf。
\n\n鉴于结果并不如预期。下一步是确认是否在 pythonanywhere.com 上安装了运行 wkhtmltopdf的推荐依赖项 -所需的推荐依赖项是xserver和xvfb。为此,我们将使用 dpkg -s xserver 命令和 dpkg xvfb 命令。
\n在 pythonanywhere bash 控制台中执行dpkg -s xserver命令可确认xserver 软件包未安装,并且没有有关 xserver 的信息。
\n\n\n在 pythonanywhere bash 控制台中运行命令dpkg -s xvfb确认xvfb软件包已安装。
\n\n\n由于 pythonanywhere 服务器没有附加显示器,Pythonanywhere 支持建议使用“PyVirtualDisplay”库。\n*
\n\n\n“在 PythonAnywhere 上运行代码的服务器没有\n附加的显示器,因此没有 X 服务器。相反,您需要使用\n虚拟显示器。尝试将 from pyvirtualdisplay import Display 添加到\n顶部脚本,然后将调用 \nwkhtmltopdf 的代码包装在 with Display(): 中,看看是否有帮助”
\n
使用“wkhtmltopdf”包装代码的实现如下:
\nimport pdfkit # needed to convert jinja templates to PDF file\n\nfrom pyvirtualdisplay import Display # pyvirtualdisplay is a python wrapper\n # for Xvfb, Xephyr and Xvnc\n # SEE: https://pypi.org/project/PyVirtualDisplay/\n\n\n\n\n@app.route(\'/print_report001\')\ndef print_report001():\n\n now = datetime.now()\n current_report_date = now.strftime("%Y-%m-%d %H:%M:%S")\n\n rendered = render_template(\n \'report_001.html\', \n report_title = "Report 001", \n current_report_date = current_report_date\n )\n\n\n disp = Display().start()\n # display is active\n pdf = pdfkit.from_string(rendered, False)\n response = make_response(pdf)\n response.headers[\'Content-Type\']=\'application/pdf\'\n response.headers[\'Content-Disposition\']=\'inline; filename=report_001.pdf\'\n disp.stop()\n # display is stopped\n return response\nRun Code Online (Sandbox Code Playgroud)\n结果是一份完美转换为 PDF 格式的报告。
\n| 归档时间: |
|
| 查看次数: |
5521 次 |
| 最近记录: |