Bài 15. Tệp CSV, JSON, Excel và ngày giờ

Tự động hóa văn phòng bắt đầu từ việc đọc, xử lý, ghi dữ liệu. Bài này dùng pathlib, csv, json, openpyxl và datetime để xử lý các tệp thường gặp.

50 phútTrung cấp
Bạn sẽ học được
  • Quản lý đường dẫn, thư mục bằng pathlib
  • Đọc ghi CSV, JSON đúng mã hóa tiếng Việt
  • Đọc ghi Excel với openpyxl
  • Xử lý ngày giờ với datetime
Thuật ngữ cần biết
pathlib
Thư viện chuẩn thao tác đường dẫn hướng đối tượng.
UTF-8
Bảng mã hiển thị đúng tiếng Việt.
Serialize
Chuyển đối tượng thành chuỗi/tệp để lưu.
ISO 8601
Định dạng ngày chuẩn: 2026-11-10.

Khái niệm và lý thuyết

Mọi thao tác tệp nên dùng with open(...) để tệp tự đóng kể cả khi có lỗi, và luôn ghi rõ encoding="utf-8". Với CSV mở bằng Excel trên Windows, dùng utf-8-sig để Excel nhận đúng tiếng Việt.

CSV đơn giản, chỉ chứa bảng; JSON lưu dữ liệu lồng nhau, là định dạng của API web; Excel (.xlsx) có nhiều sheet, định dạng, công thức.

pathlib

from pathlib import Path
goc = Path("du_lieu")
goc.mkdir(exist_ok=True)
for tep in goc.glob("*.csv"):
    print(tep.name, tep.stat().st_size, "byte")
bao_cao = goc / "bao_cao.txt"
bao_cao.write_text("Xin chào", encoding="utf-8")

CSV và JSON

import csv, json
with open("sinh_vien.csv", encoding="utf-8-sig", newline="") as f:
    ds = list(csv.DictReader(f))          # mỗi dòng là dict
for sv in ds:
    sv["diem"] = float(sv["diem"])
dat = [sv for sv in ds if sv["diem"] >= 5]

with open("ket_qua.csv", "w", encoding="utf-8-sig", newline="") as f:
    w = csv.DictWriter(f, fieldnames=["ma", "ho_ten", "diem"])
    w.writeheader(); w.writerows(dat)

Path("ket_qua.json").write_text(
    json.dumps(dat, ensure_ascii=False, indent=2), encoding="utf-8")

Excel với openpyxl

# uv add openpyxl   (hoặc pip install openpyxl)
from openpyxl import Workbook, load_workbook
from openpyxl.styles import Font

wb = Workbook(); ws = wb.active; ws.title = "Điểm"
ws.append(["Mã", "Họ tên", "Điểm"])
for sv in dat:
    ws.append([sv["ma"], sv["ho_ten"], sv["diem"]])
ws["A1"].font = ws["B1"].font = ws["C1"].font = Font(bold=True)
ws[f"C{ws.max_row + 1}"] = f"=AVERAGE(C2:C{ws.max_row})"
wb.save("diem.xlsx")

for row in load_workbook("diem.xlsx").active.iter_rows(min_row=2, values_only=True):
    print(row)

Ngày giờ

from datetime import datetime, date, timedelta
from zoneinfo import ZoneInfo
bay_gio = datetime.now(ZoneInfo("Asia/Ho_Chi_Minh"))
print(bay_gio.strftime("%d/%m/%Y %H:%M"))
han = date(2026, 12, 31)
print((han - date.today()).days, "ngày nữa")
ngay = datetime.strptime("15/11/2026", "%d/%m/%Y")
tuan_sau = ngay + timedelta(weeks=1)
Tình huống: Gộp báo cáo các lớp

Thư mục có 10 tệp CSV điểm của 10 lớp. Viết chương trình duyệt bằng glob, gộp vào một tệp Excel, mỗi lớp một sheet, kèm sheet tổng hợp điểm trung bình từng lớp. Việc làm tay mất 1 giờ chỉ còn vài giây.

Mẹo hay

Với dữ liệu lớn hoặc cần phân tích, chuyển sang pandas (Bài 18): đọc CSV/Excel chỉ một dòng.

Lưu ý

Đường dẫn Windows như "C:\new" bị hiểu \n là xuống dòng. Dùng Path, dấu / hoặc chuỗi raw r"C:\new".

Thực hành
  1. Đọc danh sách sinh viên CSV, xếp loại và ghi ra CSV mới.
  2. Chuyển tệp CSV thành JSON và ngược lại.
  3. Tạo tệp Excel bảng lương có dòng tổng bằng công thức.
  4. Đổi tên hàng loạt ảnh trong thư mục theo ngày sửa đổi.
Tóm tắt bài học
  • pathlib cho đường dẫn và thư mục.
  • Luôn ghi encoding; CSV cho Excel dùng utf-8-sig.
  • json.dumps(ensure_ascii=False) giữ tiếng Việt.
  • openpyxl đọc ghi Excel; datetime + zoneinfo xử lý thời gian.