Python 与 Excel 不得不说的事

bfbq9609 8年前
   <p style="text-align:center"><img src="https://simg.open-open.com/show/829097c1bdd2d80acdd5cfe729559b4f.jpg"></p>    <p>数据处理是 Python 的一大应用场景,而 Excel 则是最流行的数据处理软件。因此用 Python 进行数据相关的工作时,难免要和 Excel 打交道。</p>    <p>如果仅仅是要以表单形式保存数据,可以借助 CSV 格式(一种以逗号分隔的表格数据格式)进行处理,Excel 也支持此格式。但标准的 Excel 文件(xls/xlsx)具有较复杂的格式,并不方便像普通文本文件一样直接进行读写,需要借助第三方库来实现。</p>    <p>常用的库是 python-excel 系列:</p>    <p><strong>xlrd、xlwt、xlutils</strong></p>    <ul>     <li> <p>xlrd - 读取 Excel 文件</p> </li>     <li> <p>xlwt - 写入 Excel 文件</p> </li>     <li> <p>xlutils - 操作 Excel 文件的实用工具,如复制、分割、筛选等</p> </li>    </ul>    <p>尽管这是目前被用得最多的 Excel 库,我还是很想吐槽为什么这三个包不能放在一个模块里……另外它们有个缺陷,就是只能处理 xls 文件。如果你想用新版本的 xlsx,可以考虑 openpyxl 和 xlsxwriter。</p>    <p>不过今天只说说这三个。</p>    <h2><strong>安装</strong></h2>    <p>安装的方法没啥特别的,只是得装三遍。可以下载安装包、下载代码压缩包、或者通过 pip 等。可参考 <a href="/misc/goto?guid=4959713438636122976" rel="nofollow,noindex">如何安装 Python 的第三方模块 - Crossin的编程教室 - 知乎专栏</a></p>    <p>如果安装过之前推荐的 anaconda,那么就已经有了 xlrd 和 xlwt,但 xlutils 没有附带在安装包中,使用时仍需另行安装。</p>    <h2><strong>读取</strong></h2>    <p>结合一段简单的代码来看:</p>    <pre>  <code class="language-python">import xlrd  # 打开 xls 文件  book = xlrd.open_workbook("test.xls")  print "表单数量:", book.nsheets  print "表单名称:", book.sheet_names()  # 获取第1个表单  sh = book.sheet_by_index(0)  print u"表单 %s 共 %d 行 %d 列" % (sh.name, sh.nrows, sh.ncols)  print "第二行第三列:", sh.cell_value(1, 2)  # 遍历所有表单  for s in book.sheets():      for r in range(s.nrows):          # 输出指定行          print s.row(r)</code></pre>    <p>测试文件:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/004f7dfcce86fbac9eb687737340c411.png"></p>    <p>输出结果:</p>    <p>表单数量: 2</p>    <p>表单名称: [u'Group.A', u'Group.B']</p>    <p>表单 Group.A 共 7 行 3 列</p>    <p>第二行第三列: 15.0</p>    <p>[text:u'Rank', text:u'Team', text:u'Points']</p>    <p>[number:1.0, text:u'Brazil', number:15.0]</p>    <p>[number:2.0, text:u'Russia', number:12.0]</p>    <p>...</p>    <p>常用的方法:</p>    <ul>     <li> <p>open_workbook 打开文件</p> </li>     <li> <p>sheet_by_index 获取某一个表单</p> </li>     <li> <p>sheets 获取所有表单</p> </li>     <li> <p>cell_value 获取指定单元格的数据</p> </li>    </ul>    <h2><strong>写入</strong></h2>    <p>还是看代码:</p>    <pre>  <code class="language-python">import xlwt  # 创建 xls 文件对象  wb = xlwt.Workbook()  # 新增一个表单  sh = wb.add_sheet('A Test Sheet')  # 按位置添加数据  sh.write(0, 0, 1234.56)  sh.write(1, 0, 8888)  sh.write(2, 0, 'hello')  sh.write(2, 1, 'world')  # 保存文件  wb.save('example.xls')</code></pre>    <p>生成文件:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/9deae3cee4536d96ab75a938e3c6037e.png"></p>    <p>常用的方法:</p>    <ul>     <li> <p>Workbook 创建文件对象</p> </li>     <li> <p>add_sheet 新增一个表单</p> </li>     <li> <p>write 在指定单元格写入数据</p> </li>    </ul>    <h2><strong>修改</strong></h2>    <p>很遗憾,并没有直接修改 xls 文件的方法。通常的做法是,读取出文件,复制一份数据,对其进行修改,再保存。</p>    <p>在复制时,需要用到 xlutils 中的方法。</p>    <pre>  <code class="language-python">from xlrd import open_workbook  from xlutils.copy import copy  # 打开文件  rb = open_workbook("example.xls")  # 复制  wb = copy(rb)  # 选取表单  s = wb.get_sheet(0)  # 写入数据  s.write(0, 1, 'new data')  # 保存  wb.save('example.xls')</code></pre>    <p>修改后文件:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/79900ec9b0205e8cfcbc708812142a1e.png"></p>    <p>特别要注意的是,选取读取表单时,要使用 sheet_by_index,而在选取写入表单时,则要用 get_sheet。不要问我为什么,我也很想知道这么设定的用意何在……</p>    <h2><strong>时间转换</strong></h2>    <p>如果表单中有时间格式的数据,通过处理之后,你会发现时间数据出了差错。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/f920b1ec89c396ff264a719feecf67a8.png"> <img src="https://simg.open-open.com/show/ee087c5772905ddd58d99d69aff50c3b.png"></p>    <p>输出单元格内容:</p>    <p>[number:8888.0, xldate:42613.0]</p>    <p>因为这里 xldate 有自己的格式定义。如果要使用正确的格式,必须转换:</p>    <pre>  <code class="language-python">new_date = xlrd.xldate.xldate_as_datetime(date, book.datemode)</code></pre>    <p>date 是对应单元格的数据,book 是打开的文件对象。</p>    <p>另外,在打开文件时,加上参数 formatting_info=True,可以保证在时间数据在 copy 时保持原样。</p>    <p>写入时间数据,则可通过此方法创建 excel 的时间对象:</p>    <pre>  <code class="language-python">xlrd.xldate.xldate_from_datetime_tuple</code></pre>    <p>或者通过 xlwt.easyxf 指定时间格式:</p>    <pre>  <code class="language-python">style = xlwt.easyxf(num_format_str='D-MMM-YY')  ws.write(1, 0, datetime.now(), style)</code></pre>    <p>具体细节及更多功能这里不展开说明。</p>    <p>以上便是 Python 操作 Excel 文件的一些基本方法。实际使用过程中遇到问题或者需要了解更多功能,永远记住两个词:</p>    <p>RTFM、 <strong>STFW</strong></p>    <p>参考资料:</p>    <p><a href="/misc/goto?guid=4959713438733785117" rel="nofollow,noindex">http://www. python-excel.org/ </a></p>    <p><a href="/misc/goto?guid=4959713438817048723" rel="nofollow,noindex">https:// github.com/python-excel </a></p>    <p><a href="/misc/goto?guid=4959713438899296129" rel="nofollow,noindex">https:// github.com/python-excel /tutorial/raw/master/python-excel.pdf </a></p>    <p> </p>    <p> </p>    <p>来自:https://zhuanlan.zhihu.com/p/22261597</p>    <p> </p>