上海某医院阳光采购项目总结一(报表功能)

近几个月一直在忙一个采购项目. 目前已经上线. 现在对这个项目的技术细节和开发过程做一个总结.

功能选型

公司原本有完善的报表打印功能, 是cs架构的. 而医院又没有上bs架构的主程序. 要使用bs架构的打印功能又需要上线完整的bs中间件, 我这边是独立的web项目就很尴尬.

好在医院只需要简单的报表打印功能. 因此领导让我研究一下, 看能否是否简单实现一下.

首先在开源世界搜了搜, 积木/帆软这些都是非开源的直接排除了. 公司肯定不会采购. EasyReport和UReport 不错, 可惜许久没有更新了.

  1. 首先选择的 printjs

优点: 集成简单.
缺点: 功能简单. 且只能打印出当前页面显示的内容. 表格需要左右拖动的, 就打印不完整. 非常儿戏.

当时医院催着上线, 我直接选用了该组件, 纯前端实现. 报表内容完全前端代码写死了. 非常的不妥当. 但是现场要着急演示. 我也只有搞上去,先发了.

  1. 之后项目顺利上线, 医院返了几张报表需求. 因为是前端写死的. 所以只能我来处理. 第一个方案肯定不行, 问题都需要我来改程序. 每次还改这么多, 改个样式都要重新打包, 大大的不妥.
    第二个方案选用的是 hi-print
    这是一个不错的方案, 基于jQuery实现, 开源维护作者还是个老乡, 我直接杀进交流群加了大佬微信.

优点:
1. 有完整的报表设计功能,
2. 支持控件自定义. 字体支持自定义. 样式直接通过界面修改.
3. 报表设计导出为json, 填充数据也为json. 方便传输

通过这些优点, 我已经有方案了. 把报表设计模板json保存到数据库, 需要的时候从数据库查. 把报表框架渲染出来, 再把数据绑定上去不就ok了

重新设计

  1. 后端: 先建一个表保存报表设计json. crud这个简单. 把报表名字作为主键.
  2. 前端: 把打印主键封装到单独print-vue中, 方便项目其他项目导入使用.
  3. 前端a页面需要打印功能时, 引入print-vue 作为子组件, 需要增加一个变量showType控制组件的显示.
  4. 然后就是父子组件的传值. 这里有个坑, 可能出现print-vue已经打开了 但是设计页面没有展示出来. 这里使用this.$nextTick()语法 (可以请教gpt)

    因为 父组件的mounted钩子函数会在子组件的mounted钩子函数之前执行。这意味着在父组件的mounted钩子函数中调用子组件的方法时,子组件的mounted钩子函数已经执行完毕。

  5. 前端需要打印时先传名字到后端检查是否存在报表设计, 如果数据库不存在则弹出设计页面. 如果存在则直接打印. 如果按住ctrl再打印 表示要修改报表设计…
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if (event.ctrlKey) {
    this.$nextTick(() => {
    this.showType = 'design'
    })
    } else {
    this.$nextTick(() => {
    this.$refs.reportDesignV2.print()
    })
    }

报表截图