<p>我在使用pyinstaller构建GUI时遇到了这个问题。我使用Jinja2呈现一个报表,模板没有加载,相反,我也收到了“unregistered loader type”错误。通过在线阅读和测试许多解决方案,我终于找到了一个解决方案:必须使用FileSystemLoader而不是PackageLoader。还需要为FileSystemLoader提供文件路径。我的最终解决方案是来自<a href="https://stackoverflow.com/questions/38617900/need-to-package-jinja2-template-for-python">here</a>和{a2}的信息的组合。在</p>
<p>下面提供了此解决方案的完整示例。我的代码在testjinjia2下,模板在子目录templates中:</p>
<pre><code>testjinja2
| |
| + templates
| |
| + base.html
| + report.html
testreport.py
testreport.spec
</code></pre>
<p>在测试报告.spec公司名称:</p>
^{pr2}$
<p>在测试报告.py你说</p>
<pre><code>import os
import sys
from jinja2 import Environment, PackageLoader, FileSystemLoader
def resource_path(relative_path, file_name):
""" Get absolute path to resource, works for both in IDE and for PyInstaller """
# PyInstaller creates a temp folder and stores path in sys._MEIPASS
# In IDE, the path is os.path.join(base_path, relative_path, file_name)
# Search in Dev path first, then MEIPASS
base_path = os.path.abspath(".")
dev_file_path = os.path.join(base_path, relative_path, file_name)
if os.path.exists(dev_file_path):
return dev_file_path
else:
base_path = sys._MEIPASS
file_path = os.path.join(base_path, file_name)
if not os.path.exists(file_path):
msg = "\nError finding resource in either {} or {}".format(dev_file_path, file_path)
print(msg)
return None
return file_path
class Report:
def main(self, output_html_file):
# template_loader = PackageLoader("report", "templates")
# - PackageLoader returns unregistered loader problem, use FileSystemLoader instead
template_file_name = 'report.html'
template_file_path = resource_path('templates', template_file_name)
template_file_directory = os.path.dirname(template_file_path)
template_loader = FileSystemLoader(searchpath=template_file_directory)
env = Environment(loader=template_loader) # Jinja2 template environment
template = env.get_template(template_file_name)
report_content_placeholder = "This is my report content placeholder"
html = template.render(report_content= report_content_placeholder)
with open(output_html_file, 'w') as f:
f.write(html)
if __name__ == "__main__":
my_report = Report()
my_report.main("output.html")
</code></pre>
<p>需要一个方法资源_路径,因为jinja模板文件的文件路径在我的IDE和从exe文件中提取的文件不同。在</p>
<p>还有一些简单的模板文件供您试用。<br/>
基本.html在</p>
<pre><code><html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.centered {
text-align: center;
}
.centeredbr {
text-align: center;
page-break-before:always;
}
.underlined {
text-decoration: underline;
}
</style>
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
</code></pre>
<p>报表html</p>
<pre><code><!DOCTYPE html>
{% extends "base.html" %}
{% block body %}
<h1 class="centered underlined">Report Title</h1>
<h2 class="centeredbr">Chaper I</h2>
<p>{{ report_content }}</p>
{% endblock %}
</code></pre>
<p>我使用的是pyinstaller 3.2.1和python3.5.1anaconda自定义(64位)</p>