Cara Import Excel ke Database Laravel dengan PhpSpreadsheet phpoffice (Mudah & Cepat & Contoh kasus)

Cara Import Excel ke Database Laravel dengan PhpSpreadsheet phpoffice (Mudah & Cepat & Contoh kasus)

Import data dari Excel ke database adalah solusi paling efisien untuk mengelola banyak data sekaligus. Dengan Laravel dan PhpSpreadsheet, proses ini bisa dibuat otomatis, rapi, dan minim error.

Artikel ini langsung membahas praktiknya, mulai dari contoh sederhana sampai studi kasus nyata.

Kenapa Perlu Import Excel?

Beberapa alasan kenapa fitur ini penting:

  • Menghemat waktu input data
  • Mengurangi human error
  • Cocok untuk data massal (undangan, produk, user, dll)
  • Bisa dibuat template agar user tidak salah format

Persiapan Install Library

Gunakan PhpSpreadsheet:

composer require phpoffice/phpspreadsheet

Contoh Dasar Import Excel (Tabel Barang)

Struktur Tabel

Schema::create('barangs', function (Blueprint $table) {
$table->id();
$table->string('nama_barang');
$table->integer('qty');
$table->integer('harga');
$table->timestamps();
});

Format Excel

Pastikan urutan kolom seperti ini:

nama_barangqtyharga
Pensil102000
Buku55000

Controller Import

use PhpOffice\PhpSpreadsheet\IOFactory;
use App\Models\Barang;public function import(Request $request)
{
$request->validate([
'file' => 'required|mimes:xlsx,xls'
]); $file = $request->file('file')->getPathname();
$spreadsheet = IOFactory::load($file);
$rows = $spreadsheet->getActiveSheet()->toArray(); unset($rows[0]); // hapus header foreach ($rows as $row) {
Barang::create([
'nama_barang' => $row[0],
'qty' => $row[1],
'harga' => $row[2],
]);
} return back()->with('success', 'Import berhasil');
}

Membuat Template Excel Agar Tidak Salah Format

Supaya user tidak salah isi, buat template:

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;public function downloadTemplate()
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet(); $sheet->fromArray([
['nama_barang', 'qty', 'harga']
], NULL, 'A1'); $writer = new Xlsx($spreadsheet);
$fileName = 'template_barang.xlsx'; header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header("Content-Disposition: attachment; filename=\"$fileName\"");
$writer->save('php://output');
exit;
}

Studi kasus : Dalam banyak kasus, kita punya kebutuhan contoh seperti ini:

Kita ingin input banyak data perusahaan sekaligus, tapi tidak mau input manual satu per satu di form. Selain itu, setiap perusahaan juga harus:

  • punya akun user otomatis
  • punya kode unik
  • punya token
  • dan mengikuti aturan tertentu (misalnya kuota & meja)

Jadi alurnya yang diinginkan adalah:

  1. Admin download template Excel
  2. Admin isi data perusahaan di Excel
  3. Upload ke sistem
  4. Sistem otomatis:
    • membaca file Excel
    • membuat user baru
    • generate kode perusahaan (ext50-0001, dst)
    • menentukan kuota (company vs personal)
    • menyimpan ke database

Dengan konsep ini, input ratusan data bisa selesai dalam hitungan detik.


Struktur Data yang Digunakan

Tabel perusahaans:

  • kode_perusahaan
  • nama_perusahaan
  • jenis (personal / company)
  • pic
  • meja
  • kuota
  • token

Relasi ke tabel users (otomatis dibuat saat import)


Route

Tambahkan di web.php:

use App\Http\Controllers\Admin\PerusahaanTemplateExport;Route::prefix('admin/undangan')->group(function () {
Route::get('/download-template', [PerusahaanTemplateExport::class, 'downloadTemplate'])
->name('undangan.template'); Route::post('/import', [PerusahaanTemplateExport::class, 'import'])
->name('undangan.import');
});

Buat Controller

php artisan make:controller Admin/PerusahaanTemplateExport

Controller Lengkap

