将Excel文件(xlsx)中的联系人和电话转换成vcard文件(.vcf),并用pyinstaller打包发布
效果: 将一个Excel表格和该脚本放入同一个文件夹下,运行脚本,输入感兴趣的联系人所在行序号,直接生成vCard文件
步骤:
- 获取同文件夹下的绝对路径(用于pyinstaller打包)
- 读取绝对路径下的xlsx文件数据(要input的:联系人和电话所在列数,以及要输出的数据行数)
- 套用vcf格式,在绝对路径下写入vcf文件
坑很多:
- Mac上打的包在win上运行不成,这一点是改变不了的
- 获取绝对路径是一个很难的活,因为绝对路径要在打包后生效,开始我用filedir=file,在idle中可以获取到路径,打包后exe文件获取失败,最后在这位大神博客中找到了答案link
- 编一个程序很容易,编一个用户友好的程序很难,因为要考虑所有用后可能遇到的情况。。。
from openpyxl import load_workbook
import time
import os
import sys
def read_xlsx(path):
''''''
#return [[changed_name,phone_num],...] list
excel = load_workbook(path)
#读表操作:
# sheet_names = excel.get_sheet_names()#方法得到工作簿的所有工作表
# print(sheet_names)
table = excel.active
print('将对如下sheet进行读取联系人:',table.title,'.如果有误请保存一下表格文件并重启该程序')
result=[]
while True:
try:
in_=input('请输入联系人姓名和电话所在列的数字,逗号分隔,回车确认')
if ',' in in_:
c_name,c_phone=in_.split(',')
else:
c_name,c_phone=in_.split(',')
input_=input('请输入想要读取到手机的联系人起始和终止条目对应的行序号,以逗号分隔,回车确认')
if ',' in input_:
r_begin,r_end=input_.split(',')
else:
r_begin,r_end=input_.split(',')
fuck=int(c_name)
bitch=int(c_phone)
begin=int(r_begin)
end=int(r_end)
break
except :
print('输入错误,重新输入')
#begin read
times=end-begin+1
for time in range(times):
item=[]
name=table.cell(begin+time,fuck)#行列时情况而定!!!!!!!!!!!!!
name='%s'%str(begin+time)+name.value
phone=table.cell(begin+time,bitch).value#行列时情况而定!!!!!!!!!!!!!
item.append(name)
item.append(phone)
result.append(item)
return result,r_begin,r_end
def write2file(result,f_dir,begin='1',end='2'):#write result to f_dir/
f=open('%s/联系人%s到%s.vcf'%(f_dir,begin,end),'w',encoding='utf-8')
for item in result:
name=item[0]
num=item[1]
stencil='BEGIN:VCARD\nVERSION:3.0\nFN:%s\nN:;%s;;;\nTEL;TYPE=VOICE,CELL,pref;VALUE=text:%s\nUID:69E7CCC1-7AC2-F741-865D-C9BDF3AA763F\nEND:VCARD\n'%(name,name,num)
f.write(stencil)
f.close()
print('done!')
time.sleep(5)
def read_xlsx_name(abs_dir):#得到绝对路径里面的所有xlsx文件名列表【file1,file2...】
gener=os.walk(abs_dir)
try:
self_=gener.__next__()
except StopIteration:
print(abs_dir)
print(gener)
input('读取路径错误')
pass
obj_file=[]
for f in self_[2]:
if os.path.splitext(f)[1]=='.xlsx':
obj_file.append(f)
#处理._文件名.xlsx的情况
def remove():
for i in obj_file:##################################['~$test.xlsx', 'test.xlsx']
if i[2:] in obj_file:
obj_file.remove(i)
#print('remove')
remove()
if len(obj_file) != 1:
remove()
if len(obj_file) != 1:
print('该文件夹下没有表格文件或多于一个表格文件',obj_file)
time.sleep(20)
os._exit(0)
return obj_file[0]
if __name__=='__main__':
#获得绝对路径
abs_dir = os.path.dirname(os.path.realpath(sys.executable))
#print(abs_dir,'--1')
#获得同级文件夹内的xlsx文件名
obj_file=read_xlsx_name(abs_dir)
#print(obj_file)
result = read_xlsx('%s/%s'%(abs_dir,obj_file))
#input('result%s'%result[0][0][0])
information=result[0]
begin=result[1]
end=result[2]
#input('Now, let us write2file')
write2file(information,abs_dir,begin,end)
好了,一个喜欢编程的非专业人员想要编一个程序刚开始真的很难,因为身边没有人可以讨论的。这些代码我断断续续写了三天。。。但是每当解决了一个bug带给我的喜悦真的是发自内心的。真后悔当初没进软件工程专业。佛不渡我人自渡,且行且行且珍惜吧。