工作原因,每学期都需要提交一个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,下载后安装:

image.png

运行:

image.png

然后新建一个工程,全部选择默认后点击完成:
image.png

点击运行,在控制台中成功的显示了Hi PyCharm,表示Python环境成功。

image.png

读取EXCEL

phtyon只所以广受欢迎,与其有一个非常完善的社区是分不开的,基本上我们想要的都会有包的支持,所以当我们需要读取excel表格时,首先想要的就是去搜索是否有可用的第三方包。

image.png

然后我们得到一个关键的信息: 使用pandas可以对excel进行操作。

安装pandas

和很多优秀的包管理器一样,pip3同样提供了非常友好的包管理功能。所以我们想安装pandas只需要来到pip3的官方网站然后以pandas进行搜索就可以了。

image.png

点击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,安装成功后再次运行示例代码,成功:

image.png

在增加点代码:

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文件的库。

image.png

然后找到了一个名为dbfpy的库来读写dbf库,但查看了一个最新的发布日期是2015年(它有可能只支持python2),于是报着试试看的态度来安装一下。

image.png

(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:
        print
        rec
    print


if __name__ == '__main__':
    testDbf()

然后运行的时候报错了:

    print repr(_rec)
          ^
SyntaxError: invalid syntax

通过查询得知dbfpy最大仅支持在python2.7,而python3中无法使用它。。。

于是开始转战另一个dbf库 ---- dbf,看到它最新发布的日期是2021年,总算是放心了:

image.png

(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()

测试结果:

  0 - 课程编号      : '123         '
  1 - 课程名称      : '123                                     '
  2 - 备注        : '                                                            '
  3 - 简码        : '          '
  4 - 标志        : ' '
  5 - 输入人       : '                    '
  6 - 输入日期      : None
  7 - 审核        : ' '
  8 - 审核人       : '                    '
  9 - 审核日期      : 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
  0 - 课程编号      : '123         '
  1 - 课程名称      : '123                                     '
  2 - 备注        : '                                                            '
  3 - 简码        : '          '
  4 - 标志        : ' '
  5 - 输入人       : '                    '
  6 - 输入日期      : None
  7 - 审核        : ' '
  8 - 审核人       : '                    '
  9 - 审核日期      : None
  0 - 课程编号      : '456         ' 😄😄😄😄😄😄
  1 - 课程名称      : '                                        '
  2 - 备注        : '                                                            '
  3 - 简码        : '          '
  4 - 标志        : ' '
  5 - 输入人       : '                    '
  6 - 输入日期      : None
  7 - 审核        : ' '
  8 - 审核人       : '                    '
  9 - 审核日期      : None

而这,正是我想要的。

收尾

解决了使用python读excel、写dbf的相关技术点后,后面的代码实现便只是逻辑性处理问题了。把代码完成后,再简单保存一份,明年的时候将10个工作日的工作缩短为1个工作日,而相信写代码的时间应该会控制在1个工作日。

这明显是个划的来的买卖。

总结

语言只是工具,我们学习的应该是思想。当接到一个新的跳战时,第一时间应该这个跳转中的技术难点找出来,而从技术难点并解决那一刻开始,整个挑战便开始有了预期完成时间。


潘杰
3.1k 声望245 粉丝