original作者 : seeksky http://blog.seeksky.tk 转载请注明
最近在做一个项目,有关企业中的CRM的项目
客户的原始资料是存储在excel中的,需要导入到新的基于服务的数据库中
其中有一个很麻烦的位置,就是有一部分文件是存储在嵌入在excel的word之中的(后来才知道所有的office的文件都可以被解析成ole对象,包括excel文档本身和word文档本身),这样使用python读取excel的库xlrt就不行了
在这之间查了很多资料,最后确定使用win32com这个库可以实现这个功能,因为win32com直接调用的office的程序的接口进行操作,和VBA调用的基本一样(后来分析了win32com的代码才发现其实就是用的一样的接口,使用的office的类似java中反射一类的接口,直接通过函数名称调用的一种方式)
在网上查找了一些资料之后,终于把这件事情搞定了,下面就来详细讲一下如何使用python win32com库读取excel中的word文档
——————————–正文———————————
-
安装win32com
这步很简单,但是之前要装python运行环境,我的装的是2.7的所以对应的也是win32com针对2.7运行环境的版本,当然还有64位操作系统与32位操作系统的区别,不过这里的64位和32位指的是你装的python运行环境是32位还是64位的(因为64位操作系统也可以跑32位的python)。
-
读取excel中嵌入的word文档
先贴代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from win32com.client import Dispatch import win32com.client import codecs import sys import os import types class easyExcel: def __init__(self, filename=None): self.xlApp = win32com.client.Dispatch('Excel.Application') self.xlApp.Visible = False if filename: self.filename = filename self.xlBook = self.xlApp.Workbooks.Open(filename) else: print "not found this file" print self.xlBook.Worksheets(1).name for ole_1 in self.xlBook.Worksheets(1).OLEObjects(): ole_1.Activate() ole_obj = ole_1.Object word_obj = ole_obj.Application doc = word_obj.Documents(1) doc.Activate() str1 = doc.Tables(1).Cell(2,1).Range.Text str2=str1.encode('gbk') str2=str2.decode("gbk") |
这里主要分为几个步骤
1.建立excel应用对象
1 2 | self.xlApp = win32com.client.Dispatch('Excel.Application') self.xlApp.Visible = False |
2.读取excel文档
1 2 3 4 5 | if filename: self.filename = filename self.xlBook = self.xlApp.Workbooks.Open(filename) else: print "not found this file" |
3.取出嵌入到excel中的word文档的ole对象
1 2 3 4 5 6 | for ole_1 in self.xlBook.Worksheets(1).OLEObjects(): ole_1.Activate() ole_obj = ole_1.Object word_obj = ole_obj.Application doc = word_obj.Documents(1) doc.Activate() |
4.读取word文档中的内容(这里的例子是读取了文档中一个表格的内容,具体方法参考word中Document对象VBA宏的用法)
1 2 3 | str1 = doc.Tables(1).Cell(2,1).Range.Text str1=str1.encode('gbk') str1=str1.decode("gbk") |
-
遇到的问题总结
在整个过程中遇到的问题很多,因为从来没有人做过相关的工作,在网上也找不到任何相关的资料,在这里把问题总结一下
首先一个是win32com库的相关问题:
1.由于本身这个库使用的是office自带的库的反射机制实现的,所以通过dir()或者是help()这样python自带的帮助函数是看不到你想要用的库函数的声明和帮助的,唯一的办法就是查微软的MSDN
2.由于这个库直接使用office自带的API,所以虽然大部分的版本都能通用,但是部分函数在office不同版本中有所差别,所以兼容性需要在对应的版本上面进行测试
另外一方面是有关字符集的问题:
在读取word文档的时候遇到了一个很奇怪的问题,因为数据库使用的utf-8的字符集,所以需要将本身word中存储的gbk字符集的字符串进行转换,但是转换总是出错,提示类似ascii编码超出128的错误提示,貌似是因为ascii和gbk混合的原因,最后加了一句encode(‘gbk’)再decode(‘gbk’)问题解决,但是具体什么原理,并不清楚。