从手机导出通讯录,是一个vcf格式的文件,无法直接导入excel进行处理,所以我用python转换成csv格式
预处理
但是这段代码并不完善,比如vcf文件中有时会出现跨行的数据,我的代码就不能处理,需要提前手动将换行数据合并为一行,并删除行末行首连接处中间多余的等号
上图就是有跨行数据,要先手动合并成一行,然后中间有两个等号==,删掉一个留下一个,变成这样:
转换过程
转换过程中会自动识别vcf文件中的所有字段,把每个字段转换成csv的一列
如果vcf的一个字段包含多条数据,则转换为csv的一列时,多条数据合并为一条,中间用分号分隔,如:
TEL;CELL:13012345678
TEL;CELL:13112345678
将被转换为csv中的一列,列名为tel,单元格的内容为13012345678;13112345678
后续处理
转换结束后会生成一个csv文件,因为代码中字符集没有处理好,所以如果通过双击csv文件的方式打开excel,有时显示乱码,可以先打开excel软件,点击数据-来自文件-选中csv文件。注意分隔符选择逗号。
代码:
import os
import vobject
import csv
# 读取vcf文件,输出csv文件
def work(inputFile, outputFile):
# Reading the vcf file
with open(inputFile, 'r', encoding='gbk') as f:
contacts = f.read()
# 读取1条记录
# vcard = vobject.readOne(contacts)
# print(vcard)
# print(vcard.behavior)
# print(vcard.contents['tel'])
# print(type(vcard.contents))
# keys = vcard.contents.keys()
# print(keys)
try:
# 获取所有vcard的keys
index = 0
allKeys = []
vcards = vobject.readComponents(contacts)
for vcard in vcards:
index += 1
# print('==========')
# print(index)
# 取出所有的key
keys = vcard.contents.keys()
# print(keys)
for key in keys:
if key not in allKeys:
allKeys.append(key)
# valueCount = len(vcard.contents[key])
# if valueCount > 1:
# print(f'key:{key},value:{vcard.contents[key]},type:{type(vcard.contents[key])},count:{valueCount}')# 全是list类型
print(f'allKeys:{allKeys}')
# 再次遍历,按keys提取数据,写入csv
with open(outputFile, 'w', newline='', encoding='gbk') as f:
writer = csv.writer(f)
writer.writerow(allKeys)
vcards = vobject.readComponents(contacts)
for vcard in vcards:
row = []
for key in allKeys:
if key in vcard.contents.keys():
content = vcard.contents[key]#每个content都是list类型
tmp = ''
for item in content:
if item.value is not None:
tmp += str(item.value) + ';'
row.append(tmp[:-1])
# row.append(tmp)
else:
row.append('')
print(row)
writer.writerow(row)
except Exception as e:
print("An error occurred:", e)
if '__main__' == __name__:
# Set the working directory to the current file's directory
os.chdir(os.path.dirname(os.path.abspath(__file__)))
inputFile = 'contacts.vcf'
outputFile = 'output.csv'
work(inputFile, outputFile)