使用Python的openpyxl庫批量格式化Excel文件的方法
場景引入
公司規(guī)定所有報表必須使用統(tǒng)一的格式:標題行加粗、背景色藍色、字號 12、所有單元格加邊框。但每次從系統(tǒng)導出的數(shù)據(jù)都是"裸表"——沒有任何格式。公司有 50 份這樣的報表需要格式化,手動調(diào)整每份表格至少要 5 分鐘,總計 4 個小時。
本節(jié)教你用 Python + openpyxl 實現(xiàn) 一鍵格式化,50 份表格只需 10 秒。
技術(shù)原理
pandas 擅長數(shù)據(jù)處理,但不擅長格式控制。本節(jié)引入 openpyxl 庫,它可以直接操作 Excel 的格式屬性:
| 格式屬性 | openpyxl 對應(yīng) |
|---|---|
| 字體 | Font(name, size, bold, italic, color) |
| 填充(背景色) | PatternFill(start_color, fill_type) |
| 邊框 | Border(left, right, top, bottom) |
| 對齊 | Alignment(horizontal, vertical) |
| 列寬 | worksheet.column_dimensions[col].width |
工作流程:
裸數(shù)據(jù).xlsx → openpyxl 加載 → 應(yīng)用格式規(guī)則 → 保存格式化后的文件
環(huán)境準備
pip install openpyxl
完整代碼
import os
from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment
def format_excel_sheet(input_file, output_file=None):
"""
為 Excel 文件添加統(tǒng)一的格式:標題行加粗、藍色背景、邊框、對齊
參數(shù):
input_file: 輸入的原始 Excel 文件
output_file: 輸出的格式化文件(默認在原文件名后加_已格式化)
"""
if output_file is None:
base_name = os.path.splitext(input_file)[0]
output_file = f"{base_name}_已格式化.xlsx"
# 1. 加載工作簿
wb = load_workbook(input_file)
ws = wb.active
# 2. 定義樣式對象
# 標題行字體:微軟雅黑,12號,加粗,白色
title_font = Font(name='微軟雅黑', size=12, bold=True, color='FFFFFF')
# 標題行背景:藍色
title_fill = PatternFill(start_color='4472C4', fill_type='solid')
# 數(shù)據(jù)行字體:微軟雅黑,11號
data_font = Font(name='微軟雅黑', size=11)
# 細邊框
thin_border = Border(
left=Side(style='thin'),
right=Side(style='thin'),
top=Side(style='thin'),
bottom=Side(style='thin')
)
# 居中對齊
center_align = Alignment(horizontal='center', vertical='center')
# 左對齊(適合文本列)
left_align = Alignment(horizontal='left', vertical='center')
# 3. 獲取數(shù)據(jù)范圍
max_row = ws.max_row
max_col = ws.max_column
if max_row < 1:
print(f"警告: {input_file} 沒有數(shù)據(jù)")
return
# 4. 格式化標題行(第一行)
for col in range(1, max_col + 1):
cell = ws.cell(row=1, column=col)
cell.font = title_font
cell.fill = title_fill
cell.border = thin_border
cell.alignment = center_align
# 5. 格式化數(shù)據(jù)行(第二行到最后)
for row in range(2, max_row + 1):
for col in range(1, max_col + 1):
cell = ws.cell(row=row, column=col)
cell.font = data_font
cell.border = thin_border
# 文本列左對齊,數(shù)字列居中
if isinstance(cell.value, (int, float)):
cell.alignment = center_align
else:
cell.alignment = left_align
# 6. 自動調(diào)整列寬
for col in range(1, max_col + 1):
max_length = 0
column_letter = ws.cell(row=1, column=col).column_letter
for row in range(1, max_row + 1):
cell_value = ws.cell(row=row, column=col).value
if cell_value:
cell_length = len(str(cell_value))
if cell_length > max_length:
max_length = cell_length
# 設(shè)置列寬(最大 30,最小 10)
adjusted_width = min(max(max_length + 2, 10), 30)
ws.column_dimensions[column_letter].width = adjusted_width
# 7. 凍結(jié)首行(滾動時標題行固定不動)
ws.freeze_panes = 'A2'
# 8. 保存
wb.save(output_file)
print(f"格式化完成: {output_file}")
# ==================== 批量格式化 ====================
def batch_format_excel_files(folder_path):
"""
批量格式化文件夾中的所有 Excel 文件
"""
count = 0
for filename in os.listdir(folder_path):
if filename.endswith('.xlsx') and '已格式化' not in filename:
file_path = os.path.join(folder_path, filename)
format_excel_sheet(file_path)
count += 1
print(f"\n批量格式化完成!共處理 {count} 個文件")
# ==================== 使用示例 ====================
if __name__ == "__main__":
# 單個文件格式化
# format_excel_sheet("原始數(shù)據(jù).xlsx")
# 批量格式化文件夾
batch_format_excel_files(r"D:\待格式化報表")
代碼逐行解析
1. 樣式對象定義
openpyxl 中的樣式是可復(fù)用的對象:
title_font = Font(name='微軟雅黑', size=12, bold=True, color='FFFFFF')
Font 參數(shù)說明:
| 參數(shù) | 說明 | 示例值 |
|---|---|---|
name | 字體名稱 | ‘微軟雅黑’, ‘Arial’, ‘宋體’ |
size | 字號 | 11, 12, 14 |
bold | 是否加粗 | True / False |
italic | 是否斜體 | True / False |
color | 字體顏色(HEX 六位碼) | ‘FFFFFF’(白色), ‘FF0000’(紅色) |
2. 背景色填充
title_fill = PatternFill(start_color='4472C4', fill_type='solid')
start_color:填充顏色(HEX 色值)fill_type='solid':純色填充
常用顏色對照:
4472C4:Office 藍色C00000:紅色70AD47:綠色FFC000:橙色E2EFDA:淺綠色
3. 邊框設(shè)置
thin_border = Border(
left=Side(style='thin'),
right=Side(style='thin'),
top=Side(style='thin'),
bottom=Side(style='thin')
)
Side 的 style 可選值:'thin', 'medium', 'thick', 'double', 'dashed', 'dotted'
4. 自動列寬計算
adjusted_width = min(max(max_length + 2, 10), 30)
這段代碼的邏輯:
max_length + 2:最長字符長度 + 2 的余量max(..., 10):最小列寬為 10min(..., 30):最大列寬為 30(防止個別超長文本把列拉得太寬)
5. 凍結(jié)首行
ws.freeze_panes = 'A2'
凍結(jié) A2 單元格上方的行(即第一行),滾動數(shù)據(jù)時標題行始終可見。
進階技巧
技巧 1:條件格式——自動高亮異常值
from openpyxl.formatting.rule import CellIsRule
# 高亮負數(shù)(紅色背景)
ws.conditional_formatting.add(
f'B2:B{max_row}',
CellIsRule(
operator='lessThan',
formula=['0'],
fill=PatternFill(start_color='FFC7CE', fill_type='solid')
)
)
技巧 2:隔行變色(斑馬紋)
light_fill = PatternFill(start_color='F2F2F2', fill_type='solid')
for row in range(2, max_row + 1):
if row % 2 == 0: # 偶數(shù)行
for col in range(1, max_col + 1):
ws.cell(row=row, column=col).fill = light_fill
技巧 3:從模板復(fù)制格式
如果公司已有標準模板,可以先復(fù)制模板再寫入數(shù)據(jù):
import shutil
shutil.copy("公司標準模板.xlsx", output_file)
wb = load_workbook(output_file)
ws = wb.active
# 此時已有模板的所有格式,只需寫入數(shù)據(jù)即可
for row_idx, row_data in enumerate(data_rows, start=2):
for col_idx, value in enumerate(row_data, start=1):
ws.cell(row=row_idx, column=col_idx, value=value)
常見問題
Q1:保存時報錯ValueError: Max value is 255
原因:openpyxl 對舊版 .xls 格式支持有限。
解決:確保文件是 .xlsx 格式。如果是 .xls,先用 Excel 另存為 .xlsx。
Q2:中文顯示為方框(亂碼)?
原因:系統(tǒng)缺少對應(yīng)字體。
解決:改用通用字體:
title_font = Font(name='Arial Unicode MS', size=12, bold=True) # 或 title_font = Font(name='SimSun', size=12, bold=True) # 宋體
Q3:如何設(shè)置行高?
# 設(shè)置第一行行高為 25
ws.row_dimensions[1].height = 25
# 批量設(shè)置所有數(shù)據(jù)行行高
for row in range(1, max_row + 1):
ws.row_dimensions[row].height = 20
總結(jié)
| 格式需求 | openpyxl 類 | 關(guān)鍵參數(shù) |
|---|---|---|
| 字體 | Font() | name, size, bold, color |
| 背景色 | PatternFill() | start_color, fill_type |
| 邊框 | Border() + Side() | style=‘thin’/‘medium’ |
| 對齊 | Alignment() | horizontal, vertical |
| 列寬 | column_dimensions[].width | 數(shù)值 |
| 行高 | row_dimensions[].height | 數(shù)值 |
| 凍結(jié)窗格 | freeze_panes | 單元格地址如 ‘A2’ |
本節(jié)掌握了用 Python 自動控制 Excel 格式的能力。配合前兩節(jié)的合并和拆分,你已經(jīng)可以處理大部分 Excel 批量操作場景。
以上就是使用Python的openpyxl庫批量格式化Excel文件的方法的詳細內(nèi)容,更多關(guān)于Python openpyxl格式化Excel文件的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python數(shù)據(jù)分析之DateFrame數(shù)據(jù)排序和排名方式
這篇文章主要介紹了python數(shù)據(jù)分析之DateFrame數(shù)據(jù)排序和排名方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05
Python內(nèi)置函數(shù)all()的實現(xiàn)
Python內(nèi)置函數(shù)?all()?用于判斷可迭代對象中的所有元素是否都為真值(Truthy),是邏輯判斷的重要工具,下面就來具體介紹如何使用,感興趣的可以了解一下2025-04-04

