Skip to main content

CSV to VCF converter

Map your spreadsheet columns onto vCard properties and export every row as a contact. vCard 3.0 or 4.0, one .vcf or one file per contact, all in this tab.

Parsed by Papa Parse and written to a Blob in this tab. No row, and no photo URL, is fetched or uploaded.

A spreadsheet export and a phone contact list hold the same information in incompatible shapes: CSV is a grid with whatever headers the exporting app felt like using, while a vCard is a list of named properties with a fixed vocabulary. This page bridges them by asking you to say which column is the mobile number and which is the job title, then writing one VCARD block per row. It reads the header line, guesses a mapping from names it recognises (including Danish headers like Fornavn, Efternavn and Postnummer), and lets you correct every guess before anything is written. The result is a plain .vcf you can import into iOS Contacts, Google Contacts, Outlook or a Nextcloud address book.

Key facts about CSV to VCF converter

Key facts about CSV to VCF converter
Mapped propertiesFN, N, ORG, TITLE, TEL (cell/work/home), EMAIL (home/work), ADR, URL, BDAY, NOTE, PHOTO
Versions writtenvCard 3.0 (RFC 2426) and vCard 4.0 (RFC 6350) — picked per export, not converted afterwards
3.0 vs 4.0 phone3.0 writes TEL;TYPE=CELL:+45 12 34 56 78; 4.0 writes TEL;TYPE=cell;VALUE=uri:tel:+4512345678
Mandatory fieldFN — a row with no first name, last name, full name or organization is skipped and counted
EscapingBackslash, semicolon, comma and newline in a value are escaped; lines fold at 75 UTF-8 bytes
Line endingsCRLF, as both RFCs require — a .vcf with bare LF is rejected by some Outlook builds
Photo handlingA photo column becomes a URI reference (PHOTO;VALUE=URL in 3.0, PHOTO;MEDIATYPE in 4.0); the image is never downloaded or embedded
Birthday parsingYYYY-MM-DD and DD/MM/YYYY are recognised; 3.0 keeps the dashes, 4.0 writes YYYYMMDD
Output shapesOne .vcf holding every contact, or a ZIP with one .vcf per contact for services that import singles
DelimiterPapa Parse sniffs comma, semicolon and tab from the header line — a Danish Excel export with semicolons works unchanged
Input ceiling10 MB of CSV text, which is roughly 60,000 contact rows
Not writtenGroups, categories, IMPP handles, multiple addresses per contact, and embedded base64 photos

What happens to your file

The CSV is read by a FileReader in this tab, parsed by Papa Parse, and turned into vCard text by string concatenation. The .vcf you download is a Blob built in page memory and handed to a temporary object URL; the per-contact ZIP is assembled by JSZip in the same tab. There is no upload endpoint and no Pages Function involved, so names, phone numbers and email addresses never travel. The one thing worth stating plainly: if you map a Photo column, the tool writes the URL you gave into the card as a reference — it does not fetch that image, so no request is made to the host holding it either. Close the tab and every parsed row is gone; nothing is stored in localStorage.

About this tool

  1. 1

    Load the CSV

    Drop the file, browse for it, or paste the text. The first line must be the column names — that is what the mapping list is built from.

  2. 2

    Check the auto-mapping

    Headers like Email, Mobile, Company and Postnummer are matched automatically. Every field has a dropdown, so anything guessed wrong can be repointed or set to 'not used'.

  3. 3

    Pick the vCard version

    Choose 3.0 if you are importing into Outlook or an older address book, 4.0 for modern CardDAV servers and iOS. The two write genuinely different property syntax.

  4. 4

    Choose one file or many

    One .vcf with every contact is what Google Contacts and iOS expect. The ZIP option gives one file per contact for services that only take a single card at a time.

  5. 5

    Read the preview

    The first card is printed in full. Check the FN line and the phone format before you download — that is the fastest way to catch a mis-mapped column.

  6. 6

    Download and import

    Import the .vcf in your contacts app. If rows were skipped, the counter above the preview says how many and why: no usable name.

