excel數據處理工具開發小記

給兄弟幫個忙

因爲新冠疫情封閉在家,一直沒有做過什麼像樣的事情。同學T兄經常會跟我交流技術,某天他給我留言說能否幫他做一個excel文件處理的小工具?想想人家是奮戰在抗疫前線的,我一介草民怎能不盡一份綿薄之力呢,於是慨然應允。

首先是聊需求,要將一個想法變成一個具體的軟件,最重要的是知道對方想要什麼。幸好需求不復雜,就是可以將excel表格中的數據按列進行去重,然後還可以多列之間比較取交集。之前T兄是直接在excel裏面操作,但數據量到了40萬條以後運算速度奇慢無比。他甚至不得不分表進行處理。

當然,之所以會這麼做也是疫情發展太快,既有系統來不及升級,只得人肉手工幹了。不消說,excel的定位是辦公場景, 把這當數據庫來使顯然不是它的強項。所以我最初的想法也比較簡單,就是能夠把excel的數據以映射的關係導入到一個數據庫中,再進行運算就能滿足要求了。

於是我給出的答覆是可以實現,需要T兄給我一個示例文件,我就可以開工了。

技術選型

其實我在之前的工作中並沒有做過這方面的工作,印象中也只是記得有同事用python處理過excel文件。我本來也打算用python語言來實現解析,然後導入數據庫中,再做一個操作界面就可以了。

在進行一番搜索與瞭解之後,我發現javascript就有一個第三方庫能夠做excel的解析工作,而且代碼的成熟度也不錯。這下我又有了新的想法,現在的考慮就轉變成了我可以將解析工作放在web的前端上進行,然後通過http方式將數據傳輸至後臺服務。至於後臺服務,我想到的是用go語言來開發。

不過後來的事實證明,前端做excel解析還是有問題,一旦數據量超過40萬行,頁面就出現崩潰現象了。因此在緊急修復時還是選擇了一個go語言實現的excel解析庫。測試數據量50萬行也可以成功,不過時間需要一分鐘左右。不管怎樣,保證能先工作起來更重要。

這麼考慮的原因,一是平臺兼容性。web的好處就是前端可以運行不同平臺的瀏覽器中,例如PC與移動設備,windows與linux。只要選擇一個兼容性好的前端UI庫,使用則不必受到平臺的限制了。

二是可擴展性。前端與後臺相互獨立,這樣將來後臺服務要換用其它開發語言也不影響前端。後臺也可以靈活選擇數據庫產品,例如性能要求不高的可以就在單機上用sqlite,用戶多而且數據量大的則可以部署一套mysql集羣。

三是部署的便利性。go語言編譯得到的就是一個對環境最小依賴的可執行文件,我不用操心對方的宿主機上是否缺失什麼運行時庫之類的問題。而諸如python這樣的腳本語言則不能忽視運行時環境這個問題。

所以最終的開發技術:

  1. 前端:html, css, javascript;
  2. 後臺:go語言

依賴的第三方庫:

名稱 功能 鏈接
layui 一個簡單好用的前端框架 https://www.layui.com/
beego 基於go語言的一款web服務開發套件 https://beego.me/
SheetJS javascript語言開發的一套excel文件解析、生成庫 https://github.com/SheetJS/sheetjs
tealeg/xlsx go語言開發的excel文件解析與生成工具 https://github.com/tealeg/xlsx

架構設計

採用BS部署結構,優點是前端UI操作界面只依賴於瀏覽器的技術性能,跨平臺兼容性會比較好。在前期實現中,將excel解析的工作完全放在了前端進行處理。但在真實環境中使用發現有問題,因爲excel文件數據行超過40萬時則頁面出現崩潰現象。因此改爲採用後端解析的方式,實際測試解析50萬行數據的時長在一分鐘左右。經過與T兄的溝通之後,他表示可以接受,於是就使用後端解析的方法。

前端功能模塊

  1. 原始excel文件加載與解析。可批量導入文件,支持文件解析功能,生成json數據上傳至後端服務;
  2. 任務管理組件。可查看計算任務的狀態,並將計算結果導出爲excel文件;
  3. 計算結果預覽組件。展示計算之後的結果數據,支持分頁查看;
  4. 據手機號顯示歸屬地。

後端功能模塊

  1. 數據存儲與檢索管理。接收前端上傳的原始數據並將json文本轉換爲對象結構存儲,並可根據文件名進行檢索;
  2. 去重計算。對指定字段進行數據比較之後,生成無重複數據的記錄集;
  3. 碰撞計算。比較多個字段,找出所有值相同的數據,生成記錄集;
  4. 數據輸出。可根據前端的請求,按照分頁規則以json封裝給出相應的數據集;
  5. 據手機號計算歸屬地。調用百度提供的公共API接口,可根據手機號計算出歸屬地並返回。
前端
後臺服務
原始文件管理
計算結果預覽
據手機號顯示歸屬地
數據輸出
調度處理
數據存儲與檢索
任務管理
去重計算
碰撞計算
據手機號計算歸屬地

工程管理:Gitea與每週交付