<?phpnamespace App\Http\Controllers\Admin;use App\Http\Controllers\Controller;
use Illuminate\Http\Request;use App\Models\User;
use App\Models\Perusahaan;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;class PerusahaanTemplateExport extends Controller
{
// DOWNLOAD TEMPLATE
public function downloadTemplate()
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet(); // header
$sheet->fromArray([
['nama_perusahaan', 'jenis', 'pic', 'meja', 'kuota']
], NULL, 'A1'); // dropdown jenis
$validationJenis = $sheet->getCell('B2')->getDataValidation();
$validationJenis->setType(DataValidation::TYPE_LIST);
$validationJenis->setAllowBlank(false);
$validationJenis->setFormula1('"personal,company"'); // dropdown pic
$validationPic = $sheet->getCell('C2')->getDataValidation();
$validationPic->setType(DataValidation::TYPE_LIST);
$validationPic->setAllowBlank(false);
$validationPic->setFormula1('"iqbal,dewi,vic,harzen,hrd"'); // apply ke banyak baris
for ($i = 2; $i <= 100; $i++) {
$sheet->getCell('B' . $i)->setDataValidation(clone $validationJenis);
$sheet->getCell('C' . $i)->setDataValidation(clone $validationPic);
} $writer = new Xlsx($spreadsheet);
$fileName = 'template_perusahaan_' . Carbon::now()->format('dmyHi') . '.xlsx'; header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header("Content-Disposition: attachment; filename=\"$fileName\"");
$writer->save('php://output');
exit;
} // IMPORT EXCEL
public function import(Request $request)
{
$request->validate([
'file' => 'required|mimes:xlsx,xls'
]); $file = $request->file('file')->getPathname();
$spreadsheet = IOFactory::load($file);
$rows = $spreadsheet->getActiveSheet()->toArray(); unset($rows[0]); // skip header foreach ($rows as $row) { if (!$row[0]) continue; $nama = $row[0];
$jenis = strtolower($row[1]);
$pic = $row[2];
$meja = $row[3];
$kuota = $row[4]; // generate kode
$lastKode = Perusahaan::where('kode_perusahaan', 'like', 'ext50-%')
->orderBy('kode_perusahaan', 'desc')
->first(); $number = $lastKode ? ((int)substr($lastKode->kode_perusahaan, -4)) + 1 : 1;
$kode = 'ext50-' . str_pad($number, 4, '0', STR_PAD_LEFT); // create user
$user = User::create([
'name' => $nama,
'email' => Str::slug($kode) . '@extrupack.com',
'password' => Hash::make($kode),
'role' => 'user'
]); // create perusahaan
Perusahaan::create([
'user_id' => $user->id,
'kode_perusahaan' => $kode,
'nama_perusahaan' => $nama,
'jenis' => $jenis,
'pic' => $pic,
'meja' => $jenis === 'personal' ? $meja : null,
'kuota' => $jenis === 'company' ? $kuota : 1,
'token' => Str::random(20),
]);
} return back()->with('success', 'Import berhasil!');
}
}

View (Blade)

<div class="d-flex flex-wrap align-items-center gap-2">    <a href="{{ route('undangan.template') }}" class="btn btn-success btn-sm">
        Download Template
    </a>    <form action="{{ route('undangan.import') }}" method="POST" enctype="multipart/form-data" class="d-flex gap-2">
        @csrf
        <input type="file" name="file" class="form-control form-control-sm" required>
        <button type="submit" class="btn btn-primary btn-sm">Import</button>
    </form></div>@if(session('success'))
    <div class="alert alert-success mt-2">
        {{ session('success') }}
    </div>
@endif

Format Excel

nama_perusahaanjenispicmejakuota
PT ABCcompanyjoko10
BowopersonalmegaA1

QnA

Q: Kenapa kuota personal tidak terbaca?
A: Karena otomatis diset jadi 1 di backend.

Q: Kenapa meja company kosong?
A: Karena memang hanya dipakai untuk personal.

Q: Bisa tambah validasi?
A: Bisa, misalnya cek jenis hanya “personal” atau “company”.

Q: Aman untuk banyak data?
A: Aman, tapi kalau sangat besar gunakan queue.

Q: Bisa dikembangkan lagi?
A: Bisa, seperti:

  • cek duplikat perusahaan
  • import dengan progress bar
  • export ulang ke Excel

Dengan struktur ini, sistem kamu sudah masuk level “semi automation”, bukan sekadar CRUD biasa.


Comments

No comments yet. Why don’t you start the discussion?

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *