A Laravel package to efficiently manage and export contacts as vCard (.vcf) files.
developerabod/laravel-contact-exporter is a Laravel package for a laravel package to efficiently manage and export contacts as vcard (.vcf) files..
It currently has 2 GitHub stars and 6 downloads on Packagist (latest version 1.0.0).
Install it with composer require developerabod/laravel-contact-exporter.
Discover more Laravel packages by developerabod
or browse all Laravel packages to compare alternatives.
Last updated
composer require developerabod/laravel-contact-exporter
.vcf file ready to import on any smartphoneDB::table queriescomposer require developerabod/laravel-contact-exporter
php artisan vendor:publish --tag=vcard-exporter-config
This creates the file: config/vcard-exporter.php
Open config/vcard-exporter.php and map each config key to the actual column name in your database table:
return [
'table' => 'users', // Your database table name
'columns' => [
'first_name' => 'first_name', // The column name in your table
'last_name' => null, // null = disabled by default
'middle_name' => null,
'phone_mobile' => 'phone', // Primary mobile number β required
'phone_work' => null, // Optional work phone number (disabled by default)
'phone_home' => null, // Optional home phone number (disabled by default)
'email' => null, // null = disabled by default
],
'filename' => 'contacts', // Base name of the exported file (e.g. contacts.csv)
'append_count' => true, // If true: appends total contact count to filename, Example:contacts_250.vcf
'append_date' => false, // If true: appends export date to filename Example: contacts_2026-02-22.vcf
'skip_empty_phone' => true,
'normalize_phone' => true,
'charset_utf8' => true, // Enables UTF-8 encoding to support arabic
'chunk_size' => 500, // Chunk size for optimized processing
];
Note:
last_nameandwithLastName()andwithEmail()on theVCardfacade β no config changes needed.
use VCard;
public function export()
{
return VCard::download();
// Output: contacts_250.vcf
}
return VCard::withLastName()->download();
return VCard::withEmail()->download();
return VCard::withLastName()->withEmail()->download();
return VCard::from('users')->download();
return VCard::map([
'first_name' => 'name',
'phone_mobile' => 'mobile_number',
])->download();
return VCard::where(['active' => 1])->download();
// Multiple conditions
return VCard::where(['active' => 1, 'country' => 'SA'])->download();
Note:
where()only works when usingfrom(). Do not combine it withfromQuery().
// All records
return VCard::fromQuery(Contact::query())->download();
// Using an existing scope on the model
return VCard::fromQuery(Contact::active())->download();
// With custom constraints
return VCard::fromQuery(
Contact::where('country', 'SA')->orderBy('first_name')
)->download();
Important: When using
fromQuery(), apply all conditions directly to the query before passing it in. Do not chainwhere()on the VCard facade alongsidefromQuery().
DB::table Queryreturn VCard::fromQuery(
DB::table('contacts')->where('active', 1)
)->download();
return VCard::download('company_employees');
// Output: company_employees_150.vcf
return VCard::fromQuery(Contact::active())
->map([
'first_name' => 'fname',
'last_name' => 'lname',
'phone_mobile' => 'mobile',
'phone_work' => 'work_phone',
'email' => 'email',
])
->withLastName()
->withEmail()
->filename('contacts_export')
->chunkSize(1000)
->download();
| Option | Description | Default |
|--------|-------------|---------|
| table | Database table name | contacts |
| filename | Output filename without .vcf extension | contacts |
| append_count | Append the total record count to the filename | true |
| append_date | Append today's date to the filename | false |
| skip_empty_phone | Skip records that have no phone number | true |
| normalize_phone | Strip symbols and formatting from phone numbers | true |
| charset_utf8 | Enable UTF-8 charset for Arabic name support | true |
| chunk_size | Number of records to process per chunk | 500 |
| Method | Description |
|--------|-------------|
| from(string $table) | Set the database table to query |
| fromQuery($query) | Pass in a ready-made Eloquent or DB::table query builder |
| map(array $columns) | Override the column mapping at runtime |
| where(array $conditions) | Add WHERE conditions (only works with from()) |
| withLastName() | Enable the last name field |
| withEmail() | Enable the email field |
| filename(string $name) | Set a custom output filename |
| chunkSize(int $size) | Override the chunk size for this export |
| download(?string $filename) | Execute the export and stream the .vcf file |
src/
βββ Support/
β βββ ExportConfig.php β Data object holding all resolved settings
β βββ ColumnMap.php β Column mapping between config keys and DB columns
βββ VCardBuilder.php β Builds vCard 3.0 formatted strings
βββ VCardDownloader.php β Reads from DB in chunks and streams the file
βββ VCardExporter.php β The fluent API builder
βββ Facades/
β βββ VCard.php β Laravel Facade
βββ Providers/
βββ VCardServiceProvider.php
config/
βββ vcard-exporter.php
| Requirement | Version |
|-------------|---------|
| PHP | ^8.3 |
| Laravel | ^10 \| ^11 \| ^12 |
Open source, released under the MIT License.
Made with β€οΈ by Developer Abod