What’s the most reliable way to Convert VCF to CSV without losing formatting?

The​‍​‌‍​‍‌​‍​‌‍​‍‌ biggest problem when changing the format of contact files is that you need to keep track of all the fields, phone numbers, emails, and addresses properly. Some online tools work very fast, but they break the structure when a VCF file has several numbers or custom labels. I am an offline tool user, as they do not rely on internet uploads and handle mapping more efficiently. Once I had to change the format of about 600 mobile contacts from VCF to CSV, and the only tool that kept the columns correct was Softaken vCard to CSV Converter. The result was perfect, and nothing was out of place. The main thing is always to have your original VCF backed up before you change the format, because if the formatting is changed, it is very difficult to restore it. CSV is a plain text file with columns, so you need to have a converter that understands vCard format. If you put accuracy before speed, then an offline conversion will be the safest ​‍​‌‍​‍‌​‍​‌‍​‍‌way.

Or, try this.

#!/usr/bin/env python3
#
#  may need to run "pip install vobject" first
#

import csv
import vobject
import argparse

def vcf_to_csv(vcf_file, csv_file):
    try:
        with open(vcf_file, 'r', encoding='utf-8') as vcf:
            # Read all VCards
            vCards = list(vobject.readComponents(vcf.read()))

            print(f"Total vCards read: {len(vCards)}")

            if not vCards:
                print("No vCards found.")
                return

            with open(csv_file, 'w', newline='', encoding='utf-8') as csvfile:
                csv_writer = csv.writer(csvfile)

                # Empty lists to hold headers and content
                headers = []
                content_list = []

                # Extract headers and content
                for card in vCards:
                    # Temporary dictionary for the current card
                    card_dict = {}
                    for key, value in card.contents.items():
                        # Capture all keys and their values
                        if isinstance(value, list):
                            card_dict[key] = [str(v) for v in value]  # Convert value(s) to string
                        else:
                            card_dict[key] = str(value)

                    # Only add keys to headers if they don't already exist
                    for key in card_dict.keys():
                        if key not in headers:
                            headers.append(key)

                    # Append content to content_list for CSV writing
                    content_list.append(card_dict)

                # Write header row
                csv_writer.writerow(headers)

                # Write contact data
                for content in content_list:
                    row = []
                    for header in headers:
                        # Append the value based on header presence
                        row.append(", ".join(content.get(header, [''])))
                    csv_writer.writerow(row)

    except Exception as e:
        print(f"An error occurred: {e}")

def main():
    parser = argparse.ArgumentParser(description='Convert VCF to CSV.')
    parser.add_argument('-i', '--input', required=True, help='Input VCF file')
    parser.add_argument('-o', '--output', required=True, help='Output CSV file')

    args = parser.parse_args()

    vcf_to_csv(args.input, args.output)
    print(f"Successfully converted {args.input} to {args.output}")

if __name__ == "__main__":
    main()