82 lines
2.2 KiB
Python
82 lines
2.2 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
HTML渲染器
|
||
"""
|
||
|
||
from datetime import datetime
|
||
from pathlib import Path
|
||
from typing import Any, Dict
|
||
|
||
from jinja2 import Environment, FileSystemLoader
|
||
|
||
|
||
def datetime_to_str(field):
|
||
"""
|
||
渲染模板时,若字段为datetime对象则转为字符串
|
||
:param field: 字段
|
||
:return: 字符串
|
||
"""
|
||
if isinstance(field, datetime):
|
||
if field == datetime(9999, 12, 31):
|
||
return "长期"
|
||
if field.hour == 0 and field.minute == 0 and field.second == 0:
|
||
return field.strftime("%Y-%m-%d")
|
||
return field.strftime("%Y-%m-%d %H:%M:%S")
|
||
else:
|
||
return field
|
||
|
||
|
||
def str_to_str(field):
|
||
"""
|
||
渲染模板时,若字段为字符串则转空字符串
|
||
:param field: 字段
|
||
:return: 字符串
|
||
"""
|
||
if isinstance(field, str):
|
||
return field
|
||
return ""
|
||
|
||
|
||
class HTMLRenderer:
|
||
"""
|
||
HTML渲染器,支持:
|
||
基于模板,根据数据字典渲染HTML文档
|
||
"""
|
||
|
||
def __init__(self, template_path: Path):
|
||
"""
|
||
初始化HTML渲染器
|
||
:param template_path: 模板路径
|
||
"""
|
||
# 实例化jinja2环境
|
||
self.environment = Environment(
|
||
loader=FileSystemLoader(searchpath=template_path.parent)
|
||
)
|
||
# 设置过滤器
|
||
self.environment.filters.update(
|
||
{
|
||
"datetime_to_str": datetime_to_str,
|
||
"str_to_str": str_to_str,
|
||
}
|
||
)
|
||
# 加载指定模板
|
||
self.template = self.environment.get_template(template_path.name)
|
||
|
||
def render(self, obj: Dict[str, Any], output_path: Path) -> None:
|
||
"""
|
||
根据数据字典渲染HTML文档
|
||
:param obj: 数据字典
|
||
:param output_path: HTML文档输出路径
|
||
:return: 无
|
||
"""
|
||
try:
|
||
with open(
|
||
file=output_path,
|
||
mode="w",
|
||
encoding="utf-8",
|
||
) as file:
|
||
file.write(self.template.render(obj=obj)) # 在模板中需以obj获取键值
|
||
|
||
except Exception as exception:
|
||
print(f"根据数据字典渲染HTML文档发生异常:{str(exception)}")
|