这是Jerry在2021年的第71篇文章,也是王子熙一共发表的第348篇原创文章公众号。Jerry之前发表过一篇文章,没有使用任何框架,手写纯JavaScript将本地文件上传到ABAP服务器。之后有不少朋友留言,提出的问题归纳为以下两类:(1)客户端通过multipart/form-data格式发送的数据,除了像jerry文章那样繁琐的字符串解析方式,还有没有还有其他方法可以在ABAP方面处理它吗?(2)能否将Excel等二进制文件上传到ABAP中解析?本文将回答这两个问题。使用JavaScript将PDF和Excel文件以multipart/form-data格式发送到ABAP服务器。multipart/form-data格式的详细说明,参考Mozilla开发社区和W3Org的文档:https://developer.mozilla.org...https://www.w3.org/html/wg/sp...我在上一个例子的基础上做了一点小改动,分别在Form中使用了typefile的两个input标签上传PDF和Excel文件:使用本地PDF文件进行测试:PDF.pdf,大小是30129字节。内容如下:本地测试使用的Excel文件:TEST.xlsx,内容如下:点击HTML页面的超链接上传文件,在Chrome开发者工具中观察HTTPPOST请求的负载情况,包括PDF和Excel两个输入控件。Binarystream(流):点击viewsource可以查看multipart/form-data数据详情:我们在Chrome开发者工具中仍然可以观察到上传PDF和Excel的文件名和Content-Type。与前面上传文本文件的例子不同,这里看不到两个文件的二进制内容——这些二进制内容可以在ABAP服务器端调试器中观察到。以上传的PDF文件为例,ABAP服务器端收到的form-data数据,如下图,绿色高亮区域为在Chrome开发者中可以观察到的文件名PDF.pdf和文件类型上图中的toolsapplication/pdf,%PDF-1.4#以PDF文件的二进制内容开头。准确地说,PDF格式是文本流和二进制流的混合模式。用文本编辑器打开PDF.pdf,可以看到文件头包含了用文本字符描述的文件元数据,比如文件的创建和修改时间、创建文件的工具名称等,并且后半部分是二进制流。现在有很多开源工具可以用来生成和解析PDF文件,比如JavaScript库。有兴趣的朋友可以在搜索引擎搜索Jerry的文章:使用ABAP和JavaScript代码生成PDF文件的几种方法使用JavaScript转换当前页面保存为PDF,支持保存图片和文字如何将PDF文件转换为markdownformat对于上传到ABAP服务器的PDF文件的文件名,我们还是采用与上一篇文章相同的方法进行分析,从下图中红色矩形框内的字符串中提取出来。对于上面绿色高亮显示的PDF的二进制数据,CL_HTTP_REQUEST提供了相应的方法来提取。关键代码如下图所示:当ABAP服务器接收到的客户端数据格式为multipart/form-data时,调用CL_HTTP_REQUEST的num_multiparts方法获取part的个数,然后使用get_multipart方法传入每个部分的索引。您可以获得表示此部分的实例引用。调用本参考的get_content_type和get_data方法,解析出上传文件的类型(如application/pdf对应pdf格式)和二进制内容。至此,调用SAPCRM附件创建API的三个参数:文件名、文件类型、文件二进制内容都准备好了,可以通过调用将上传的PDF和Excel数据创建为SAPCRM销售订单的附件API。创建好的PDF和Excel附件在SAPCRM系统中显示如下:打开这两个附件,上传后确保内容与本地文件完全一致:如何使用ABAP解析上传的Excel文件这个话题,在其实Jerry在2019年的文章《使用ABAP操作Excel的几种方法》已经系统介绍过了。我们在ABAP调试器中观察到,当本地扩展名为xlsx的Excel文件上传到ABAP服务器时,其content-type为:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet什么是openxmlformats?下面通过一个具体的例子来说明。以我本地的Excel文件为例,将扩展名xlsx改为zip,然后解压:发现xlsx文件其实是一个压缩包。解压后生成一个文件夹,包括几个子文件夹和文件。上面的Excel文件有一个名为Sheet1的内容页,A1值为ABAP,B1值为Java,在解压后的worksheets文件夹的子文件sheet1.xml中维护了这些信息:上图中高亮的XMLc节点代表Cell,r="A1"和r="B1",代表两个cell的RowID,c的子节点v包含了Cell的具体值。不难发现,sheet1.xml中并没有直接包含ABAP和Java字符串字面量,只是存储了它的索引,0和1。做过Java开发的朋友可以把这种设计比作Java的String常量池。解压后的文件夹中还有一个文件sharedStrings.xml,顾名思义,它维护了Excel工作表中出现的所有字符串,用于工作表之间的共享。每个单独的工作表xml文件只维护使用过的字符串的索引,以减少Excel文件的大小。因此,只要熟悉将TEST.xlsx重命名为TEST.zip并解压后生成的各个文件的用途,即OpenXMLFormats的协议规范,就可以使用任何高级编程语言解析Excel文件。OpenXMLFormats协议定义的各个文件的作用可以在维基百科中找到:https://en.wikipedia.org/wiki...SAPCRM提供了一个工具类来解析基于OpenXMLFormats的Excel文件的内容:cl_xlsx_文档。只需传入Excel文件的二进制内容,工具类就会返回对Excel文件的引用。根据引用的各种GET方法,可以访问OpenXMLFormats协议定义的Excel文件各部分的内容。核心逻辑如下图所示,代码自述,这里不再赘述。当然,开源项目abap2xlsx也是另一种选择:https://github.com/sapmentors...至于SAPFiori应用通过SAPGateway上传附件的技术细节,Jerry会在以后介绍。本文涉及的前后端完整源码请到此链接下载。谢谢阅读。Jerry'sABAP专题Jerry'sABAP,Java和JavaScript炖煮ABAP开发者未来应该学什么Jerry's2017年五一假期:8种经典排序算法的ABAP实现Jerry'sABAP原创技术文章合集300行ABAP代码实现最简单的区块链原型之一使用Java+SAP云平台+SAPCloudConnector调用ABAPOn-Premise系统中的函数在SAP云平台的CloudFoundry环境中消费ABAPOn-PremiseOData服务ABAPvsJava,蛙泳vsfreestyle聊聊C语言和ABAP实战使用ABAPChannel开发一些小工具,提高日常工作效率那些用ABAP做过的无聊事不喜欢SAPGUI?然后尝试使用Eclipse进行ABAP开发。使用VisualStudioCode编写和激活ABAP代码。你的ABAP程序悟佛了吗?下面我们来试试Jerry的小技巧,在SAP云平台ABAP编程环境下编写第一个ABAP程序。SAP官方发布的ABAP编程规范ABAPCodeInspector的隐藏功能你知道吗?还在用ABAP进行SAP产品的二次开发?一起来了解一下这个全新的二次开发理念吧。ABAPNetweaver中的寄生编程语言从SAP社区的一篇博客说起,说说SAP产品命名背后的感受。在云平台ABAP编程环境中,CDS视图暴露为OData服务。使用abapGit在ABAPOn-Premises系统和SAP云平台ABAP环境之间传递代码。使用RestfulABAP编程模型开发一个支持增删改查的Fiori应用。你了解RestfulABAP编程模型系列二:Action和Validation的实现Jerry带你了解RestfulABAP编程模型系列三:云ABAP应用调试如何在SAP云平台ABAP编程环境中消费第三方服务ABAP开发者上云时代已经到来——现在大家可以免费使用SAP云平台ABAP环境的试用版了。学而不思则无用——SAP云平台ABAP编程环境的由来及适用场景如何在SAP云平台上搭建Trident应用基于RestfulABAP编程模型,开发部署一个支持增删改查的Fiori应用。SAP2019TechEdKeyNote解读:云时代SAP从业者如何进行二次开发?ABAP云环境中不能使用的ABAP关键字和语法有哪些?ABAP开发环境终于支持驼峰式ABAP变量名自动格式化。使用ABAP740的新关键字REDUCE来完成一个真实的任务。一段让人瑟瑟发抖的ABAP代码。ABAP内核模式下高效复制内表的方法SAP云应用程序模型开发OData实例当ABAP遇上Prometheus用ABAP绘制可缩放矢量图ABAP开发环境语法高亮那些事SAP错误消息调试的七大武器:让所有错误信息定位SAPGUI中使用ABAP操作Excel收藏夹的几种方法小心,你的一举一动都在系统监控中ABAPCCDEF,CCIMP,CCMAC,CCAU,CMXXX这些都是什么鬼东西?ABAP条件断点实现的三种方式使用SATtrace监控从浏览器打开的SAP应用程序的性能以及调用栈13年ABAP老手的忠告:了解这些基础知识有利于ABAP开发无损SAPABAPNetweaver容器化,不可能完成的任务?SAP产品增强技术回顾SAPAPI开发方法大全浅谈Java与SAPABAP静态代理和动态代理,以及ABAP面向切面编程的尝试SAPABAP应用服务器HTTP响应状态码(StatusCode)JavaList存在于SAPABAP中吗采集工具类?CL_OBJECT_COLLECTION了解ABAP面试题系列:写一组会引起死锁(Deadlock)的ABAP程序SAPABAPNetweaver服务器的标准登录方法详解SAPABAP关键字语法图和ABAP代码自动生成工具CodeComposerSAPABAPSM50的替代用法-ABAP工作进程对数据库表读操作的检测SAPABAP字符变量和字符串变量的字符数知识点,SAPABAP血案组关键字ISBOUND,ISNOTINITIALandISASSIGNED的用法SAPABAP和Java中的弱引用(WeakReference)和软引用(SoftReference)分析SAPAMDP简介-ABAP管理的HANA数据库进程标注你的ABAP对象(Tag)历史上的今天:编程语言空引用中的十亿美元错误ABAP开发工具代码模板及其他一些实用技巧SAPABAP开发工具总结提升开发效率的十大技巧如何在SAPBTP平台ABAP编程环境中使用基于SOAP的Web服务ABAP真的过时了吗?说说ABAP的过去、现在和未来基于abapGit和abaplint的ABAP持续集成实例不使用任何框架,手写纯JavaScript上传本地文件到ABAP服务器Jerry更多原创文章在:《汪子熙》:
