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

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