输出 EXCEL 文件是 ABAP 开发工作中的常见需求, 为了学习相关技术, 我翻译过一篇文章: 使用 OLE2 对象创建 EXCEL 文件, 并且一度乐在其中.
最近几个月, 经过与若干 EXCEL 打印程序的艰苦斗争, 以及对 abap2xlsx 和 XLSX Workbench 的使用. 我逐渐意识到 OLE 实在是一种不适合输出 EXCEL 的技术, 虽然它似乎是大部分 ABAP 开发者实现相关功能的首选方案. 它的缺点很多, 优点则乏善可陈... 它的过度使用, 对业界是一件不好的事情. 为了让一些新人不至于误入歧途, 选用不合理的技术进行开发工作, 我决定写下这篇文章.
下面就来逐一列数以 OLE 方式生成 EXCEL 文件的各种缺点, 以及它的替代品.
本文链接: http://www.cnblogs.com/hhelibeb/p/8984969.html
转载请注明
OLE 的缺点
OLE 即 Object Linking and Embedding https://en.wikipedia.org/wiki/Object_Linking_and_Embedding 对象链接与嵌入, 通过查阅 ABAP 文档 https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abenole2.htm 可知, 在 ABAP 中, OLE 可以用于在表示层处理外部对象. 只支持 windows 自动化对象. 典型的应用场景是与 Microsoft Office 产品进行交互.
基于这一信息, 我们可以得知两件事情:
OLE 需要在表示层运行(通俗地说, 即需要在用户的设备上运行)
OLE 只能经由 SAP 客户端与支持 OLE 的应用进行交互
这两个特性是使用 OLE 方式输出 EXCEL 时产生各种的问题的重要来源. 下面来一一说明这些问题.
(注: 下文中所提到的 OLE, 如无特指, 均指使用生成 EXCEL 文件时使用的 OLE)
1, 运行速度慢
使用 OLE 生成 EXCEL 的速度很慢, 是每个有过相关开发经验的人都体验到的事情, 特别是某些涉及到动态行列的表单(需要用到大量复制 / 粘贴操作), 有时这类程序的 99% 以上的运行时间都花在 OLE 操作上面. 此外, 既然 OLE 需要在用户的电脑上通过应用程序交互的方式来运作, 用户的计算机的性能和可用资源也可能会对程序的运行效率产生一定影响.
2, 兼容性差
OLE 的技术原理决定了用户必须装有 Office 软件和 SAP 客户端软件 (如 SAP GUI, NWBC 等) 才能正常运行相关程序. 如果软件安装不正确, 或者某些版本之间的兼容性不良好, 就可能会导致程序无法正常运行. 而且问题会很难排查和解决, 最后往往只能请 IT 支持人员为用户升级 Office 软件, SAP 客户端, 甚至重装 Windows 系统.
另一方面, 如果用户没有安装 SAP 客户端, 而是使用基于 web 的客户端访问 SAP 系统, OLE 程序也无法运行. 本人在前些天就遇到这样一个需求: 把 ERP 已有的某个打印程序迁移到 SAP SRM 系统上面. 这本来是很简单的事情. 但是, 由于该打印程序选择了 OLE 输出 EXCEL, 调用 EXCEL 打印预览的方式实现打印功能, 因此无法迁移到 SRM, 因为 SRM 的用户界面是基于浏览器的, 无论是 WebDynpro 还是 SAP GUI for HTML, 都不会支持 OLE. 最终只好用 SmartForms 重写了打印部分.
一个速度慢, 兼容性差的程序, 其用户体验是不好的. 重视用户体验的程序设计者, 不应该使用这一技术.
3, 开发效率低
ABAP 中有几个专门用来处理 OLE 的关键字: CALL METHOD,CREATE OBJECT,GET PROPERTY,SET PROPERTY,FREE OBJECT. 通过它们开发者可以在 ABAP 中写出类似于 VBA 的代码. 大部分 ABAP 开发者在写 OLE 代码之前的第一件是是在 EXCEL 中录制宏, 然后将宏中的代码 "翻译" 成 ABAP 代码, 对于不了解 VBA 的开发者来说, 这是一个额外的负担. 此外, 开发者需要将数据从 ABAP 的数据结构 (内表, 结构) 映射至 EXCEL 的单元格, 很多开发者特别是新入门的开发者在这方面没有很好的组织能力, 写出的代码中充满了魔法数, 不合理的数据结构. 耦合度高, 可读性差, 也较难改用其它表单输出技术输出.
由于 1 和 2 的存在, 开发者自己在调试程序时甚至都要花上不少额外的时间, 等待程序完成... 综合各种原因, OLE 的开发效率是很低的. 重视开发速度的实施项目里, 不应该选择使用这一技术.
以下是一段典型的 OLE 代码, 可以看到意义不显明的数字, 动态的行操作等...
DATA: c_line TYPE i.
c_line = 27.
DO 3 TIMES.
c_line = c_line + 1.
ADD 1 TO lc_row.
PERFORM excel_row_insert USING wsheetobj c_line lc_row 1.
CASE sy-index.
WHEN 1.
PERFORM frm_fill_xls USING lc_row 8 gw_mseg-dmbtr.
PERFORM frm_fill_xls USING lc_row 9 gw_mseg-tax.
PERFORM frm_fill_xls USING lc_row 10 gw_mseg-dmbtr_t.
CLEAR gw_mseg.
WHEN 2.
PERFORM frm_fill_xls USING lc_row 1 '本次收货总计:'.
PERFORM frm_fill_xls USING lc_row 4 lwa_out-menge.
PERFORM frm_fill_xls USING lc_row 8 lwa_out-dmbtr.
PERFORM frm_fill_xls USING lc_row 9 lwa_out-tax1.
PERFORM frm_fill_xls USING lc_row 10 lwa_out-dmbtr_t.
IF lc_page <> lwa_out-page.
PERFORM frm_delete_row USING lc_row.
lc_row = lc_row - 1.
ENDIF.
WHEN 3.
PERFORM frm_fill_xls USING lc_row 11 gc_name.
WHEN OTHERS.
ENDCASE.
ENDDO.
4, 维护困难
如果说开发效率低, 会让项目实施人员痛苦一时. 那么 OLE 带来的程序维护困难, 则会让接下来的维护人员受到长期的折磨.
OLE 的专有语法使得静态分析工具难以对其进行分析, 这就使得代码质量的控制变得困难. 我们在实践 Code Inspector 的时候, 只能被迫无视 OLE 代码的检查结果, 因为这种情况下的结果并不正确可靠.
开发难度大, 开发者水平的不足使得程序的可读性和可扩展性可能比较差, 修改困难.
可测试性差. OLE 代码的耦合度普遍过高(没有把数据的处理和前端的展示逻辑很好的区分开), 所以即便成功修改了程序, 要验证修改的正确性也是困难的..
可能要花大力气处理未来的兼容问题.
相信每一个开发者都希望自己能成为创造价值的人, 而非成为总是在应付不应存在的技术债务的还债人. 也就是说, 稍具同理心的人, 也不应该为程序的维护者留下这样的债务. 尊重劳动者的人, 不应该选择使用这一技术.
5, 可控性差
本节是专门针对打印功能的讨论. 出于对数据一致性, 数据安全的控制需求, 某些公司希望可以用户的控制打印行为: 在打印内容输出到系统外部之后, 锁定相关的数据(比如, 打印过的采购订单不可以再编辑). 如果是使用 SAP 自身 SmartForms 等技术, 可以从相关函数的参数获取到表单的输出状态(output_done). 但如果使用 OLE 技术, 则无法实现这样的控制.
这是因为, 对 SAP 系统而言, SmartForms 的打印预览是在 SAP 系统内进行的, 系统可以准确地获知预览内容是否被输出到外部; 而相对的, 对于任何基于 OLE 操作 EXCEL 的打印方式而言, 在实际打印发生前, 打印内容都必须输出到外部, 这使得系统失去了对相关内容的控制能力. 以采购订单为例, 在运行基于 SmartForms 开发的打印程序时, 用户可以选择预览表单, 同时不将其输出, 这时系统认为采购订单没有被输出到外部, 会保持其可编辑的状态, 显然这是合理的; 但如果换成 OLE 操作 EXCEL 输出内容, 调用 Excel 的打印预览的话, 进入打印预览之前, 系统就已经将内容输出到外部了(即已经将内容输出到被打开的 EXCEL 应用中), 此时采购订单需要被锁定, 可是用户会认为这是不合理的, 因为在业务上, 用户只是想预览一下内容而已, 并不是真的要打印, 实际上也没有执行打印动作.
希望对表单内容有更好的控制能力时, 不应该选用这一技术.
替代品
从 Office2007 开始, 微软逐渐推广了 Open XML 格式 https://msdn.microsoft.com/en-us/library/aa338205(v=office.12).aspx . 这一格式的存在催生了新的生成 EXCEL 文件的技术实现方式. 以下介绍我接触过的两种, 相比 OLE, 它们有着相似的优点:
速度快
平台独立
支持后台处理
XLSX Workbench
一种可视化表单生成工具, 相比复杂的 OLE, 可以用少量代码 + 一些拖拽和配置来生成 EXCEL 报表, 性能更好. 按 XLSX Workbench 的文档介绍, 它有九大特性:
无需 ABAP 编程技能
可视化设计方式
高性能
支持后台处理
强大的表单格式特性支持
支持公式
支持图片
支持图表
支持树
官方文档: https://sites.google.com/site/sapxlwb/home
XLSX Workbench 是我眼中的首选方案, 因为它的可视化编辑工具真的很方便. 通过这个工具, 开发者只需要简单地将数据放入设计好的 context 结构, 并且在可视化工具中将 context 绑定到具体的单元格, 就可以生成 EXCEL 文件了:
DATA: l_data TYPE zcontext.
- CALL FUNCTION 'ZXLWB_CALLFORM'
- EXPORTING
- iv_formname = 'ZXLWBFORM'
- iv_context_ref = l_data
- EXCEPTIONS
OTHERS = 2.
IF sy-subrc NE 0 .
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 .
ENDIF .
也可以轻松地将表单输出方式切换为 SmartForms:
DATA: fm_name TYPE rs38l_fnam,
l_data TYPE zcontext.
- CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
- EXPORTING
- formname = 'ZSMARTFORM'
- IMPORTING
- fm_name = fm_name
- EXCEPTIONS
- no_form = 1
- no_function_module = 2
OTHERS = 3.
- CALL FUNCTION fm_name
- EXPORTING
- it_data = l_data.
- abap2xlsx
abap2xlsx 的优势:
可能是最知名的 ABAP 开源项目. 该项目包含很多简单易上手的例子代码. 在与 XLSX Workbench 对比后, 我没有选用它, 是因为它似乎不能将 EXCEL 的样式处理和 ABAP 的数据处理分离, 据此我认为, 使用它带来的开发难度和维护难度要稍高一点点(当然比 OLE 好得多).
项目地址: https://github.com/ivanfemia/abap2xlsx
来源: https://www.cnblogs.com/hhelibeb/p/8984969.html