Trong quá trình phát triển ứng dụng bằng Python, việc xử lý dữ liệu bảng là một nhiệm vụ phổ biến. Thư viện Pandas được dùng rộng rãi để xử lý và phân tích dữ liệu. Khi cần xuất dữ liệu từ Pandas DataFrame ra Excel để báo cáo hoặc phân tích sâu hơn, mặc dù Pandas cung cấp phương thức to_excel cho phép xuất cơ bản, nhưng để tạo các báo cáo Excel chuyên nghiệp với định dạng và biểu đồ, ta cần sử dụng thư viện chuyên biệt như Spire.XLS.
Bài viết này hướng dẫn cách sử dụng thư viện Spire.XLS for Python để ghi nhiều DataFrame từ Pandas vào Excel, đồng thời áp dụng định dạng và tùy chỉnh trực quan.
Tại sao nên sử dụng Spire.XLS để xuất DataFrame ra Excel
Mặc dù Pandas hỗ trợ chức năng xuất cơ bản sang Excel, nhưng khả năng tùy chỉnh định dạng, kiểu và tạo biểu đồ bị hạn chế. Ngược lại, Spire.XLS là một thư viện chuyên nghiệp dành riêng cho việc tạo và chỉnh sửa tệp Excel, cung cấp nhiều tính năng linh hoạt hơn:
- Ghi nhiều DataFrame vào các sheet khác nhau của cùng một workbook.
- Tùy chỉnh tiêu đề, font chữ, màu sắc và định dạng ô để tạo layout chuyên nghiệp.
- Điều chỉnh tự động chiều cao hàng và chiều rộng cột để tăng khả năng đọc.
- Thêm biểu đồ, công thức và các tính năng Excel khác mà không cần cài đặt Microsoft Excel hay thư viện phụ trợ.
pip install pandas spire.xls
Xuất một DataFrame duy nhất sang Excel và áp dụng định dạng
Bước 1: Tạo DataFrame mẫu
import pandas as pd
from spire.xls import Workbook, ExcelVersion
df = pd.DataFrame({
'Tên': ['Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C'],
'Phòng ban': ['Nhân sự', 'Tài chính', 'Kỹ thuật'],
'Lương': [8000, 9500, 12000]
})
Bước 2: Tạo workbook và truy cập sheet đầu tiên
workbook = Workbook()
sheet = workbook.Worksheets[0]
sheet.Name = "Thông tin nhân viên"
Bước 3: Viết tiêu đề và áp dụng định dạng
for col_index, col_name in enumerate(df.columns, start=1):
cell = sheet.Range[1, col_index]
cell.Text = col_name
cell.Style.Font.IsBold = True
cell.Style.Color = Color.LightGray
Bước 4: Viết dữ liệu vào các dòng
for row_index, row in enumerate(df.values, start=2):
for col_index, value in enumerate(row, start=1):
cell = sheet.Range[row_index, col_index]
if isinstance(value, (int, float)):
cell.NumberValue = value
else:
cell.Text = str(value)
Bước 5: Áp dụng viền và điều chỉnh chiều rộng cột
used_range = sheet.AllocatedRange
used_range.BorderAround(LineStyleType.Thin, Color.Black)
used_range.BorderInside(LineStyleType.Thin, Color.Black)
used_range.AutoFitColumns()
Bước 6: Thêm biểu đồ để trực quan hóa dữ liệu
chart = sheet.Charts.Add()
chart.ChartType = ExcelChartType.ColumnClustered
chart.DataRange = sheet.Range["A1:C4"]
chart.LeftColumn = 5
chart.TopRow = 1
chart.RightColumn = 10
chart.BottomRow = 16
chart.ChartTitle = "So sánh lương nhân viên"
chart.ChartTitleArea.Font.Size = 12
chart.ChartTitleArea.Font.IsBold = True
Bước 7: Lưu workbook
workbook.SaveToFile("bao_cao_nhan_vien.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
Xuất nhiều DataFrame vào cùng một tệp Excel
Để tổ chức dữ liệu liên quan vào các sheet khác nhau trong cùng một workbook, sử dụng vòng lặp để ghi mỗi DataFrame vào một sheet riêng biệt.
Bước 1: Tạo nhiều DataFrame mẫu
df1 = pd.DataFrame({'Tên': ['Nguyễn Văn A', 'Trần Thị B'], 'Tuổi': [28, 32]})
df2 = pd.DataFrame({'Sản phẩm': ['Laptop', 'Điện thoại'], 'Giá': [7500, 3200]})
dataframes = [
(df1, "Thông tin nhân viên"),
(df2, "Thông tin sản phẩm")
]
Bước 2: Tạo workbook mới
workbook = Workbook()
Bước 3: Ghi từng DataFrame vào sheet riêng biệt
for i, (df, sheet_name) in enumerate(dataframes):
if i < workbook.Worksheets.Count:
sheet = workbook.Worksheets[i]
else:
sheet = workbook.Worksheets.Add()
sheet.Name = sheet_name
for col_index, col_name in enumerate(df.columns, start=1):
cell = sheet.Range[1, col_index]
cell.Text = col_name
cell.Style.Font.IsBold = True
cell.Style.Color = Color.LightGray
sheet.Columns[col_index - 1].ColumnWidth = 15
for row_index, row in enumerate(df.values, start=2):
for col_index, value in enumerate(row, start=1):
cell = sheet.Range[row_index, col_index]
if isinstance(value, (int, float)):
cell.NumberValue = value
else:
cell.Text = str(value)
used_range = sheet.AllocatedRange
used_range.BorderAround(LineStyleType.Thin, Color.Black)
used_range.BorderInside(LineStyleType.Thin, Color.Black)
Bước 4: Lưu workbook
workbook.SaveToFile("bao_cao_nhan_vien_san_pham.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
Xuất DataFrame vào tệp Excel đã có
Để thêm dữ liệu mới vào một tệp Excel hiện hữu, chỉ cần tải workbook đó lên, sau đó thêm hoặc chỉnh sửa sheet theo yêu cầu.
workbook = Workbook()
workbook.LoadFromFile("bao_cao_nhan_vien_san_pham.xlsx")
new_df = pd.DataFrame({
'Vùng miền': ['Miền Bắc', 'Miền Nam', 'Miền Trung', 'Miền Tây'],
'Doanh số': [120000, 150000, 130000, 110000]
})
new_sheet = workbook.Worksheets.Add("Doanh số theo vùng")
for col_index, col_name in enumerate(new_df.columns, start=1):
cell = new_sheet.Range[1, col_index]
cell.Text = col_name
cell.Style.Font.IsBold = True
cell.Style.Color = Color.LightGray
new_sheet.Columns[col_index - 1].ColumnWidth = 15
for row_index, row in enumerate(new_df.values, start=2):
for col_index, value in enumerate(row, start=1):
cell = new_sheet.Range[row_index, col_index]
if isinstance(value, (int, float)):
cell.NumberValue = value
else:
cell.Text = str(value)
workbook.SaveToFile("bao_cao_hoan_chinh.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
Tuỳ chỉnh khi xuất DataFrame
Có thể tùy chỉnh quá trình xuất để phù hợp với nhu cầu cụ thể, như chọn cột cần xuất hoặc quyết định có bao gồm index của DataFrame hay không.
Chọn cột cụ thể để xuất
columns_to_export = ['Tên', 'Phòng ban']
workbook = Workbook()
sheet = workbook.Worksheets[0]
for col_index, col_name in enumerate(columns_to_export, start=1):
sheet.Range[1, col_index].Text = col_name
for row_index, row in enumerate(df[columns_to_export].values, start=2):
for col_index, value in enumerate(row, start=1):
sheet.Range[row_index, col_index].Text = value
workbook.SaveToFile("chon_cot_xuat.xlsx")
workbook.Dispose()
Bao gồm hoặc loại bỏ index của DataFrame
sheet.Range[1, 1].Text = "Index"
for row_index, idx in enumerate(df.index, start=2):
sheet.Range[row_index, 1].NumberValue = idx
for col_index, col_name in enumerate(columns_to_export, start=2):
sheet.Range[1, col_index].Text = col_name
for row_index, row in enumerate(df[columns_to_export].values, start=2):
for col_index, value in enumerate(row, start=2):
if isinstance(value, (int, float)):
sheet.Range[row_index, col_index].NumberValue = value
else:
sheet.Range[row_index, col_index].Text = str(value)
workbook.SaveToFile("bao_gom_index.xlsx", ExcelVersion.Version2016)
workbook.Dispose()