Specs & compatibility
Input.csv, .tsv or .txt with a header row, or CSV pasted into the box; up to 10 MB
Outputtext/vcard (.vcf), UTF-8, CRLF line endings — or a .zip of individual cards
ParserPapa Parse 5 with header mode and quoted-field support, so a value containing a comma survives
Import targets testediOS and macOS Contacts, Google Contacts, Outlook (desktop and web), Thunderbird, Nextcloud
Character setUTF-8 throughout — Danish, German and Greek names come through unchanged
Browser supportAny current Chrome, Edge, Firefox or Safari; the clipboard button needs a secure context
OfflineWorks with the network off once the page has loaded
AccountNone — no signup, no quota, no watermark
  • Export from Google Contacts, delete the columns you do not want, and re-import: this page is the return leg of that round trip.
  • If your phone numbers lack a country code, add one in the spreadsheet first — vCard 4.0 turns TEL into a tel: URI, and a bare local number is ambiguous there.
  • Map Company even when you have names: it becomes ORG, and it is also the fallback the tool uses for FN when a row has no person name at all.
  • A Danish Excel export usually uses semicolons as the delimiter; paste it as-is, the parser detects the separator from the header line.
  • Leave Work email unmapped if you only have one address — two EMAIL properties with the same value produce duplicate entries in some address books.
  • The ZIP option names each file after the contact, so a folder of cards is browsable; duplicates get a numeric suffix rather than overwriting each other.
  • Auto-detected column mapping with manual override per field
  • vCard 3.0 and 4.0 with version-correct TEL, EMAIL, ADR and PHOTO syntax
  • Single .vcf or a ZIP of one card per contact
  • RFC escaping and 75-byte line folding
  • Live preview of the first generated card
  • Skipped-row counter instead of silently dropping data
  • Moving a customer list out of a CRM export and into the phone of whoever is doing the calling.
  • Turning a conference attendee spreadsheet into cards the sales team can import before they travel.
  • Rebuilding an address book after a phone migration left you with only a CSV backup.
  • Loading a club or class roster into Google Contacts so group messaging works.
  • Preparing per-contact .vcf files to attach to individual emails or hand to a partner system that imports one card at a time.
  • Round-tripping contacts that were flattened with the vCard to CSV tool, cleaned in a spreadsheet, and now need to go back.
Choose 3.0 unless you know the target wants 4.0. Version 3.0 is what Outlook, most CRMs and every older address book were written against, and modern apps still read it. Version 4.0 is the current RFC and is what CardDAV servers and recent iOS builds prefer; it writes phone numbers as tel: URIs and dates without dashes. The difference is real syntax, not a label: this page generates the correct form for whichever you pick rather than writing one file and stamping a different version number on it.
A vCard must have an FN property — a display name — or importers reject the whole card. If a row has no first name, no last name, no full name and no organization mapped to it, there is nothing honest to put there, so the row is skipped and the count is shown next to the contact total. The usual cause is a mapping that points FN at a column which is empty for those rows. Map Full name, or First and Last name, and the count drops to zero.
No, and that is deliberate. Embedding a photo means downloading the image and base64-encoding it into the card, which would mean this page making a request to whatever server hosts it — the one thing a browser-only tool should not do quietly. Instead a mapped photo column is written as a URI reference, which iOS Contacts, Google Contacts and most CardDAV clients resolve themselves on import. If you need embedded images, do the embedding in the app you are importing into.
Yes. The parser sniffs the delimiter from the header line, so a semicolon-separated export from a Danish or German Excel works without any conversion step. Tab-separated files work too. If the sniff goes wrong you will see it immediately: the mapping list will show one giant column instead of several, and you can re-save the file with commas.
They are escaped. vCard uses the semicolon as a structural separator inside properties like N and ADR and the comma to separate list values, so a company called "Fjord, ApS" would otherwise split into two values. The generator escapes backslash, semicolon, comma and newline in every value it writes, and folds any line past 75 UTF-8 bytes onto a continuation line, which is what the RFC requires and what strict importers check.
No. Reading the file, parsing it and writing the vCard text all happen in this tab, and the download is a Blob created in page memory. You can disconnect from the network after the page loads and the conversion still completes. Nothing is written to localStorage either, so reloading the page clears everything.
View all

Updated

We use anonymous analytics to improve ToolChamp. No personal data is stored or sold. Privacy Policy