Skip to main content
Version: CANARY 🚧

Importing and exporting models in CSV format

Introduction​

The bowphp/csv module makes it easy to export or import models in CSV format. It relies on league/csv for robust CSV file processing.

Installation​

composer require bowphp/csv

Model configuration​

Add the Bow\Csv\Csv trait to your models:

app/Models/User.php
namespace App\Models;

use Bow\Csv\Csv;
use Bow\Database\Barry\Model;

class User extends Model
{
use Csv;

protected ?string $table = "users";
}

Exporting to CSV​

Basic export​

use App\Models\User;

// Export all users as a CSV string
$user = new User();
$csv = $user->toCsv();

// Result:
// id,name,email,created_at,updated_at
// 1,John Doe,john@example.com,2025-01-01,2025-01-01
// 2,Jane Doe,jane@example.com,2025-01-02,2025-01-02

Export with specific columns​

$user = new User();
$user->setCsvHeaders(["id", "name", "email"]);

$csv = $user->toCsv();

// Result:
// id,name,email
// 1,John Doe,john@example.com
// 2,Jane Doe,jane@example.com

Export and download​

$user = new User();
$user->setCsvHeaders(["id", "name", "email"]);

// Downloads the CSV file directly
$user->toCsv("users-export.csv");

Export in a controller​

app/Controllers/ExportController.php
namespace App\Controllers;

use App\Models\User;

class ExportController
{
public function exportUsers()
{
$user = new User();
$user->setCsvHeaders(["id", "name", "email", "created_at"]);

// Force the download
return $user->toCsv("users-" . date("Y-m-d") . ".csv");
}

public function exportAllColumns()
{
// Export all columns (default headers: ["*"])
$user = new User();
return $user->toCsv("users-full.csv");
}
}

Importing from a CSV​

Import via the service​

use Bow\Csv\CsvService;
use App\Models\User;

$service = new CsvService();
$service->import(
new User(),
"/path/to/users.csv",
["name", "email", "password"]
);
CSV file format

The CSV file must contain a header row matching the column names. The headers passed as a parameter must correspond to the columns in the CSV file.

Import via the model​

use App\Models\User;

$user = new User();
$user->setCsvHeaders(["name", "email", "password"]);

// Imports each row of the CSV as a new record
$user->importCsv("/path/to/users.csv");

Import in a controller​

app/Controllers/ImportController.php
namespace App\Controllers;

use App\Models\User;
use Bow\Http\Request;

class ImportController
{
public function importUsers(Request $request)
{
// Retrieve the uploaded file
$file = $request->file("csv_file");

if (!$file || !$file->isUploaded()) {
return response_json(["error" => "No file uploaded"], 400);
}

// Validate the extension
if ($file->getExtension() !== "csv") {
return response_json(["error" => "The file must be in CSV format"], 400);
}

// Save temporarily
$tempPath = "/tmp/" . str_uuid() . ".csv";
$file->moveTo($tempPath);

try {
$user = new User();
$user->setCsvHeaders(["name", "email", "password"]);
$user->importCsv($tempPath);

// Delete the temporary file
unlink($tempPath);

return response_json(["message" => "Import successful"]);
} catch (\Exception $e) {
return response_json(["error" => $e->getMessage()], 500);
}
}
}

Global helpers​

Two global functions are available:

// Export a model to CSV (returns a string)
$csv = app_export_model_to_csv(new User(), null, ["id", "name", "email"]);

// Export to a file (force the download)
app_export_model_to_csv(new User(), "users.csv", ["id", "name", "email"]);

// Export all columns
$csv = app_export_model_to_csv(new User(), null, ["*"]);

// Import a CSV into a model
app_import_csv_to_model(
new User(),
"/path/to/users.csv",
["name", "email", "password"]
);

API reference​

Csv trait​

MethodDescription
setCsvHeaders(array $headers)Defines the columns to export/import
toCsv(?string $filename = null)Exports to CSV (string or download)
importCsv(string $filename)Imports from a CSV file

CsvService​

MethodDescription
export(Model $model, ?string $filename, array $headers = ['*'])Exports a model to CSV
import(Model $model, string $filename, array $headers)Imports a CSV into a model

Best practices​

Recommendations
  • Define the headers: Use setCsvHeaders() to precisely control which columns are exported.
  • Validate files: Check the extension and content before importing.
  • Clean up temporary files: Delete uploaded files after processing.
  • Handle errors: Wrap imports in a try/catch to handle failures.
Caution
  • The model must use the Bow\Csv\Csv trait for the toCsv() and importCsv() methods.
  • The CSV file headers must match the expected column names.
  • The import creates new records for each row of the CSV.

Is something missing?

If you run into problems with the documentation or have suggestions to improve the documentation or the project in general, please open an issue for us, or send a tweet mentioning the Twitter account @bowframework or directly on github.