工作原因, 每学期都需要提交一个 DBF 文件给上级部门, 而这个 DBF 中的大多数信息都是在特定的软件中使用添加原本在 Excel 中的数据, 最后由软件生成的.
由于每年都需要弄一次, 每位同事都需要弄一次, 整体上会花费 2 * 5 = 10 人 / 天的工作量 (运气好的话), 所以决定用自动化来实现一下.
由于需求不大, 又是用于特定的场合下, 所以对 UI 没有要求. 决定尝试使用 (人生苦短, 我用)python3 来自动化一下.
安装
在 macos 下由于 brew 的加成, 使其安装相关的软件都比较简单, 当然了当提是我们需要有一个还不错的网络环境.
- panjie@panjies-iMac web % brew install python
- ==> Downloading
- ....
- ==> python@3.9
- Python has been installed as
- /usr/local/bin/python3
- Unversioned symlinks `python`, `python-config`, `pip` etc. pointing to
- `python3`, `python3-config`, `pip3` etc., respectively, have been installed into
- /usr/local/opt/python@3.9/libexec/bin
- You can install Python packages with
- pip3 install <package>
- They will install into the site-package directory
- /usr/local/lib/python3.9/site-packages
- tkinter is no longer included with this formula, but it is available separately:
- brew install python-tk@3.9
- See: https://docs.brew.sh/Homebrew-and-Python
看到上述结果, 就表示 python 安装好了. 安装好后的提示信息很重要, 需要认真阅读一下. 比如我们使用上述命令安装的是 python3, 然后它的包管理器叫 pip3 等.
如果我们不小心忘记看相当提示的话, 其实还可以来到 brew 的官方网站, 找到相应的包的地址, 那个地址上也会有相应包安装成功后的提示.
这装完成后打开 shell, 运行 phtyon3 --version
- panjie@panjies-iMac Web % python3 --version
- Python 3.9.5
安装成功.
使用 python
使用 python 前我还是喜欢先下载一款得手的 IDE, 比如 pycharm, 下载后安装:
运行:
然后新建一个工程, 全部选择默认后点击完成:
点击运行, 在控制台中成功的显示了 Hi PyCharm, 表示 Python 环境成功.
读取 Excel
phtyon 只所以广受欢迎, 与其有一个非常完善的社区是分不开的, 基本上我们想要的都会有包的支持, 所以当我们需要读取 Excel 表格时, 首先想要的就是去搜索是否有可用的第三方包.
然后我们得到一个关键的信息: 使用 pandas 可以对 Excel 进行操作.
安装 pandas
和很多优秀的包管理器一样, pip3 同样提供了非常友好的包管理功能. 所以我们想安装 pandas 只需要来到 pip3 的官方网站然后以 pandas 进行搜索就可以了.
点击 User Guide 便进行了说明页面, 按此页面的说明开始安装 panda.
按说明我们执行 python3 -m pip install pandas 便开始了 pandas 的安装:
- panjie@panjies-iMac Web % python3 -m pip install pandas
- Collecting pandas
- Downloading pandas-1.3.3-cp39-cp39-macosx_10_9_x86_64.whl (11.6 MB)
|███▍ | 1.2 MB 53 kB/s eta 0:03:15
实际上 PIP 的官方站点是 https://pypi.org/ , 在下文中将访问该站点来查询安装包.
由于我们是首次安装, 所以包管理器中基本上什么包都没有, 此时便需要耐心的等待下载. pandas 以及其依赖的包全部安装完成后, 将得到以下安装成功的提示:
- Installing collected packages: six, pytz, python-dateutil, numpy, pandas
- Successfully installed numpy-1.21.2 pandas-1.3.3 python-dateutil-2.8.2 pytz-2021.1 six-1.16.0
- WARNING: You are using pip version 21.1.1; however, version 21.2.4 is available.
- You should consider upgrading via the '/usr/local/opt/python@3.9/bin/python3.9 -m pip install --upgrade pip' command.
测试
按 pandas 的入门文档或是随便由网上找一些示例代码, 使用 pandas 来读取任意的 Excel 来测试一下:
- import pandas
- def test():
- pandas.read_excel('/Users/panjie/sync/work/task.xlsx')
- if __name__ == '__main__':
- test()
运行结果:
ImportError: Missing optional dependency 'openpyxl'. Use pip or conda to install openpyxl.
提示我说需要安装 openpyxl 这个模块
插曲: 安装完 pandas 后我并没有重启 pycharm, 此时 pycharm 提示我说没有找到 pandas. 此时直接尝试使用 pycharm 提示中的 install package 直接快速解决了找不到的问题. 至于为什么会这样, 没有研究.
安装 openpyxl
有了安装 pandas 的经验, 安装 openpyxl 便显得非常简单了.
- panjie@panjies-iMac Web % python3 -m pip install openpyxl
- Collecting openpyxl
- Downloading openpyxl-3.0.8-py2.py3-none-any.whl (244 kB)
|████████████████████████████████| 244 kB 926 kB/s
- Collecting et-xmlfile
- Downloading et_xmlfile-1.1.0-py3-none-any.whl (4.7 kB)
- Installing collected packages: et-xmlfile, openpyxl
- Successfully installed et-xmlfile-1.1.0 openpyxl-3.0.8
- WARNING: You are using pip version 21.1.1; however, version 21.2.4 is available.
- You should consider upgrading via the '/usr/local/opt/python@3.9/bin/python3.9 -m pip install --upgrade pip' command.
使用 shell 安装后, pycharm 仍然报错. 这可能是由于 pycharm 与 shell 是两个作用域吧. 于是在 pycharm 中打开 Terminal, 然后继续运行 python3 -m pip install openpyxl, 安装成功后再次运行示例代码, 成功:
在增加点代码:
- import pandas
- def test():
- xxx = pandas.read_excel('/Users/panjie/sync/work/task.xlsx')
- print(xxx)
- if __name__ == '__main__':
- test()
打印一下:
/Users/panjie/PycharmProjects/pythonProject/venv/bin/python /Users/panjie/PycharmProjects/pythonProject/main.py
方案计划名 方案课组 课程号 ... 备注 备注. 1 类型
0 软件 专业选修课 xxx ... 2~16 NaN 1
1 计算机 专业必修课 xxx ... 3~17 NaN 1
2 计算机 专业必修课 xxx ... 3~17 NaN 1
3 计算机 专业必修课 xxx ... 13*2+11*2 NaN 1
4 软件 学科平台课程 xxx ... 4~16 NaN 1
DBF 读写
想处理成可用的 dbf 文件, 则需要对使用软件生成的 DBF 文件进行分析. 这时候则需要一个 python 下可以读写 dbf 文件的库.
然后找到了一个名为 dbfpy 的库来读写 dbf 库, 但查看了一个最新的发布日期是 2015 年 (它有可能只支持 python2), 于是报着试试看的态度来安装一下.
- (venv) panjie@panjies-iMac pythonProject % python3 -m pip install dbfpy
- Collecting dbfpy
- Downloading dbfpy-2.3.1.tar.gz (19 kB)
- ...
- Installing collected packages: dbfpy
- Successfully installed dbfpy-2.3.1
测试
同样, 我们按官方文档的示例代码来尝试进行读库:
- import pandas
- from dbfpy import dbf
- def test():
- xxx = pandas.read_excel('/Users/panjie/sync/work/task.xlsx')
- print(xxx)
- def testDbf():
- db = dbf.Dbf("/Users/panjie/sync/work/x_kck.DBF")
- for rec in db:
- rec
- if __name__ == '__main__':
- testDbf()
然后运行的时候报错了:
- print repr(_rec)
- ^
- SyntaxError: invalid syntax
通过查询得知 dbfpy 最大仅支持在 python2.7, 而 python3 中无法使用它...
于是开始转战另一个 dbf 库 ---- dbf, 看到它最新发布的日期是 2021 年, 总算是放心了:
(venv) panjie@panjies-iMac pythonProject % python3 -m pip install dbf
安装成功后找到其官方文档, 进行测试:
- import pandas
- from dbf import *
- import dbf
- def test():
- xxx = pandas.read_excel('/Users/panjie/sync/work/task.xlsx')
- print(xxx)
- def testDbf():
- db = dbf.Table(filename='/Users/panjie/sync/work/x_kck.DBF')
- db.open(dbf.READ_WRITE)
- for record in db:
- print(record)
- db.close()
- if __name__ == '__main__':
- testDbf()
测试结果:
- 课程编号 : '123'
- 课程名称 : '123'
- 备注 : ' '
- 简码 : ' '
- 标志 : ' '
- 输入人 : ' '
- 输入日期 : None
- 审核 : ' '
- 审核人 : ' '
- 审核日期 : None
测试写 DBF
读文件需要一行一行的来读, 而写文件只需要追加记录即可:
- def testDbf():
- db = dbf.Table(filename='/Users/panjie/sync/work/x_kck.DBF')
- db.open(dbf.READ_WRITE)
- db.append({'课程编号': '456'})
- for record in db:
- print(record)
- db.close()
上述代码, 我尝试加入了 456 的记录, 加入记录后再次打印记录值:
/Users/panjie/PycharmProjects/pythonProject/venv/bin/python /Users/panjie/PycharmProjects/pythonProject/main.py
- 课程编号 : '123'
- 课程名称 : '123'
- 备注 : ' '
- 简码 : ' '
- 标志 : ' '
- 输入人 : ' '
- 输入日期 : None
- 审核 : ' '
- 审核人 : ' '
- 审核日期 : None
- 课程编号 : '456'
- 课程名称 : ' '
- 备注 : ' '
- 简码 : ' '
- 标志 : ' '
- 输入人 : ' '
- 输入日期 : None
- 审核 : ' '
- 审核人 : ' '
- 审核日期 : None
而这, 正是我想要的.
收尾
解决了使用 python 读 Excel, 写 dbf 的相关技术点后, 后面的代码实现便只是逻辑性处理问题了. 把代码完成后, 再简单保存一份, 明年的时候将 10 个工作日的工作缩短为 1 个工作日, 而相信写代码的时间应该会控制在 1 个工作日.
这明显是个划的来的买卖.
总结
语言只是工具, 我们学习的应该是思想. 当接到一个新的跳战时, 第一时间应该这个跳转中的技术难点找出来, 而从技术难点并解决那一刻开始, 整个挑战便开始有了预期完成时间.
来源: https://segmentfault.com/a/1190000040674407