美文网首页
[py052] 通讯录vcf与csv互转

[py052] 通讯录vcf与csv互转

作者: Andy计算机专业 | 来源:发表于2019-12-02 19:05 被阅读0次
    Coding is better than boring.
    与其无聊倒不如写点东西,或许会少点辜负时光。
                      ---Mon,Dec 2,2019 Andy
    

    前言:

    有时候需要将vcf和csv互转,但众里寻他千百度,始终找不到一个通用且便捷的转换方式。所以自己写一个吧!自己以后用方便,刚好需要用的朋友遇到也方便。
    下面来一起看看要怎么弄。

    首先、两种文件的格式有什么区别?


    1.一句话说完。“csv以逗号分隔,vcf有一堆东西,看着好复杂。”
    2.csv可以excel打开直接编辑
    3.vcf的格式也是很清晰的,如图。

    思路:越野越好

    1.vcf转csv,把起始标志、版本等全部去掉。
    2.csv转vcf,把那一堆加上。

    废话少说,上代码

    """
    @title:通讯录vcf与csv互转
    @filename:vcf22csv_ok.py
    """
    import os
    import quopri
    import re
    
    
    def get_fpath_fname_fextension(file):
        """返回文件路径、文件名、拓展名"""
        (fpath, temp_fname) = os.path.split(file)
        (fname, fextension) = os.path.splitext(temp_fname)
        return fpath, fname, fextension
    
    
    def vcf2csv(vcf_filename):
        """vcf格式文件转换为csv格式文件"""
        # 1.读取vcf文件
        with open(vcf_filename, 'r', encoding='utf-8') as f:
            try:
                ftext = f.read()
            finally:
                f.close()
        # 2.正则替换清洗数据
        re_dic = {
            r"(EMAIL;)(.*)(\n)": "",
            r"(ADR;)(.*)(\n)": "",
            r"(ORG;)(.*)(\n)": "",
            r"(NOTE:)(.*)(\n)": "",
            r"(\n)(VERSION:2.1)": "",
            r"\nEND:VCARD\nBEGIN:VCARD": "",
            r"\nEND:VCARD": "",
            r"BEGIN:VCARD\n": "",
            r"(;;;)([\s\S]*?)(TEL;CELL:)": ",",
            r"N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:": "",
            r"(\nTEL;)(.*?)(:)": ",",
            r"N:;": "",
            r";": "",
            r" ": "",
            r"=\n": ""
        }
        for re_rule, replace_str in re_dic.items():
            p1 = re.compile(re_rule)
            ftext = p1.sub(replace_str, ftext)
        # 3.解码quopri编码
        ftext = quopri.decodestring(ftext).decode('utf-8', "ignore").replace(" ", "")
        ftext = "".join([s for s in ftext.splitlines(True) if s.strip()])
        # 4.保存cvs文件
        csv_str = f'姓名,手机\n{ftext}'
        fname = get_fpath_fname_fextension(vcf_filename)
        with open(f'{fname[0]}{fname[1]}.csv', "w", encoding="utf-8") as f:
            try:
                f.write(csv_str)
            finally:
                f.close()
    
    
    def csv2vcf(csv_filename):
        """csv格式文件转换为vcf格式文件"""
        # 1.读取csv文件
        with open(csv_filename, 'r', encoding='utf-8') as f:
            ftext_list = f.readlines()
            f.close()
        # 2.将cvs转换为vcf格式
        vcards = ''
        for line in ftext_list[1:]:
            tel_numbers = ''
            name_tel_list = line.strip().split(',')
            if name_tel_list[0]:
                tel_name = name_tel_list[0]  # 姓名
                for tel in name_tel_list[1:]:  # 电话
                    tel_numbers += f'TEL;CELL:{tel}\n'
                vcard = f'BEGIN:VCARD\nN:{tel_name}\n{tel_numbers}END:VCARD\n'
                vcards += vcard
        # 3.保存转换后的vcf格式文件
        fname = get_fpath_fname_fextension(csv_filename)
        with open(f'{fname[0]}{fname[1]}.vcf', "w", encoding="utf-8") as f:
            try:
                f.write(vcards)
            finally:
                f.close()
    
    
    def vcf22csv(file):
        if not os.path.isfile(file):
            print("文件不存在")
        else:
            a = get_fpath_fname_fextension(file)[2]
            if a == ".csv":
                csv2vcf(file)
                print("此文件为csv文件,已生成vcf文件")
            elif a == ".vcf":
                vcf2csv(file)
                print("此文件为vcf文件,已生成csv文件")
            else:
                print("请选择正确的csv文件或者vsf文件")
    
    
    if __name__ == "__main__":
        filename = "vcards.csv"
        vcf22csv(filename)
        pass
    
    

    GUI版

    """
    @title:通讯录vcf与csv互转
    @filename:vcf22csv_gui_ok.py
    """
    import os
    import quopri
    import re
    import tkinter as tk
    import tkinter.filedialog as tk_file
    import tkinter.messagebox as msg
    
    
    def get_fpath_fname_fextension(file):
        """返回文件路径、文件名、拓展名"""
        (fpath, temp_fname) = os.path.split(file)
        (fname, fextension) = os.path.splitext(temp_fname)
        return fpath, fname, fextension
    
    
    def vcf2csv(vcf_filename):
        """vcf格式文件转换为csv格式文件"""
        # 1.读取vcf文件
        with open(vcf_filename, 'r', encoding='utf-8') as f:
            try:
                ftext = f.read()
            finally:
                f.close()
        # 2.正则替换清洗数据
        re_dic = {
            r"(EMAIL;)(.*)(\n)": "",
            r"(ADR;)(.*)(\n)": "",
            r"(ORG;)(.*)(\n)": "",
            r"(NOTE:)(.*)(\n)": "",
            r"(\n)(VERSION:2.1)": "",
            r"\nEND:VCARD\nBEGIN:VCARD": "",
            r"\nEND:VCARD": "",
            r"BEGIN:VCARD\n": "",
            r"(;;;)([\s\S]*?)(TEL;CELL:)": ",",
            r"N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:": "",
            r"(\nTEL;)(.*?)(:)": ",",
            r"N:;": "",
            r";": "",
            r" ": "",
            r"=\n": ""
        }
        for re_rule, replace_str in re_dic.items():
            p1 = re.compile(re_rule)
            ftext = p1.sub(replace_str, ftext)
        # 3.解码quopri编码
        ftext = quopri.decodestring(ftext).decode('utf-8', "ignore").replace(" ", "")
        ftext = "".join([s for s in ftext.splitlines(True) if s.strip()])
        # 4.保存cvs文件
        csv_str = f'姓名,手机\n{ftext}'
        fname = get_fpath_fname_fextension(vcf_filename)
        with open(f'{fname[0]}/{fname[1]}.csv', "w", encoding="utf-8") as f:
            try:
                f.write(csv_str)
            finally:
                f.close()
    
    
    def csv2vcf(csv_filename):
        """csv格式文件转换为vcf格式文件"""
        # 1.读取csv文件
        with open(csv_filename, 'r', encoding='utf-8') as f:
            ftext_list = f.readlines()
            f.close()
        # 2.将cvs转换为vcf格式
        vcards = ''
        for line in ftext_list[1:]:
            tel_numbers = ''
            name_tel_list = line.strip().split(',')
            if name_tel_list[0]:
                tel_name = name_tel_list[0]  # 姓名
                for tel in name_tel_list[1:]:  # 电话
                    tel_numbers += f'TEL;CELL:{tel}\n'
                vcard = f'BEGIN:VCARD\nN:{tel_name}\n{tel_numbers}END:VCARD\n'
                vcards += vcard
        # 3.保存转换后的vcf格式文件
        fname = get_fpath_fname_fextension(csv_filename)
        with open(f'{fname[0]}/{fname[1]}.vcf', "w", encoding='utf-8') as f:
            try:
                f.write(vcards)
            finally:
                f.close()
    
    
    def vcf22csv(file):
        if not os.path.isfile(file):
            msg.showerror(message="文件不存在!")
        else:
            a = get_fpath_fname_fextension(file)[2]
            if a == ".csv":
                csv2vcf(file)
                msg.showinfo(message="转换成功!此文件为csv文件,已生成vcf文件。")
            elif a == ".vcf":
                vcf2csv(file)
                msg.showinfo(message="转换成功!此文件为vcf文件,已生成csv文件。")
            else:
                msg.showwarning(message="请选择正确的csv文件或者vsf文件.")
    
    
    if __name__ == "__main__":
        root = tk.Tk().withdraw()  # 创建tk窗口并隐藏
        filename = tk_file.askopenfilename(title='请选择vcf或csv文件',
                                           filetypes=[("vcf文件", "*.vcf"), ('csv文件', '*.csv')])
        vcf22csv(filename)
    

    效果演示

    最后

    [1].代码截止2019-12-02调试无误。
    [2].如需全部代码及相关文件,留言邮箱。
    [3].过程中有任何问题,欢迎交流!Q597966823

      让知识或技术实现其最大的价值,欢迎收藏自用、转载分享,转载请注明原文出处,谢谢!

    相关文章

      网友评论

          本文标题:[py052] 通讯录vcf与csv互转

          本文链接:https://www.haomeiwen.com/subject/ydmfgctx.html