Cepat atau lambat, setiap aplikasi bisnis akan mendapat permintaan yang sama: data ini perlu bisa diunduh, dan data itu perlu bisa diunggah kembali. Pertanyaan berikutnya adalah formatnya, dan pilihannya selalu CSV atau Excel. Keduanya bisa dipakai, dan keduanya sama-sama menimbulkan masalah kalau dipakai di tempat yang salah. Export CSV yang terbuka menjadi satu kolom di Excel, nomor HP yang kehilangan angka nol di depan, NIK yang berubah menjadi 3,20123E+15, atau export yang menghabiskan memori server adalah kejadian yang umum, padahal semuanya bisa dihindari. Pilihan yang tepat terutama bergantung pada siapa, atau apa, yang akan membaca file tersebut.
Sebenarnya Ada Tiga Format
Saat orang menyebut Excel, yang dimaksud bisa dua format yang berbeda, dan perbedaannya penting.
| Format | Apa itu | Batasan |
|---|---|---|
| CSV | Teks biasa, satu baris data per baris teks, nilai dipisahkan oleh delimiter. Tanpa tipe data, tanpa format tampilan, tanpa sheet. | Formatnya sendiri tidak punya batas. Excel hanya membuka 1.048.576 baris pertama. |
| XLSX | Format Excel yang dipakai sejak 2007: arsip ZIP berisi file-file XML. Menyimpan tipe data, format tampilan, rumus, dan beberapa sheet. | 1.048.576 baris dan 16.384 kolom per sheet, 32.767 karakter per sel. |
| XLS | Format biner lama dari Excel 97 sampai 2003. | 65.536 baris dan 256 kolom per sheet. |
Untuk fitur baru, tidak ada alasan lagi untuk menghasilkan file XLS. Semua aplikasi spreadsheet yang dipakai saat ini bisa membaca XLSX, sementara XLS punya batas yang lebih sempit dan kode parser yang lebih tua. Jadi, kata Excel di artikel ini berarti XLSX. Ada satu jalan pintas yang juga sebaiknya dihindari, yaitu menyimpan CSV atau tabel HTML dengan ekstensi .xls. Excel memang bisa membukanya, tetapi selalu didahului peringatan bahwa format dan ekstensi file tidak cocok, dan banyak pengguna menganggap peringatan itu tanda filenya berbahaya.
Kenapa File CSV Sering Terlihat Berantakan di Excel
Sebagian besar keluhan tentang CSV sebenarnya keluhan tentang cara Excel membuka CSV. Saat pengguna mengklik dua kali file CSV, Excel menebak delimiter, encoding, dan tipe setiap kolom, dan tebakannya mengikuti regional settings komputer. Akibatnya muncul beberapa masalah yang sangat sering dialami pengguna di Indonesia.
- Semua data masuk ke satu kolom. Windows dengan regional settings Indonesia memakai koma sebagai pemisah desimal, sehingga pemisah daftarnya adalah titik koma. CSV yang dipisahkan koma akhirnya terbuka dengan seluruh isi baris menumpuk di kolom A. File yang sama terlihat normal di laptop yang memakai pengaturan English (United States).
- Angka nol di depan hilang. Excel menganggap 081234567890 sebagai angka dan menampilkannya sebagai 81234567890. Kode pos, nomor induk karyawan, dan kode produk yang diawali nol mengalami hal yang sama.
- Angka panjang kehilangan digit. Excel hanya menyimpan 15 digit angka penting. NIK yang panjangnya 16 digit atau nomor rekening akan tampil sebagai 3,20123E+15, dan digit terakhirnya diganti nol. Kalau pengguna menyimpan ulang filenya, angka aslinya hilang.
- Nama berubah menjadi karakter aneh. Tanpa byte order mark (BOM), Excel di Windows bisa membaca file UTF-8 sebagai encoding Windows lama, sehingga nama seperti José atau tulisan non-Latin menjadi rusak.
- Tanggal dan bulan tertukar. 04/03/2026 berarti 4 Maret di Indonesia dan 3 April di Amerika Serikat, dan Excel memilih salah satunya berdasarkan regional settings.
Menulis CSV dengan hati-hati hanya membantu sebagian. Menyimpan dalam UTF-8 dengan BOM menyelesaikan masalah encoding, dan tanggal berformat ISO seperti 2026-03-04 dibaca dengan benar hampir di mana saja. Namun tidak ada cara di dalam file CSV untuk memberi tahu Excel bahwa sebuah kolom adalah teks, sehingga angka nol di depan dan angka panjang tetap berisiko setiap kali file diklik dua kali. Pengguna yang perlu membuka CSV di Excel sebaiknya memakai menu Data, lalu From Text/CSV, karena di sana delimiter bisa dipilih dan kolom bisa diatur sebagai teks. Masalahnya, kebanyakan pengguna tidak akan melakukannya.
Apa yang Diselesaikan XLSX, dan Apa Biayanya
XLSX menyimpan tipe setiap sel. NIK yang ditulis sebagai teks tetap menjadi teks, tanggal tetap tanggal, dan nominal tetap angka yang bisa langsung dijumlahkan. File terbuka dengan tampilan yang sama di komputer mana pun tanpa terpengaruh regional settings, bisa berisi beberapa sheet, dan baris judulnya bisa dibekukan serta diberi format. Untuk file yang akan dibuka orang di Excel, inilah yang sebenarnya dibutuhkan pengguna.
Biayanya ada di sisi server. Untuk melihat seberapa besar, kami menulis 100.000 baris yang sama dengan tujuh kolom (ID, nama, NIK, nomor HP, tanggal, nominal, dan status) sebagai CSV dan XLSX, lalu membacanya kembali. Pengujian memakai Python 3.10 dengan modul csv bawaan dan openpyxl 3.1.5.
| Pengukuran | CSV | XLSX, mode biasa | XLSX, mode streaming |
|---|---|---|---|
| Ukuran file | 7,8 MB | 5,5 MB | 5,5 MB |
| Setelah gzip | 2,5 MB | 5,3 MB | 5,3 MB |
| Waktu menulis | 0,4 detik | 7,3 detik | 7,1 detik |
| Puncak pemakaian memori saat menulis | 11 MB | 309 MB | 43 MB |
| Waktu membaca semua baris | 0,06 detik | tidak diukur | 6,3 detik |
Ada beberapa hal yang menonjol. File XLSX sudah terkompresi sejak awal, jadi ukurannya lebih kecil tetapi hampir tidak menyusut lagi dengan gzip, sedangkan CSV justru menjadi separuh ukuran XLSX setelah dikompresi. Menulis XLSX butuh waktu sekitar tujuh belas kali lebih lama daripada CSV, dan membacanya kembali sekitar seratus kali lebih lama. Perbedaan terbesar ada di memori. Pada mode biasa, library menyimpan semua sel di memori sampai file disimpan, sehingga kebutuhan memori ikut membesar seiring ukuran export. Library yang sama dalam mode streaming menulis baris demi baris dan hanya memakai sekitar sepertujuh memorinya. Angka memori ini sudah termasuk sekitar 10 MB untuk interpreter Python itu sendiri.
Pola yang sama berlaku di bahasa lain. Kebanyakan library punya mode praktis yang membangun seluruh workbook di memori, dan mode streaming untuk file besar: Laravel Excel dan PhpSpreadsheet di PHP dengan query per chunk dan export lewat queue, atau OpenSpout untuk streaming murni, ExcelJS dengan WorkbookWriter streaming di Node.js, dan excelize dengan StreamWriter di Go. Satu catatan untuk proyek Node.js: package xlsx dari SheetJS di npm berhenti di versi 0.18.5 yang masih punya celah keamanan yang sudah diketahui, termasuk prototype pollution dan ReDoS. Versi yang lebih baru hanya diterbitkan lewat CDN SheetJS, jadi cek versi mana yang sebenarnya terpasang di proyek Anda.
Mana yang Sebaiknya Dipakai
Pertanyaan penentunya adalah siapa yang akan membaca file tersebut berikutnya. Kalau yang membaca orang yang bekerja di Excel, pakai XLSX. Kalau yang membaca program lain, pakai CSV, atau lebih baik lagi API.
| Situasi | Format yang disarankan | Alasannya |
|---|---|---|
| Laporan yang diunduh tim keuangan, admin, atau manajemen | XLSX | Terbuka dengan benar di komputer mana pun, angka tetap bisa dijumlahkan, dan kode tidak rusak |
| Data yang dikirim ke sistem lain, data warehouse, atau script | CSV dengan UTF-8 | Mudah dibuat dan dibaca, mudah di-stream, didukung semua tool |
| File upload massal yang formatnya ditentukan bank, marketplace, atau portal pemerintah | Ikuti spesifikasinya | Banyak yang mewajibkan CSV atau TXT dengan delimiter dan urutan kolom tertentu, dan spesifikasi selalu menang |
| Export di atas sekitar satu juta baris | CSV yang dikompresi ZIP atau gzip | Melewati batas baris XLSX, dan jauh lebih ringan dibuat |
| Beberapa tabel yang saling terkait dalam satu unduhan | XLSX dengan satu sheet per tabel | Satu file CSV hanya bisa berisi satu tabel |
| Data yang diisi pengguna lalu diunggah kembali | Template XLSX, dengan CSV tetap diterima | Template bisa mengatur kolom sebagai teks dan menyediakan pilihan drop-down |
| Dua sistem yang bertukar data setiap hari | API, atau CSV terjadwal kalau API tidak memungkinkan | File yang dikirim manual mudah terlupa, terubah, atau terkirim dua kali |
Untuk export, menyediakan keduanya sering kali jawaban yang paling tepat. Halaman laporan dengan tombol Unduh Excel untuk pengguna biasa dan Unduh CSV untuk analis atau kebutuhan integrasi hampir tidak menambah pekerjaan, karena keduanya dihasilkan dari query yang sama.
Membuat Fitur Export yang Andal
- Pakai mode streaming sejak awal, dan ambil data dari database per chunk atau dengan cursor, bukan memuat semuanya dalam satu query.
- Buat export besar di background job, lalu beri notifikasi atau tampilkan link unduhan saat file siap. Request HTTP yang berjalan sampai beberapa menit cepat atau lambat akan diputus oleh proxy atau load balancer.
- Di XLSX, tulis NIK, nomor HP, nomor rekening, dan kode lain sebagai sel teks, nominal sebagai angka, dan tanggal sebagai tanggal sungguhan.
- Di CSV, pakai UTF-8 dengan BOM jika file akan dibuka di Excel, beri tanda kutip pada nilai sesuai RFC 4180, dan pakai tanggal berformat ISO 8601.
- Lindungi dari formula injection. Sel yang nilainya diawali =, +, -, atau @ bisa dijalankan sebagai rumus saat file dibuka. OWASP menyarankan menambahkan tanda kutip tunggal di depan nilai seperti itu, dan ini penting setiap kali export berisi teks yang diketik pengguna, seperti nama, alamat, atau catatan.
- Terapkan aturan akses yang sama dengan halaman asal export. Export yang melewatkan filter hak akses adalah salah satu jalur kebocoran data yang paling sering terjadi di aplikasi bisnis.
Membuat Fitur Import yang Tidak Gagal Saat Menerima File Sungguhan
Import lebih sulit daripada export, karena filenya berasal dari pengguna dan isinya bisa apa saja. CSV yang disimpan Excel di komputer berbahasa Indonesia sering memakai titik koma, dan kalau pengguna tidak memilih CSV UTF-8 saat menyimpan, encoding-nya adalah encoding Windows lama. Fitur import harus siap menghadapi kondisi itu.
- 1Sediakan template yang bisa diunduh, sebaiknya XLSX, berisi header yang diharapkan, kolom kode yang sudah diatur sebagai teks, dan pilihan drop-down untuk nilai seperti status atau kategori.
- 2Jika menerima CSV, deteksi delimiter (koma, titik koma, atau tab) dan encoding-nya, jangan diasumsikan. Cocokkan kolom berdasarkan nama header, bukan urutan kolom.
- 3Tetapkan batasan sebelum file diproses: ukuran file maksimum, jumlah baris maksimum, dan hanya ekstensi yang didukung. File XLSX adalah arsip ZIP, sehingga file unggahan yang kecil bisa mengembang menjadi sangat besar. Pakai library yang membatasi hal ini, dan tolak file .xlsm yang berisi macro.
- 4Baca nilai sel yang tersimpan, jangan pernah mengeksekusi rumus dari file yang diunggah.
- 5Validasi setiap baris dan tampilkan preview berisi kesalahan per baris, misalnya baris 37: NIK harus 16 digit, sebelum ada data yang disimpan.
- 6Simpan semuanya dalam satu transaksi, atau lewat staging table, supaya kegagalan di tengah proses tidak meninggalkan data yang baru setengah masuk. Untuk file besar, proses import di background job dan laporkan hasilnya setelah selesai.
Ringkasnya
CSV adalah format yang lebih baik untuk mesin, dan XLSX lebih baik untuk manusia. Sebagian besar masalah muncul karena CSV diberikan kepada orang yang akan membukanya dengan klik dua kali, atau karena XLSX berukuran besar dibuat tanpa streaming. Tentukan format berdasarkan siapa yang membaca file berikutnya, pakai streaming dan background job untuk export besar, dan perlakukan setiap file unggahan sebagai input yang tidak tepercaya. Jika aplikasi Anda butuh fitur import dan export yang dibangun atau diperbaiki, terutama untuk data besar atau integrasi dengan sistem lain, tim custom software kami siap membantu.
Poin penting
- Pakai XLSX untuk file yang akan dibuka orang di Excel, dan CSV untuk file yang dibaca sistem lain, script, atau export yang sangat besar. Jangan lagi menghasilkan format XLS lama.
- Excel membuka CSV mengikuti regional settings, sehingga pengguna di Indonesia sering melihat data menumpuk di satu kolom, angka nol di depan hilang, NIK berubah ke notasi ilmiah, dan nama rusak.
- Dalam pengujian kami dengan 100.000 baris, menulis XLSX sekitar 17 kali lebih lama daripada CSV, dan mode biasa memakai memori 309 MB dibanding 43 MB pada mode streaming.
- Untuk export, stream datanya, jalankan export besar di background, tulis kode sebagai teks, dan lindungi dari formula injection.
- Untuk import, sediakan template XLSX, deteksi delimiter dan encoding, batasi ukuran file, validasi setiap baris dengan preview, dan simpan dalam satu transaksi.


