使用 python 获取excel的作者和最后一次保存者

场景描述

最近有个需求,序号获取excel文件的作者,最后一次保存者,文件创建时间,文件修改时间,用于投标的文件审计。

如下图所示,通过右键excel文件,详细信息里有相关文件的作者,最后一次保存者信息,创建内容时间,最后一次保存的日期。

整个实现过程的话,xlsx格式比较好找,xls的还是费了一番功夫,以此文章记录。

调研过程

一开始一无所知,直接google搜索,搜到一篇利用python读取EXCEL文档中的创建者信息,里面提到了使用python读取xlsx的信息。

经过测试,确实可以获取xlsx格式的信息,但是对于xls的格式会报错。

经过一番搜索,在stackover flow How to retrieve the author of an office file in python?这篇文章中找到了答案,通过hachoir可以获取。

参考demo文章:利用hachoir获取媒体文件元数据
经过测试,可行!

最终代码

xlsx

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
27
28
def get_xlsx_creater_name(self,file_path):
"""获取文件创建者姓名"""
try:
zf = zipfile.ZipFile(file_path)
# use lxml to parse the xml file we are interested in
doc = lxml.etree.fromstring(zf.read('docProps/core.xml'))
attr_nodes = doc.getchildren()
creator='unkown'
editor='unkown'
create_time='unkown'
edit_time='unkown'
for attr_node in attr_nodes:
node_str=str(etree.tostring(attr_node))
if "dc:creator" in node_str:
creator=attr_node.text
elif "cp:lastModifiedBy" in node_str:
editor=attr_node.text
elif "dcterms:created" in node_str:
create_time=attr_node.text
elif "dcterms:modified" in node_str:
edit_time=attr_node.text
# return (attr_nodes[0].text,attr_nodes[1].text,attr_nodes[3].text)
return {'作者':creator,'创建时间':create_time,'修改人':editor,
'最后修改时间':edit_time}
except:
traceback.print_exc()
return {'作者':'unkown','创建时间':'unkown','修改人':'unkown',
'最后修改时间':'unkown'}

xls

1
2
3
4
5
6
7
8
9
10
def get_xls_creater_name(self,file_path):
"""获取xls文件创建者姓名"""
try:
metadata = extractMetadata(createParser(file_path))
return {'作者':metadata.get('author',index=0),'创建时间':metadata.get('creation_date').strftime("%Y-%m-%d %H:%M:%S"),'修改人':metadata.get('author',index=1),
'最后修改时间':metadata.get('last_modification').strftime("%Y-%m-%d %H:%M:%S")}
except:
traceback.print_exc()
return {'作者':'unkown','创建时间':'unkown','修改人':'unkown',
'最后修改时间':'unkown'}

技术总结

xls 和 xlsx 的区别

XLS(Excel97-2003工作表)和XLSX(Excel2007及更高版本工作表)是Excel中两种不同的文件格式。XLS是旧的文件格式,而XLSX是新的文件格式。在Excel2003及更早的版本中,使用的是XLS格式。从Excel2007开始,微软推出了XLSX格式。

在文件格式上,xls和xlsx具有实际的不同,这也导致了获取作者的实现方式不同。

xls 是一个特有的二进制格式,其核心结构是复合文档类型的结构,而 xlsx 的核心结构是 XML 类型的结构,采用的是基于 XML 的压缩方式,使其占用的空间更小。xlsx 中最后一个 x 的意义就在于此。

基于文件格式,xlsx可以基于压缩包zip获取文件的额外信息,而xls是特有二进制,属于媒体文件,需要使用媒体解析库hachoir-metadata。

置于doc格式,则有专门的python-docx库。

hachoir-metadata

如下图官网所示,hachoir-metadata 程序是一个从多媒体文件中提取元数据的工具:视频、图片、声音、档案等,它试图提供尽可能多的信息。

中间的一些错误

pywin32: GetFileVersionInfo returns 1812

在搜索的时候,gpt会提示可以使用pywin32获取属性,其中核心方法为GetFileVersionInfo,但是使用的时候会提示

1
pywin32: GetFileVersionInfo returns 1812

错误,该错误的原因是GetFileVersionInfo只支持 exe及dll文件,并不支持其他格式。

相关文章