👉 点关注,不迷路 👈
⭐️ 第一时间获取更新 ⭐️
⭐️ 第一时间获取更新 ⭐️
大家好,我们专注于办公自动化项目定制开发,关注我们,了解更多办公自动化知识和案例。
一、Excel 中单元格和区域的概念
1. 单元格(Cell)
Excel 表格中最小的存储单位
由 行 和 列 交叉形成
每个单元格有唯一的 坐标(如 A1、B3、Z100)
列:A B C D ...行:1 2 3 4 ...A列 B列 C列行1 A1 B1 C1行2 A2 B2 C2行3 A3 B3 C3
单元格的三大属性:
cell.coordinate | ||
cell.row | ||
cell.column |
from openpyxl import Workbookwb = Workbook()ws = wb.activecell = ws["C5"]print(f"坐标:{cell.coordinate}") # C5print(f"行号:{cell.row}") # 5print(f"列号:{cell.column}") # 3
单元格的数据类型:
str | ||
intfloat | ||
datetime | ||
str= 开头 | ||
bool | ||
None |
2. 区域(Range)
由 连续多个单元格组成的矩形范围。
通过 左上角坐标 和 右下角坐标 定义
区域 A1:B3 表示从 A1 到 B3 的矩形区域A B C1 [A1] [B1] C12 [A2] [B2] C23 [A3] [B3] C3↑ ↑左上角 右下角单元格总数 = 3行 × 2列 = 6 个单元格
区域的常用表示方法:
A1:A1 | ||
A1:B3 | ||
A:A | ||
1:1 | ||
A:C | ||
A1:C1 | ||
A1:A3 |
from openpyxl import Workbookwb = Workbook()ws = wb.active# 获取区域中的所有单元格range_a1_c3 = ws["A1:C3"]for row in range_a1_c3:for cell in row:print(f"{cell.coordinate} ", end="")print()# 输出:# A1 B1 C1# A2 B2 C2# A3 B3 C3
3. 行和列
行(Row):
水平方向的一组单元格,用数字标识:1, 2, 3, ...
最大行数:1,048,576(一百零四万八千五百七十六)(Excel 2007+)
列(Column):
垂直方向的一组单元格,用字母标识:A, B, C, ..., Z, AA, AB, ...
最大列数:XFD(16,384列)
列号索引相互转换:
from openpyxl.utils import get_column_letter, column_index_from_stringprint(get_column_letter(1)) # Aprint(get_column_letter(27)) # AAprint(get_column_letter(16384)) # XFDprint(column_index_from_string("A")) # 1print(column_index_from_string("AA")) # 27
4. openpyxl 中的对应操作
ws["A1"] | ||
ws["A1"].value | ||
ws["A1:B3"] | ||
ws[1] | ||
ws["A"] | ||
ws.iter_rows(min_row=1, max_row=5) | ||
ws.iter_cols(min_col=1, max_col=3) |
# 完整演示from openpyxl import Workbookwb = Workbook()ws = wb.active# 写入示例数据for i in range(1, 6):for j in range(1, 5):ws.cell(row=i, column=j, value=f"R{i}C{j}")# 获取单个单元格cell = ws["B2"]print(f"B2的值:{cell.value}")# 获取区域 B2:C4for row in ws["B2:C4"]:for cell in row:print(cell.value, end=" ")print()# 获取整行(第3行)for cell in ws[3]:print(cell.value, end=" ")# 获取整列(B列)for cell in ws["B"]:print(cell.value)
二、四种单元格访问方式
from openpyxl import Workbookwb = Workbook()ws = wb.active# 方式1:字典式(最常用)ws["A1"] = "方式1"# 方式2:cell方法(适合用变量)row_num = 2ws.cell(row=row_num, column=1, value="方式2")# 方式3:先获取cell对象再赋值cell = ws["A3"]cell.value = "方式3"# 方式4:区域赋值(批量)for r in range(4, 7):ws[f"A{r}"] = f"第{r}行"wb.save("单元格访问方式.xlsx")
方式对比:
ws["A1"] | ||
ws.cell(row, col) | ||
ws["A1:C3"] |
三、批量写入数据
方法1:循环 + cell(适合复杂逻辑)
data = [["姓名", "数学", "语文", "英语"],["张三", 90, 85, 88],["李四", 78, 92, 80],["王五", 95, 89, 91]]for row_idx, row_data in enumerate(data, start=1):for col_idx, value in enumerate(row_data, start=1):ws.cell(row=row_idx, column=col_idx, value=value)
方法2:append(最高效,推荐)
ws.append(["姓名", "数学", "语文", "英语"])ws.append(["张三", 90, 85, 88])ws.append(["李四", 78, 92, 80])ws.append(["王五", 95, 89, 91])
方法3:列表推导式批量写入列
# 从 B2 开始写入 10 个数字for i in range(1, 11):ws.cell(row=i+1, column=2, value=i * 10)
四、批量读取数据
方法1:遍历行列号
for row in range(1, ws.max_row + 1):for col in range(1, ws.max_column + 1):value = ws.cell(row, col).valueprint(value, end=" ")print()
方法2:iter_rows(推荐)
# 遍历所有有数据的行for row in ws.iter_rows(values_only=True):print(row) # row 是一个元组# 指定范围遍历for row in ws.iter_rows(min_row=2, max_row=5, min_col=1, max_col=3, values_only=True):print(row)
方法3:iter_cols(按列遍历)
for col in ws.iter_cols(min_row=1, max_row=10, min_col=1, max_col=3, values_only=True):print(col)
iter_rows / iter_cols 参数说明:
min_row | ||
max_row | ||
min_col | ||
max_col | ||
values_only |
五、完整实战:学生成绩表
from openpyxl import Workbookfrom openpyxl import load_workbook# ========== 1. 创建并写入数据 ==========wb = Workbook()ws = wb.activews.title = "成绩表"# 写入表头headers = ["学号", "姓名", "数学", "语文", "英语", "总分"]ws.append(headers)# 写入学生数据students = [[1, "张三", 90, 85, 88],[2, "李四", 78, 92, 80],[3, "王五", 95, 89, 91],[4, "赵六", 82, 79, 85],[5, "小明", 88, 94, 87],]for student in students:ws.append(student)# 计算总分for row in range(2, ws.max_row + 1):math = ws.cell(row=row, column=3).valuechinese = ws.cell(row=row, column=4).valueenglish = ws.cell(row=row, column=5).valuetotal = math + chinese + englishws.cell(row=row, column=6, value=total)wb.save("学生成绩表.xlsx")print("成绩表生成完成")# ========== 2. 读取并统计分析 ==========wb = load_workbook("学生成绩表.xlsx")ws = wb["成绩表"]print("=== 学生成绩列表 ===")for row in ws.iter_rows(min_row=2, values_only=True):if row[0] is not None:print(f"学号:{row[0]}, 姓名:{row[1]}, 总分:{row[5]}")# 统计平均分total_score = 0student_count = 0for row in ws.iter_rows(min_row=2, max_col=6, values_only=True):if row[5] is not None:total_score += row[5]student_count += 1if student_count > 0:avg_score = total_score / student_countprint(f"\n班级平均分:{avg_score:.2f}")ws["H1"] = "班级平均分"ws["H2"] = avg_score# ========== 3. 按列统计各科平均分 ==========math_scores = []chinese_scores = []english_scores = []for row in ws.iter_rows(min_row=2, min_col=3, max_col=5, values_only=True):math_scores.append(row[0])chinese_scores.append(row[1])english_scores.append(row[2])def average(nums):return sum(nums) / len(nums) if nums else 0print(f"数学平均分:{average(math_scores):.2f}")print(f"语文平均分:{average(chinese_scores):.2f}")print(f"英语平均分:{average(english_scores):.2f}")# 写入统计结果ws["A8"] = "科目"ws["B8"] = "数学"ws["C8"] = "语文"ws["D8"] = "英语"ws["A9"] = "平均分"ws["B9"] = average(math_scores)ws["C9"] = average(chinese_scores)ws["D9"] = average(english_scores)wb.save("学生成绩表_带统计.xlsx")print("统计分析完成")
六、独立练习:销售数据统计
任务:
创建「销售数据.xlsx」,包含工作表「一季度」
写入以下数据(使用 append):
计算每个月的合计
计算每个产品的季度总销量
将季度总销量写入表格下方
参考答案框架:
from openpyxl import Workbookwb = Workbook()ws = wb.activews.title = "一季度"# 写入表头和数据(合计列先留空)ws.append(["月份", "产品A", "产品B", "产品C", "合计"])data = [["1月", 100, 200, 150],["2月", 120, 180, 170],["3月", 110, 210, 160]]for row in data:ws.append(row)# 计算每月合计for row in range(2, 5):a = ws.cell(row=row, column=2).valueb = ws.cell(row=row, column=3).valuec = ws.cell(row=row, column=4).valuews.cell(row=row, column=5, value=a + b + c)# 计算各产品季度总和sum_a = sum(ws.cell(row=r, column=2).value for r in range(2, 5))sum_b = sum(ws.cell(row=r, column=3).value for r in range(2, 5))sum_c = sum(ws.cell(row=r, column=4).value for r in range(2, 5))ws.append(["季度合计", sum_a, sum_b, sum_c, ""])wb.save("销售数据.xlsx")print("完成")
七、常见错误与解决方法
TypeError: 'NoneType' object is not subscriptable | if value is not None 判断 | |
int(value) 转换 | ||
iter_rows | values_only=True | values_only=True |
max_row | max_row 或先判断 |
八、性能提示
# ❌ 慢:逐个单元格赋值for i in range(1, 10000):ws.cell(row=i, column=1, value=i)# ✅ 快:使用 appendfor i in range(1, 10000):ws.append([i])# ✅ 更快:批量构建后一次性写入data = [[i] for i in range(1, 10000)]for row in data:ws.append(row)
性能对比:
逐个单元格:10000行 ≈ 3秒
使用 append:10000行 ≈ 0.3秒
九、自我实战
作业:商品库存管理系统
创建「库存.xlsx」,包含「库存表」工作表
写入以下数据:
计算「库存总价」= 进货价 × 库存数量
计算所有商品的总库存价值
找出库存数量最多的商品(输出到控制台)
新增一行「合计」,统计进货价总额、销售价总额、库存总价总额
扩展挑战:
计算平均毛利率 = (销售价 - 进货价) / 销售价 × 100%,写入新列
十、核心知识点速查表
ws["A1"].value | |
ws["A1"] = "值" | |
ws["A1:B3"] | |
ws.iter_rows(values_only=True) | |
ws.iter_cols(values_only=True) | |
ws.append([1,2,3]) | |
ws[3] | |
ws["B"] | |
get_column_letter(27)"AA" | |
column_index_from_string("AA")27 |
夜雨聆风