javascript
使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 ABAP 服务器并进行解析
這是 Jerry 2021 年的第 71 篇文章,也是汪子熙公眾號總共第 348 篇原創文章。
Jerry 之前發布過一篇文章?不使用任何框架,手寫純 JavaScript 實現上傳本地文件到 ABAP 服務器,之后不少朋友留言,提出的問題概括為以下兩類:
(1) 客戶端通過 multipart/form-data 格式發送的數據,ABAP 端除了像 Jerry 文章采取字符串解析這種比較繁瑣的方式處理外,還有其他方法嗎?
(2) 能否上傳二進制文件比如 Excel 到 ABAP 并進行解析?
本文就來解答這兩個問題。
使用 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 文件:
用來測試的本地 PDF 文件:PDF.pdf,大小為 30129 字節。
內容如下:
本地用來測試的 Excel 文件:TEST.xlsx,內容如下:
點擊 HTML 頁面上傳文件的超鏈接,在 Chrome 開發者工具觀察到 HTTP POST 請求的負載,包含了 PDF 和 Excel 兩個 input 控件包含的二進制流(stream):
點擊 view source,查看 multipart/form-data 數據明細:
我們仍然可以在 Chrome 開發者工具里觀察到上傳的 PDF 和 Excel 的文件名和 Content-Type 即文件類型。同前文上傳文本文件的例子不同,這里無法看到兩個文件的二進制內容——這些二進制內容可以在 ABAP 服務器端調試器里觀察到。
以上傳的 PDF 文件為例,在 ABAP 服務器端接收到的 form-data 數據,如下圖所示,綠色高亮區域即為上圖 Chrome 開發者工具里能夠觀測到的文件名 PDF.pdf 和文件類型 application/pdf, 而%PDF-1.4# 開頭的,就是 PDF 文件的二進制內容。
準確的說,PDF 格式是文本和二進制流的混合模式。用文本編輯器打開 PDF.pdf, 能看到其文件頭部包含的是文本字符描述的文件元數據,比如該文件的創建和修改時間,創建該文件的工具名等等,后半部分才是二進制流。
現在已經有很多開源工具比如 JavaScript 庫可以用來生成和解析 PDF 文件了,感興趣的朋友可以在搜索引擎里搜索 Jerry 這幾篇文章:
- 使用 ABAP 和 JavaScript 代碼生成 PDF 文件的幾種方式
- 使用 JavaScript 將當前頁面保存成 PDF,支持圖片和文字的保存
- PDF 文件如何轉成 markdown 格式
對于上傳到 ABAP 服務器的 PDF 文件的文件名,我們仍然采取和前一篇文章同樣的方式解析,從下圖紅色矩形框中的字符串中提取。
而對于上圖綠色高亮的 PDF 的二進制數據,CL_HTTP_REQUEST 提供了相應方法來提取。關鍵代碼如下圖所示:
當 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 銷售訂單的附件。
創建好的 PDF 和 Excel 附件在 SAP CRM 系統里顯示如下:
打開這兩個附件,確保上傳之后,其內容同本地文件完全一致:
如何使用 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 內:
上圖高亮的 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 文件的尺寸。
因此,只要熟悉了 TEST.xlsx 重命名為 TEST.zip 并解壓之后生成的每一個文件的用途,即 Open XML Formats 的協議規范,就可以使用任何高級編程語言解析 Excel 文件。
可以在 WikiPedia 里找到 Open XML Formats 協議定義的每個文件的作用:
https://en.wikipedia.org/wiki/Office_Open_XML_file_formats
SAP CRM 提供了一個工具類,基于 Open XML Formats 解析 Excel 文件內容:cl_xlsx_document.
只需將 Excel 文件的二進制內容傳入,該工具類即返回一個 Excel 文件的引用,根據該引用的各種 GET 方法,即可訪問到 Excel 文件內由 Open XML Formats 協議定義的各個部分的內容。
核心邏輯如下圖所示,代碼都是自描述的,這里不再贅述。
當然,開源項目 abap2xlsx 也是另一個選擇:
https://github.com/sapmentors/abap2xlsx
至于 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這個小技巧
-
在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的原創文章,盡在:“汪子熙”:
總結
以上是生活随笔為你收集整理的使用 JavaScript 上传 PDF 和 Excel 等二进制文件到 ABAP 服务器并进行解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 空军一号07和gs的区别
- 下一篇: transportation什么意思 t