- 上一篇 Puppeteer将动态html页面生成pdf,这篇文章提到的的解决方案,从npm包的下载量看到,还是有不少developer在采用的;上一篇文章分享的是如何将我们用vue/react开发的页面比方便的转成pdf,在销售伙伴展业需求中,除了pdf之外,还有宣讲类的需求,会用到ppt、word等格式;
1.模型数据和模板
- 下面文章中所说的生成文件 ,指的是生成pdf/ppt/word;
- 这篇文章主要分享,如何只开发一次,就可以将页面生成文件;或者是批量、快速的生成文件;
- 这里我们提出了一个模型数据 和模板的概念,每条模型数据和模板是一一对应的;
- 模板 :
- 模板是可以自定义的,是根据具体的业务需求开发的,也就是平时我们说的组件,这里模板和组件不同的地方是模板已经解决了生成文件所涉及的问题;
- 模型数据 :
- 模型数据和模板是一一对应的,提供对应的模型数据,就可以渲染对应的模板,模板渲染成功,就可以生成文件;
2.生成流程
背景
目前我们需要将分析结果页生成pdf/ppt/word场景是非常多的,理财顾问拿针对客户的分析报告展开业务,或pdf打印文件,或pdf链接;
有客户需求,如果提供对应的数据,就可以生成对应的报告(pdf/word/ppt);
之前生成pdf的开发场景是:前端伙伴先开发联调完对应的分析页面,然后提测,测试bug解决差不多了再开发对应的报告页面,调样式、调下载流程,复用程度比较少; 现在流程 如果需求对应的模板之前有别的项目实现过,传入模板对应的结构数据,就可以实现生成word/pdf/ppt;
技术背景
当developer开发的原页直接接入jsdk,解析出来全数据,在生成word/ppt可能识别不到或者不支持,或者是转换出来的和在页面设置的有差异,这个需要抹平;抹平的方式有下面几种:
- 将两边有差异的部分列出来, 写js 脚本,抹平,不同设备可能表现不一样,这块可能需要一直迭代兼容;
- 用推荐的规则样式写,这样限制了开发同学;
- 用阶段二 根据模型数据来 render 模型组件,这些模型组件都是内置的,解决了css和文件转换两边的样式差异问题;开发者只用提供模型数据,具体的样式和抹平操作 模型组件来做;
- 在满足文件转换规则的基础上 可以更方便、快捷、复用程度更好;
组件模型数据:
- 按照模型结构,是以组件的维度划分的数据结构;
- 是不依赖于任何客户的、没有业务意义的、独立的数据结构;
- 模型数据是由一个个组件模型组成的,组件模型类型区分是根据 type字段;
模型计算引擎:
- 主要实现从模型数据到文件生成所需全数据的转换;
- 包括:模型数据和默认配置数据merge、单位转换、差异抹平等
组件渲染引擎:
- 这里有个模板的概念,设计思想和java poi 模板 有点类似;
- java poi 兼容多变的业务场景,其中有个模板概念,使用者在生成word之前,提前内置好模板,定义好数据结构,在模板内定义每项的字段名,加上对应的样式,生成word时,根据定义好的数据结构传入对应业务数据,即可生成对应的word;
- 但是poi 有个缺陷,是只支持流式布局,没有位置的概念,不支持支持横向布局;
- 由于组件渲染内部是用js实现的,天然的支持带位置的元素节点,位置信息一般包括x、y、w、h,如果每个节点的信息都需要模型数据往里传的话,使用起来是非常痛苦的;
- 所以需要有 render层把位置信息的获取设置变成程序实现的,使用模型时不用关心这里;
- 主要功能:
- 模板概念,聚合此模板内功能;
- 模板的颗粒度适中,可方便组合;
- 设置、获取位置信息和其他信息,满足全数据要求
- 抹平差异
- 可接入原来nb-fe-pdf 生成pdf 整套逻辑;
- 模板概念,聚合此模板内功能;
word/ppt全量数据
- 全量数据是生成word/ppt所必须的,里面包含位置信息x、y、w、h、样式信息、内容信息等;
// todo
模型数据
数据模型demo
// todo
数据模型转化过程
- 生成word/ppt是由全量数据构成,全量数据 =format (模型数据 merge 默认配置数据)
- 全量数据: jsdk解析后的数据
- 模型数据:如下面基金概率模型数据
- format: 经过包括 格式化、数据填充操作 到生成文件所需的全量数据
- 正常使用只用传模型数据就可以
Tpl说明
- 页面中所有的模板Tpl(HeaderTpl/FooterTpl/ListTpl) 都是有提前内置的模板实现,使用时:1.关联Tpl名称 2.根据Tpl 数据格式传入对应数据
- 这样做的好处是在面对各种各样的需求时 既可以保证灵活性,又可以简单、快捷接入全量数据
组件模型
- 组件模型主要分为Title/Img/RowTable/TableDisplay/Chart/Card/Tpl