#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

大鹏一日同风起,扶摇直上九万里。这篇文章主要讲述#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB相关的知识,希望能为你提供帮助。
这是 Jerry 2021 年的第 71 篇文章,也是汪子熙公众号总共第 348 篇原创文章。
Jerry 之前发布过一篇文章 不使用任何框架,手写纯 JavaScript 实现上传本地文件到 ABAP 服务器,之后不少朋友留言,提出的问题概括为以下两类:
(1) 客户端通过 multipart/form-data 格式发送的数据,ABAP 端除了像 Jerry 文章采取字符串解析这种比较繁琐的方式处理外,还有其他方法吗?
(2) 能否上传二进制文件比如 Excel 到 ABAP 并进行解析?

#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

本文就来解答这两个问题。
使用 javascript 通过 multipart/form-data 格式发送 PDF 和 Excel 文件到 ABAP 服务器关于 multipart/form-data 格式的详细说明,参考 Mozilla 开发社区和 W3 Org 的文档:
  • https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
  • https://www.w3.org/html/wg/spec/association-of-controls-and-forms.html#multipart-form-data
我在前文例子的基础上稍作修改,在 Form 里使用两个类型为 file 的 input 标签,分别上传 PDF 和 Excel 文件:
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

用来测试的本地 PDF 文件:PDF.pdf,大小为 30129 字节。
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

内容如下:
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

本地用来测试的 Excel 文件:TEST.xlsx,内容如下:
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

点击 html 页面上传文件的超链接,在 Chrome 开发者工具观察到 HTTP POST 请求的负载,包含了 PDF 和 Excel 两个 input 控件包含的二进制流(stream):
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

点击 view source,查看 multipart/form-data 数据明细:
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

我们仍然可以在 Chrome 开发者工具里观察到上传的 PDF 和 Excel 的文件名和 Content-Type 即文件类型。同前文上传文本文件的例子不同,这里无法看到两个文件的二进制内容——这些二进制内容可以在 ABAP 服务器端调试器里观察到。
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

以上传的 PDF 文件为例,在 ABAP 服务器端接收到的 form-data 数据,如下图所示,绿色高亮区域即为上图 Chrome 开发者工具里能够观测到的文件名 PDF.pdf 和文件类型 application/pdf, 而%PDF-1.4# 开头的,就是 PDF 文件的二进制内容。
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

准确的说,PDF 格式是文本和二进制流的混合模式。用文本编辑器打开 PDF.pdf, 能看到其文件头部包含的是文本字符描述的文件元数据,比如该文件的创建和修改时间,创建该文件的工具名等等,后半部分才是二进制流。
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

现在已经有很多开源工具比如 javaScript 库可以用来生成和解析 PDF 文件了,感兴趣的朋友可以在搜索引擎里搜索 Jerry 这几篇文章:
  • 使用 ABAP 和 JavaScript 代码生成 PDF 文件的几种方式
  • 使用 JavaScript 将当前页面保存成 PDF,支持图片和文字的保存
  • PDF 文件如何转成 markdown 格式
对于上传到 ABAP 服务器的 PDF 文件的文件名,我们仍然采取和前一篇文章同样的方式解析,从下图红色矩形框中的字符串中提取。
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

而对于上图绿色高亮的 PDF 的二进制数据,CL_HTTP_REQUEST 提供了相应方法来提取。关键代码如下图所示:
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

当 ABAP 服务器接收到的客户端数据格式为 multipart/form-data 时,调用 CL_HTTP_REQUEST 的num_multiparts 方法可以得到 parts 的个数,再使用 get_multipart 方法,传入每个 part 的索引,就可以得到代表这个 part 的一个实例引用。
调用该引用的get_content_type 和 get_data 方法,就能解析出上传文件的类型(比如 pdf 格式对应的 application/pdf)和二进制内容。
至此调用 SAP CRM 附件创建 API 的三大参数:文件名,文件类型和文件二进制内容均已就绪,调用 API 即可将上传的 PDF 和 Excel 数据,创建成为 SAP CRM 销售订单的附件。
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

创建好的 PDF 和 Excel 附件在 SAP CRM 系统里显示如下:
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

打开这两个附件,确保上传之后,其内容同本地文件完全一致:
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

如何使用 ABAP 解析上传的 Excel 文件这个话题,其实 Jerry 2019 年的文章 使用ABAP操作Excel的几种方法 已经系统介绍过。
我们在 ABAP 调试器里观察到,本地扩展名为 xlsx 的 Excel 文件,上传到 ABAP 服务器时,其 content-type 为:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

什么是 openxmlformats?下面通过具体的例子来说明。
以我这个本地 Excel 文件为例,将扩展名从 xlsx 更改为 zip,然后解压:
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

发现 xlsx 文件其实是一个压缩包,解压之后生成了一个文件夹,包含了下图所示的若干子文件夹和文件。
上图 Excel 文件有一个名为 Sheet1 的内容页,A1 值为 ABAP,B1 值为 Java,这个信息维护在解压出来的 worksheets 文件夹的子文件 sheet1.xml 内:
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

上图高亮的 XML c 节点代表 Cell,r=" A1" 和 r=" B1" , 代表这两个 cell 所在的 Row ID,c 的子节点 v 包含了 Cell 的具体值。
不难发现,sheet1.xml 里并未直接将 ABAP 和 Java 的字符串字面量在内,而仅仅存放了其索引,0 和 1. 做过 Java 开发的朋友,可以把这种设计类比成 Java 的字符串常量池。
在解压出的文件夹里有另一个文件 sharedStrings.xml, 顾名思义,维护了 Excel worksheets 里出现的所有字符串,用于在 sheets 之间共享。每个单独的 sheet xml 文件只维护使用到的字符串的索引,以减小 Excel 文件的尺寸。
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

因此,只要熟悉了 TEST.xlsx 重命名为 TEST.zip 并解压之后生成的每一个文件的用途,即 Open XML Formats 的协议规范,就可以使用任何高级编程语言解析 Excel 文件。
可以在 WikiPedia 里找到 Open XML Formats 协议定义的每个文件的作用:
https://en.wikipedia.org/wiki/Office_Open_XML_file_formats
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

SAP CRM 提供了一个工具类,基于 Open XML Formats 解析 Excel 文件内容:cl_xlsx_document.
只需将 Excel 文件的二进制内容传入,该工具类即返回一个 Excel 文件的引用,根据该引用的各种 GET 方法,即可访问到 Excel 文件内由 Open XML Formats 协议定义的各个部分的内容。
核心逻辑如下图所示,代码都是自描述的,这里不再赘述。
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

当然,开源项目 abap2xlsx 也是另一个选择:
https://github.com/sapmentors/abap2xlsx
#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB

文章图片

至于 SAP Fiori 应用通过 SAP Gateway 上传附件的技术细节,Jerry 将来会介绍。
本文涉及到的前后端完整源代码,请在这个链接处下载。
感谢阅读。
Jerry 的 ABAP 专题
  • Jerry的ABAP, Java和JavaScript乱炖
  • ABAP开发人员未来应该学些什么
  • Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现
  • Jerry的ABAP原创技术文章合集
  • 300行ABAP代码实现一个最简单的区块链原型
  • 使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数
  • 在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务
  • ABAP vs Java, 蛙泳 vs 自由泳
  • 聊聊C语言和ABAP
  • 动手使用ABAP Channel开发一些小工具,提升日常工作效率
  • 我用ABAP做过的那些无聊的事情
  • 不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧
  • 使用Visual Studio Code编写和激活ABAP代码
  • 你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧
  • 【#私藏项目实操分享# 使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 AB】在SAP云平台ABAP编程环境上编写第一段ABAP程序
  • SAP官方发布的ABAP编程规范
  • ABAP Code Inspector那些隐藏的功能,您都知道吗?
  • 还在用ABAP进行SAP产品的二次开发?来了解下这种全新的二次开发理念吧
  • ABAP Netweaver体内的那些寄生式编程语言
  • 从SAP社区上的一篇博客开始,聊聊SAP产品命名背后的那份情怀
  • 云端的ABAP Restful服务开发
  • 如何在SAP云平台ABAP编程环境里把CDS view暴露成OData服务
  • 使用abapGit在ABAP On-Premises系统和SAP云平台ABAP环境之间进行代码传输
  • 30分钟用Restful ABAP Programming模型开发一个支持增删改查的Fiori应用
  • Jerry带您了解Restful ABAP Programming模型系列之二:Action和Validation的实现
  • Jerry带您了解Restful ABAP Programming模型系列之三:云端ABAP应用调试
  • SAP云平台上的ABAP编程环境里如何消费第三方服务
  • ABAP开发者上云的时候到了 - 现在大家可以免费使用SAP云平台ABAP环境的试用版了
  • 学而不思则罔 - SAP云平台ABAP编程环境的由来和适用场景
  • SAP云平台里的三叉戟应用
  • 如何基于Restful ABAP Programming模型开发并部署一个支持增删改查的Fiori应用
  • SAP 2019 TechEd Key Note解读:云时代下SAP从业人员如何做二次开发?
  • 有哪些ABAP关键字和语法,到了ABAP云环境上就没办法用了?
  • ABAP开发环境终于支持以驼峰命名法自动格式化ABAP变量名了
  • 利用ABAP 740的新关键字REDUCE完成一个实际工作任务
  • 一段让人瑟瑟发抖的ABAP代码
  • 昨日万圣节ABAP怪兽级代码谜团,公布答案啦
  • 介绍一种在ABAP内核态进行内表高效拷贝的方法
  • 使用SAP Cloud Application Programming模型开发OData的一个实际例子
  • 当ABAP遇见普罗米修斯
  • 使用ABAP绘制可伸缩矢量图
  • ABAP开发环境语法高亮的那些事儿
  • SAP错误消息调试之七种武器:让所有的错误消息都能被定位
  • 使用ABAP操作Excel的几种方法
  • SAP GUI里的收藏夹事务码管理工具
  • SAP GUI和Windows注册表
  • 有了Debug权限就能干坏事?小心了,你的一举一动尽在系统监控中
  • ABAP CCDEF, CCIMP, CCMAC, CCAU, CMXXX这些东东是什么鬼
  • 实现ABAP条件断点的三种方式
  • 使用SAT跟踪监控从浏览器打开的SAP应用的性能和调用栈
  • 一个13年ABAP老兵的建议:了解这些基础知识,对ABAP开发有百利而无一害
  • SAP ABAP Netweaver容器化, 不可能完成的任务吗?
  • SAP产品增强技术回顾
  • SAP API开发方法大全
  • 浅谈Java和SAP ABAP的静态代理和动态代理,以及ABAP面向切面编程的尝试
  • SAP ABAP应用服务器的HTTP响应状态码(Status Code)
  • SAP ABAP里存在Java List这种集合工具类么?CL_OBJECT_COLLECTION了解一下
  • ABAP面试题系列:写一组会出现死锁(Deadlock)的ABAP程序
  • SAP ABAP Netweaver服务器的标准登录方式讲解
  • SAP ABAP关键字语法图和ABAP代码自动生成工具Code Composer
  • SAP ABAP SM50的另类用途 - ABAP工作进程对数据库表读取操作的检测
  • 关于SAP ABAP字符变量和字符串变量字符个数的一个知识点,和一个血案
  • SAP ABAP一组关键字 IS BOUND, IS NOT INITIAL和IS ASSIGNED的用法辨析
  • SAP ABAP和Java里的弱引用(WeakReference)和软引用(SoftReference)
  • SAP AMDP介绍 - ABAP托管的HANA数据库过程
  • 给你的ABAP对象打上标签(Tag)
  • 历史上的今天:编程语言中null引用的十亿美元错误
  • ABAP Development Tool 代码模板和其他一些实用技巧汇总
  • SAP ABAP Development Tool 提高开发效率的十个小技巧
  • 如何在 SAP BTP 平台 ABAP 编程环境里消费基于 SOAP 的 Web Service
  • ABAP 真的会过时吗?聊聊 ABAP 的过去,现在和未来
  • 基于 abapGit 和 abaplint 的 ABAP 持续集成的一个例子
  • 不使用任何框架,手写纯 JavaScript 实现上传本地文件到 ABAP 服务器
更多Jerry的原创文章,尽在:" 汪子熙" 。

    推荐阅读