近几个月一直在忙一个采购项目. 目前已经上线. 现在对这个项目的技术细节和开发过程做一个总结.
功能选型
公司原本有完善的报表打印功能, 是cs架构的. 而医院又没有上bs架构的主程序. 要使用bs架构的打印功能又需要上线完整的bs中间件, 我这边是独立的web项目就很尴尬.
好在医院只需要简单的报表打印功能. 因此领导让我研究一下, 看能否是否简单实现一下.
首先在开源世界搜了搜, 积木/帆软这些都是非开源的直接排除了. 公司肯定不会采购. EasyReport和UReport 不错, 可惜许久没有更新了.
- 首先选择的 printjs
优点: 集成简单.
缺点: 功能简单. 且只能打印出当前页面显示的内容. 表格需要左右拖动的, 就打印不完整. 非常儿戏.
当时医院催着上线, 我直接选用了该组件, 纯前端实现. 报表内容完全前端代码写死了. 非常的不妥当. 但是现场要着急演示. 我也只有搞上去,先发了.
- 之后项目顺利上线, 医院返了几张报表需求. 因为是前端写死的. 所以只能我来处理. 第一个方案肯定不行, 问题都需要我来改程序. 每次还改这么多, 改个样式都要重新打包, 大大的不妥.
第二个方案选用的是 hi-print
这是一个不错的方案, 基于jQuery实现, 开源维护作者还是个老乡, 我直接杀进交流群加了大佬微信.
优点:
1. 有完整的报表设计功能,
2. 支持控件自定义. 字体支持自定义. 样式直接通过界面修改.
3. 报表设计导出为json, 填充数据也为json. 方便传输
通过这些优点, 我已经有方案了. 把报表设计模板json保存到数据库, 需要的时候从数据库查. 把报表框架渲染出来, 再把数据绑定上去不就ok了
重新设计
- 后端: 先建一个表保存报表设计json. crud这个简单. 把报表名字作为主键.
- 前端: 把打印主键封装到单独print-vue中, 方便项目其他项目导入使用.
- 前端a页面需要打印功能时, 引入print-vue 作为子组件, 需要增加一个变量showType控制组件的显示.
- 然后就是父子组件的传值. 这里有个坑, 可能出现print-vue已经打开了 但是设计页面没有展示出来. 这里使用this.$nextTick()语法 (可以请教gpt)
因为 父组件的mounted钩子函数会在子组件的mounted钩子函数之前执行。这意味着在父组件的mounted钩子函数中调用子组件的方法时,子组件的mounted钩子函数已经执行完毕。
- 前端需要打印时先传名字到后端检查是否存在报表设计, 如果数据库不存在则弹出设计页面. 如果存在则直接打印. 如果按住ctrl再打印 表示要修改报表设计…
1
2
3
4
5
6
7
8
9if (event.ctrlKey) {
this.$nextTick(() => {
this.showType = 'design'
})
} else {
this.$nextTick(() => {
this.$refs.reportDesignV2.print()
})
}