雖說是個小小的工具,但咱在工作上不能馬虎。於是選擇了一款輕量級的git類管理工具:gitea。它的下載地址是https://github.com/go-gitea/gitea/。這也是一款go語言開發的web式服務,開箱即用,配置好地址端口以後直接訪問可用。它具備git倉庫管理,支持工單管理,有類似知識wiki的百科功能。可以說小型團隊基於gitea是可以很好地實現源碼管理和工程協作的。

在開發方法上我選擇了遵從scrum方法論。即採用小步迭代,快速實現能工作的軟件。我將版本發佈頻率定爲每週一次,這樣迫使我在一開始必須聚焦於最核心的功能。所以在和T兄聊需求時,他說了很多關於這款工具的設想和要求,但我最後還是要讓他告訴我最需要什麼功能。他的回答是數據去重,因此第一週發佈的版本包括的功能是前端解析excel,數據按列去重,結果存爲excel。這個版本定爲dev_v1.0。

第一個版本提交後,T兄表示滿足需求。於是我從主幹master分支創建新分支dev_v1.1,進行數據碰撞的開發工作。v1.1版本在增長新功能的同時,也將前端javascript部分的代碼進行了重構。減少了意義不明的冗餘部分,採用更具描述性的方法名。去重和碰撞也可以在多表多字段之間進行,此版本達到了可用的要求。

我將v1.1版本合併到master分支,再從master分支創建dev_v1.2分支,用於實現據手機號顯示歸屬地功能。但在開發期間,T兄告知程序在解析一個39萬行的excel文件出現頁面崩潰。我立即從master分支創建fix_v1.1.1分支,進行bug修復工作。當問題解決後,我將v1.1.1分支合併到master分支,發佈版本,提交v1.1.1程序給T兄。

當dev_v1.2開發完畢時,我首先從master做了一次合併到dev_v1.2。在手工解決完衝突之後,再進行一次自動化單元測試,確認結果無誤後將v1.2合併到master分支。接下來就是發佈新版本,提交v1.2程序給T兄。

時間 版本 功能
第一週 dev_v1.0 支持解析excel文件; 實現字段去重; 實現處理後結果保存爲excel文件。
第二週 dev_v1.1 支持多表多字段碰撞; 支持多表多字段去重; 調整makefile支持多平臺編譯。
第三週 fix_v1.1.1 支持處理超過50萬條記錄的excel文件; 實現post文件上傳; 使用go mod方式支持第三方包管理。
第四周 dev_v1.2 實現據手機號顯示歸屬地; 合併dev1.1.1分支; 優化前端與後端的部分代碼。

測試驅動的開發方式

在這個小小的項目中,我在一開始也還沒有完全遵循測試驅動開發(以下簡稱爲TDD)原則。雖然我一直想探索TDD這種方式可以給軟件開發帶來多大的增益,但一上手習慣性地就直接從實現業務邏輯開始了。一直到v1.1版時纔有意識地強迫自己先寫單元測試再實現業務邏輯。

一旦進入了TDD開發方式時,適應的時間比我想象的還要短一些。TDD能夠帶來最直觀的好處,確實就像那些佈道者所宣稱的那樣,對自己的代碼有了充分的信心,這種感覺在以前是不容易體會的。得益於go語言本身就內置了一個輕量級的單元測試框架,在語言層面沒有任何阻礙,編寫完一些剛好夠測試的代碼,就執行一次go test命令,方便快捷。

TDD的開發原則其實很簡潔,但難處在於持之以恆地堅持它,可以說是知易行難的典型。

  1. 在編寫好失敗的單元測試之前,不編寫任何業務代碼;

  2. 只要有一個單元測試執行失敗,就不再寫測試代碼,必須將當前的問題解決掉;

  3. 業務代碼恰好能讓當前失敗的單元測試通過即可,不用多寫。

    當開發工作進入到需要緊急解決大數據量的讀取問題時,TDD構建出來的單元測試集大大縮短了調試時間,這應該說是最大的收穫了。因爲解析excel數據從前端挪到了後端,數據處理的流程與系統的結構都發生了變化,代碼裏改動的部分是比較多的。但因爲有了前期積累的單元測試集,運行一次go test只要發現有之前的測試用例執行失敗,則立即停下來解決之後再放心地往下進行新功能開發工作。

結語

疫情以來在家的這段時間,得以靜下心來學習很多軟件工程、軟件架構方面的知識。發現很多以前思考不清楚的問題,在這段時期裏都迎刃而解了,這的確是一種很奇妙的感覺。想來自己在以前忙碌的工作中其實是一直被緊迫的任務攆着走,根本就沒有思考的空閒。所以說把一個人廢掉的最好方式真的是讓他忙得沒時間學習。

除了思考這些關於技術的問題,我也在想自身的價值是什麼?這個答案我覺得應該是能夠爲有需要的人創造出他們所需要的價值,這便是自身價值得以體現的最好方式了。而人如果一旦陷入在爲了謀生而不得不爲之的打工心理狀態中,那麼即使做了很多很有用的事情,也會迷失在疲憊與迷茫中。

我想在以後的工作和學習過程中,爲有需要的人創造價值將會是我的一個信條,希望我能夠幫助到更多人吧。

項目開源地址: ExcelCompute

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章