渲染为XLSX¶
如果我们希望有一个渲染器始终使用与主渲染器相同的数据(如mako或jinja2),但将其渲染为其他对象,例如XLSX,该怎么办?然后我们可以这样做:
1# the first view_config for the xlsx renderer that
2# kicks in when there is a request parameter xlsx
3@view_config(context="myapp.resources.DBContext",
4 renderer="dbtable.xlsx",
5 request_param="xlsx")
6# the second view_config for mako
7@view_config(context="myapp.resources.DBContext",
8 renderer="templates/dbtable.mako")
9def dbtable(request):
10 # any code that prepares the data
11 # this time, the data have been loaded into context
12 return {}
这意味着 custom renderers 是不够的。我们必须定义一个模板系统。我们的渲染器必须查找模板,渲染它,并作为一个XLSX文档返回。
让我们定义模板接口。我们的模板将是放置在项目的 xlsx
子目录,定义了两个函数:
get_header
将返回表标题单元格
iterate_rows
将生成表行
我们的渲染器必须:
导入模板
运行函数以获取数据
将数据放入XLSX文件
返回文件
因为我们的模板将是python文件,所以我们将使用一个技巧。在 view_config
我们将模板的后缀改为 .xlsx
这样我们就可以配置视图。在渲染器中,我们用 .py
后缀而不是 .xlsx
.
将以下代码添加到名为 xlsxrenderer.py
在您的应用程序中。
1import importlib
2
3import openpyxl
4import openpyxl.styles
5import openpyxl.writer.excel
6
7
8class XLSXRenderer(object):
9 XLSX_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
10 def __init__(self, info):
11 self.suffix = info.type
12 self.templates_pkg = info.package.__name__ + ".xlsx"
13
14 def __call__(self, value, system):
15 templ_name = system["renderer_name"][:-len(self.suffix)]
16 templ_module = importlib.import_module("." + templ_name, self.templates_pkg)
17 wb = openpyxl.Workbook()
18 ws = wb.active
19 if "get_header" in dir(templ_module):
20 ws.append(getattr(templ_module, "get_header")(system, value))
21 ws.row_dimensions[1].font = openpyxl.styles.Font(bold=True)
22 if "iterate_rows" in dir(templ_module):
23 for row in getattr(templ_module, "iterate_rows")(system, value):
24 ws.append(row)
25
26 request = system.get('request')
27 if not request is None:
28 response = request.response
29 ct = response.content_type
30 if ct == response.default_content_type:
31 response.content_type = XLSXRenderer.XLSX_CONTENT_TYPE
32 response.content_disposition = 'attachment;filename=%s.xlsx' % templ_name
33
34 return openpyxl.writer.excel.save_virtual_workbook(wb)
现在有了渲染器。我们在申请表上登记一下 Configurator
:
config.add_renderer('.xlsx', 'myapp.xlsxrenderer.XLSXRenderer')
Of course, you need to modify the dotted-string to point to the module location you decided upon. You must also write the templates in the directory myapp/xlsx
,如 myapp/xlsx/dbtable.py
. 下面是一个虚拟模板的示例:
1def get_header(system, value):
2 # value is the dictionary returned from the view
3 # request = system["request"]
4 # context = system["context"]
5 return ["Row number", "A number", "A string"]
6
7def iterate_rows(system, value):
8 for row in range(100):
9 return [row, 100, "A string"]
要查看此方法的工作示例,请访问:
这里有一个捷克版本的配方:
有关如何添加自定义渲染器的详细信息,请参阅 Pyramid 文档和 Pyramid 技术体系说明手册的以下部分: