CSV unggul karena sederhana, tetapi kesederhanaan itu juga membatasi: CSV tidak mengenal banyak lembar kerja, tidak menyimpan format, dan tidak dipakai para penyusun laporan untuk bekerja sehari-hari. Di banyak organisasi, laporan justru hidup di Excel — laporan mingguan manajer Toko Kopi Kita, rekap kantor pusat, hingga data harga dari dinas tiba sebagai berkas .xlsx. Pada chapter ini kita membaca workbook Excel dengan pd.read_excel(): memilih sheet, melewati baris judul, memilih kolom, menangani nilai kosong, lalu menggabungkan dua sheet menjadi satu tabel analisis.
Workbook dan Engine-nya #
Berkas .xlsx adalah satu paket berisi lembar kerja (sheet), dan tiap sheet adalah kisi sel yang bisa memuat tabel, judul, sampai catatan pinggir. Berkas latihan chapter ini, laporan_penjualan.xlsx, memuat dua sheet dengan susunan berikut:
| Sheet | Susunan baris | Isi |
|---|---|---|
Penjualan | Baris 1 judul laporan, baris 2 nama kolom, 8 baris data | Penjualan 20-23 Januari 2026 |
Produk | Baris 1 nama kolom, 4 baris data | Daftar produk, pemasok, dan harga |
Satu hal teknis sebelum masuk ke kode: pandas tidak membaca .xlsx sendiri. Pekerjaan itu diserahkan kepada library openpyxl yang berperan sebagai engine pembaca — di lingkungan latihan library tersebut sudah terpasang, dan pada lingkungan lain cukup dipasang lewat pip install openpyxl. Penjelasan lengkap tentang membaca-menulis Excel pada pandas tersedia di pandas user guide
.
Membaca Default dan Masalah Baris Judul #
Laporan buatan manusia hampir selalu memulai tabel dengan judul besar di atasnya. Kita baca dulu laporan_penjualan.xlsx apa adanya untuk melihat akibatnya:
import pandas as pd
df = pd.read_excel("laporan_penjualan.xlsx")
print(df.head(3))
print()
print("Nama kolom:", list(df.columns))Output yang Dihasilkan:
Laporan Penjualan Toko Kopi Kita Unnamed: 1 Unnamed: 2 Unnamed: 3
0 tanggal produk jumlah pelanggan
1 2026-01-20 kopi susu 12 Budi
2 2026-01-20 matcha latte 8 Siti
Nama kolom: ['Laporan Penjualan Toko Kopi Kita', 'Unnamed: 1', 'Unnamed: 2', 'Unnamed: 3']Mari kita telaah baris-baris pentingnya:
- Baris 3 (
pd.read_excel(...)tanpa parameter): pandas membuka sheet pertama secara bawaan dan menjadikan baris pertamanya — baris judul — sebagai nama kolom. - Baris 6 (
list(df.columns)): nama kolom yang diperoleh bertepatan dengan judul laporan di kolom pertama, sementara tiga kolom lainnya bernamaUnnamed: 1sampaiUnnamed: 3. Nama kolom yang sesungguhnya (tanggal,produk,jumlah,pelanggan) tergelincir menjadi baris data pertama — terlihat jelas pada hasildf.head(3).
Pembacaan seperti ini tidak mengeluarkan galat, tetapi seluruh analisis lanjutan akan salah alamat kolomnya. Solusinya satu parameter: skiprows.
Melewati Baris Judul dengan skiprows #
skiprows=1 memerintahkan pandas melewati satu baris paling atas sebelum membaca, sehingga baris kedua — baris nama kolom — menempati posisi header. Sekaligus kita tambahkan dua penyesuaian yang sudah akrab dari chapter CSV: sheet_name untuk memilih sheet secara eksplisit dan na_values untuk penanda kosong buatan.
import pandas as pd
penjualan = pd.read_excel(
"laporan_penjualan.xlsx",
sheet_name="Penjualan",
skiprows=1,
na_values=["-"],
)
print(penjualan)
print()
print(penjualan.dtypes)
print()
print("Nilai hilang per kolom:")
print(penjualan.isna().sum())Output yang Dihasilkan:
tanggal produk jumlah pelanggan
0 2026-01-20 kopi susu 12 Budi
1 2026-01-20 matcha latte 8 Siti
2 2026-01-21 americano 5 Budi
3 2026-01-21 kopi susu 15 Dewi
4 2026-01-22 teh tawar 6 NaN
5 2026-01-22 kopi susu 9 Agus
6 2026-01-23 matcha latte 7 NaN
7 2026-01-23 americano 4 Rani
tanggal object
produk object
jumlah int64
pelanggan object
dtype: object
Nilai hilang per kolom:
tanggal 0
produk 0
jumlah 0
pelanggan 2
dtype: int64Mari kita telaah baris-baris pentingnya:
- Baris 5 (
sheet_name="Penjualan"): tanpa parameter ini, pandas memakai sheet pertama. Menuliskan nama sheet membuat pilihan eksplisit dan tetap benar meski urutan sheet diubah pembuat laporan. - Baris 6 (
skiprows=1): baris judul dilewati;tanggal,produk,jumlah, danpelanggankini menjadi nama kolom yang benar. - Baris 7 (
na_values=["-"]): tanda-pada baris matcha latte tanggal 23 Januari diubah menjadiNaN. Sel yang memang kosong — pelanggan teh tawar tanggal 22 Januari — sudah menjadiNaNsecara bawaan; dua asal nilai hilang yang berbeda berakhir pada penanda yang sama. - Baris 14 (
isna().sum()): ringkasan menegaskan dua nilai hilang seluruhnya berada di kolompelanggan— pola yang wajar untuk laporan kasir yang tidak selalu mencatat nama pembeli.
Membaca Sheet Lain dan Memilih Kolom #
Sheet kedua, Produk, menyimpan harga satuan — dan justru di situlah nilainya bagi analisis: omzet tidak dapat dihitung dari sheet Penjualan saja. Kita baca kedua sheet dengan usecols agar hanya kolom yang diperlukan yang dimuat, lalu gabungkan keduanya dengan merge() — method yang didokumentasikan lengkap di pandas.DataFrame.merge
.
import pandas as pd
penjualan = pd.read_excel(
"laporan_penjualan.xlsx",
sheet_name="Penjualan",
skiprows=1,
na_values=["-"],
usecols=["tanggal", "produk", "jumlah"],
)
produk = pd.read_excel(
"laporan_penjualan.xlsx",
sheet_name="Produk",
usecols=["produk", "harga"],
)
tabel = penjualan.merge(produk, on="produk", how="left")
tabel["omzet"] = tabel["jumlah"] * tabel["harga"]
print(tabel)
print()
print("Total omzet empat hari:", tabel["omzet"].sum())Output yang Dihasilkan:
tanggal produk jumlah harga omzet
0 2026-01-20 kopi susu 12 24000 288000
1 2026-01-20 matcha latte 8 28000 224000
2 2026-01-21 americano 5 22000 110000
3 2026-01-21 kopi susu 15 24000 360000
4 2026-01-22 teh tawar 6 20000 120000
5 2026-01-22 kopi susu 9 24000 216000
6 2026-01-23 matcha latte 7 28000 196000
7 2026-01-23 americano 4 22000 88000
Total omzet empat hari: 1602000Mari kita telaah baris-baris pentingnya:
- Baris 3-9 (
penjualan): pembacaan sheetPenjualankini memuat hanya tiga kolom —pelangganyang bolong-bolong tidak diperlukan untuk menghitung omzet, jadi ditinggalkan sejak awal. - Baris 10-14 (
produk): sheetProdukdibaca denganusecols=["produk", "harga"]; kolompemasokyang tidak terpakai tidak ikut dimuat. - Baris 16 (
merge): kedua tabel digabung berdasarkan nilai yang sama pada kolomproduk.how="left"mempertahankan seluruh baris penjualan lalu menempelkan harga yang cocok di baris masing-masing. - Baris 17 (
omzet): kolom baru dihitung darijumlahdikaliharga; penjumlahannya menghasilkan 1.602.000 rupiah untuk empat hari berjualan.
Keunikan Excel yang Perlu Dikenali #
Dua sifat Excel membedakannya dari CSV dan menuntut kewaspadaan ekstra. Pertama, tipe tersimpan longgar: Excel tidak mengenal tipe kolom — tipe melekat pada sel satu per satu, sehingga satu kolom boleh memuat angka di sel atas dan teks di sel bawah tanpa teguran. Tebakan tipe oleh pandas dapat berbeda dari niat penyusunnya; kolom yang tampak penuh angka bisa terbaca object hanya karena satu sel tersimpan sebagai teks. Kebiasaan memeriksa dtypes karena itu semakin penting.
Kedua, sel gabungan (merged cells): beberapa sel dilebur menjadi satu demi tampilan — judul besar atau kategori berjajar. Bagi pembaca data, peleburan itu hanya menyisakan nilai pada sel kiri-atas; sel sisanya kosong dan muncul sebagai NaN, lengkap dengan kehilangan konteks nilainya. Untuk berkas yang akan dibaca program, simpan setiap data pada sel tunggal dan letakkan judul di luar tabel — persis pola yang kita tangani dengan skiprows di atas.
Rangkuman #
pd.read_excel()membaca.xlsxmelalui engineopenpyxl; tanpa parameter, sheet pertama yang dipakai dan baris pertamanya menjadi nama kolom.- Baris judul membuat nama kolom bergeser menjadi
Unnamed;skiprows=1melewatinya sehingga baris nama kolom menempati posisi header. sheet_namememilih sheet tertentu (atauNoneuntuk semuanya),usecolsmemuat kolom tertentu saja, danna_valuesmenangani penanda kosong buatan selain sel kosong bawaan.merge()menyatukan dua sheet menjadi satu tabel analisis — penjualan dan harga bertemu menjadi kolom omzet.- Excel menyimpan tipe per sel dan mengenal sel gabungan; keduanya menuntut pemeriksaan
dtypesserta desain berkas yang memisahkan tampilan dari data.
Baik CSV maupun Excel berbagi satu wujud: tabel baris-kolom. Sistem modern seperti API dan aplikasi web justru bertukar data dalam bentuk lain — pasangan kunci-nilai yang saling bercabang, dengan nama JSON. Pada chapter berikutnya, Membaca File JSON
, kita membaca struktur bertingkat itu dengan modul json bawaan Python dan pandas.