当前位置: 首页 > news >正文

Day12-python文件操作(二)

目录

  • 前言
  • 一、Excel文档操作
    • 1.1、`xlrd`和`xlwt`库
    • 1.2、`openpyxl`库
    • 1.3、`pandas`库
  • 总结


前言

今天继续学习文件操作相关内容,为后续办公自动化打基础。


一、Excel文档操作

1.1、xlrdxlwt

如果要兼容 Excel 2007 以前的版本,也就是xls格式的 Excel 文件,可以使用三方库xlrdxlwtxlrd用于读Excel文件,xlwt用于写Excel文件。

  • 安装库
pip install xlrd==1.2.0  # 必须指定版本以支持.xlsx格式
pip install xlwt
  • 使用xlrd读取文件内容
 import xlrd# 1. 打开Excel文件
# formatting_info=True 保留格式信息(会增加内存占用)
workbook = xlrd.open_workbook('example.xls', formatting_info=False)# 2. 工作表操作
print("所有工作表名称:", workbook.sheet_names())  # 获取所有工作表名称# 获取工作表的3种方式
sheet1 = workbook.sheet_by_index(0)  # 通过索引获取(从0开始)
sheet2 = workbook.sheet_by_name('Sheet2')  # 通过名称获取
# sheet3 = workbook.sheets()[2]  # 通过列表索引获取# 获取当前工作表信息
current_sheet = sheet1
print(f"\n当前工作表: {current_sheet.name}")
print(f"行数: {current_sheet.nrows}")
print(f"列数: {current_sheet.ncols}")# 3. 读取单元格数据
# 方式1: 通过行列索引(row, col均从0开始)
cell_value1 = current_sheet.cell_value(0, 0)  # 第1行第1列
cell_value2 = current_sheet.cell(1, 2).value  # 先获取单元格对象再取 value# 方式2: 通过行对象获取
row = current_sheet.row(2)  # 获取第3行所有单元格对象
cell_value3 = row[1].value  # 第3行第2列# 方式3: 通过列对象获取
col = current_sheet.col(0)  # 获取第1列所有单元格对象
cell_value4 = col[3].value  # 第4行第1列print(f"\n单元格数据示例:")
print(f"A1: {cell_value1}, B2: {cell_value2}, B3: {cell_value3}, A4: {cell_value4}")# 4. 批量读取数据
print("\n读取所有行数据:")
for row_idx in range(current_sheet.nrows):# 获取整行值(返回列表)row_values = current_sheet.row_values(row_idx)print(f"第{row_idx+1}行: {row_values}")print("\n读取指定范围数据(第2-4行,第1-3列):")
for row_idx in range(1, 4):  # 行索引1到3(对应第2到4行)row_data = []for col_idx in range(0, 3):  # 列索引0到2(对应第1到3列)row_data.append(current_sheet.cell_value(row_idx, col_idx))print(row_data)# 5. 处理日期类型数据
# Excel日期在xlrd中会被识别为浮点数,需要转换
if current_sheet.cell_type(2, 3) == xlrd.XL_CELL_DATE:date_value = xlrd.xldate_as_datetime(current_sheet.cell_value(2, 3), workbook.datemode)print(f"\n转换后的日期: {date_value.strftime('%Y-%m-%d')}")# 6. 处理不同数据类型
print("\n单元格数据类型示例:")
cell_types = {xlrd.XL_CELL_EMPTY: "空值",xlrd.XL_CELL_TEXT: "文本",xlrd.XL_CELL_NUMBER: "数字",xlrd.XL_CELL_DATE: "日期",xlrd.XL_CELL_BOOLEAN: "布尔值",xlrd.XL_CELL_ERROR: "错误"
}
for col_idx in range(4):cell = current_sheet.cell(1, col_idx)print(f"B{col_idx+1} 类型: {cell_types[cell.ctype]}, 值: {cell.value}")
  • 使用xlwt写入内容
import xlwt
from datetime import datetime# 1. 创建工作簿
# encoding设置编码,确保中文正常显示
workbook = xlwt.Workbook(encoding='utf-8')# 2. 添加工作表
sheet1 = workbook.add_sheet('学生信息', cell_overwrite_ok=True)  # 允许覆盖单元格
sheet2 = workbook.add_sheet('成绩表')# 3. 设置单元格样式
# 创建基础样式
base_style = xlwt.XFStyle()# 创建字体对象
font = xlwt.Font()
font.name = '宋体'
font.bold = True  # 加粗
font.height = 20 * 12  # 字体大小(20为基数,12表示12号字)
font.colour_index = 2  # 红色(参考xlwt.Style.colour_map)# 创建对齐对象
alignment = xlwt.Alignment()
alignment.horz = xlwt.Alignment.HORZ_CENTER  # 水平居中
alignment.vert = xlwt.Alignment.VERT_CENTER  # 垂直居中# 创建边框对象
borders = xlwt.Borders()
borders.left = xlwt.Borders.THIN  # 细边框
borders.right = xlwt.Borders.THIN
borders.top = xlwt.Borders.THIN
borders.bottom = xlwt.Borders.THIN# 创建表头样式(组合上述设置)
header_style = xlwt.XFStyle()
header_style.font = font
header_style.alignment = alignment
header_style.borders = borders# 创建日期样式
date_style = xlwt.XFStyle()
date_style.num_format_str = 'yyyy-mm-dd'  # 日期格式# 4. 写入数据
# 写入表头
headers = ['学号', '姓名', '性别', '出生日期', '班级']
for col, header in enumerate(headers):sheet1.write(0, col, header, header_style)  # 行索引, 列索引, 值, 样式# 写入数据行
students = [('001', '张三', '男', datetime(2005, 3, 15), '高一(1)班'),('002', '李四', '女', datetime(2005, 7, 22), '高一(1)班'),('003', '王五', '男', datetime(2004, 11, 5), '高一(2)班')
]for row, student in enumerate(students, start=1):  # 从第2行开始写入sheet1.write(row, 0, student[0])  # 学号sheet1.write(row, 1, student[1])  # 姓名sheet1.write(row, 2, student[2])  # 性别# 写入日期(应用日期样式)sheet1.write(row, 3, student[3], date_style)sheet1.write(row, 4, student[4])  # 班级# 5. 合并单元格
# 合并第6行的第0-4列(行索引5,列索引0到4)
sheet1.write_merge(5, 5, 0, 4, '全体学生名单', header_style)# 6. 设置列宽
# 列宽单位为1/256个字符宽度
sheet1.col(0).width = 256 * 10  # 学号列宽10个字符
sheet1.col(1).width = 256 * 8   # 姓名列宽8个字符
sheet1.col(3).width = 256 * 12  # 日期列宽12个字符# 7. 写入公式(在成绩表中)
sheet2.write(0, 0, '姓名', header_style)
sheet2.write(0, 1, '语文', header_style)
sheet2.write(0, 2, '数学', header_style)
sheet2.write(0, 3, '总分', header_style)# 写入成绩数据
scores = [('张三', 90, 85),('李四', 95, 92),('王五', 88, 90)
]for row, score in enumerate(scores, start=1):sheet2.write(row, 0, score[0])sheet2.write(row, 1, score[1])sheet2.write(row, 2, score[2])# 写入求和公式sheet2.write(row, 3, xlwt.Formula(f'B{row+1}+C{row+1}'))  # 注意Excel行号从1开始# 8. 保存文件
workbook.save('student_info.xls')
print("文件保存成功!")
  • 读写混合操作
import xlrd
import xlwt
from xlrd import xldate_as_datetime# 1. 使用xlrd读取源文件
source_workbook = xlrd.open_workbook('scores_source.xls')
source_sheet = source_workbook.sheet_by_name('期中成绩')# 2. 处理数据(计算平均分和总分)
processed_data = []# 读取表头
headers = source_sheet.row_values(0)
headers.extend(['总分', '平均分'])  # 添加新列
processed_data.append(headers)# 处理数据行
for row_idx in range(1, source_sheet.nrows):row_data = source_sheet.row_values(row_idx)name = row_data[0]scores = row_data[1:]  # 提取所有成绩# 计算总分和平均分total = sum(scores)average = total / len(scores) if scores else 0# 添加到处理后的数据row_data.extend([total, round(average, 1)])processed_data.append(row_data)# 3. 使用xlwt写入新文件
result_workbook = xlwt.Workbook(encoding='utf-8')
result_sheet = result_workbook.add_sheet('成绩统计', cell_overwrite_ok=True)# 创建样式
header_font = xlwt.Font()
header_font.bold = True
header_style = xlwt.XFStyle()
header_style.font = header_font# 写入数据
for row_idx, row in enumerate(processed_data):for col_idx, value in enumerate(row):# 表头应用样式style = header_style if row_idx == 0 else xlwt.XFStyle()result_sheet.write(row_idx, col_idx, value, style)# 设置列宽
for col_idx in range(len(headers)):result_sheet.col(col_idx).width = 256 * 10# 4. 保存结果
result_workbook.save('scores_processed.xls')
print("数据处理完成,已保存到 scores_processed.xls")

1.2、openpyxl

读写 Excel 2007 + 的.xlsx 文件,一般使用openpyxl库。

  • 安装库
pip install openpyxl
  • 读取
from openpyxl import load_workbook# 加载Excel文件
# read_only=True:只读模式,提高大型文件读取效率
# data_only=True:读取单元格计算后的值(而非公式本身)
wb = load_workbook('example.xlsx', read_only=False, data_only=False)# 查看所有工作表
print("工作表列表:", wb.sheetnames)# 选择工作表(3种方式)
sheet = wb['Sheet1']  # 通过名称选择
# sheet = wb.active  # 选择当前活动工作表
# sheet = wb[wb.sheetnames[0]]  # 通过索引选择# 获取工作表基本信息
print(f"当前工作表: {sheet.title}")
print(f"最大行数: {sheet.max_row}")
print(f"最大列数: {sheet.max_column}")# 读取单元格数据(2种方式)
print("\n单元格数据:")
print(f"A1的值: {sheet['A1'].value}")  # 通过单元格坐标
print(f"第2行第3列的值: {sheet.cell(row=2, column=3).value}")  # 通过行列号(从1开始)# 批量读取行数据
print("\n读取前5行数据:")
for row in sheet.iter_rows(min_row=1, max_row=5, values_only=True):# values_only=True:只返回值,不返回单元格对象print(row)# 批量读取列数据
print("\n读取前3列数据:")
for col in sheet.iter_cols(min_col=1, max_col=3, min_row=1, max_row=5, values_only=True):print(col)# 关闭工作簿(只读模式必须关闭)
if wb.read_only:wb.close()
  • 创建
from openpyxl import Workbook
from datetime import datetime# 创建工作簿
wb = Workbook()# 获取默认工作表(默认名为Sheet)
sheet = wb.active
sheet.title = "销售数据"  # 修改工作表名称# 写入表头
headers = ["日期", "产品", "销量", "单价", "销售额"]
for col, header in enumerate(headers, 1):  # 列号从1开始sheet.cell(row=1, column=col).value = header# 写入数据行
data = [(datetime(2023, 10, 1), "手机", 50, 3000, 150000),(datetime(2023, 10, 1), "电脑", 20, 5000, 100000),(datetime(2023, 10, 2), "平板", 30, 2000, 60000),
]for row, item in enumerate(data, 2):  # 行号从2开始for col, value in enumerate(item, 1):sheet.cell(row=row, column=col).value = value# 插入公式(计算总销售额)
last_row = sheet.max_row + 1  # 最后一行的下一行
sheet.cell(row=last_row, column=1).value = "总计"
sheet.cell(row=last_row, column=5).value = f"=SUM(E2:E{last_row-1})"  # 求和公式# 保存文件
wb.save("sales_data.xlsx")
print("文件已保存为 sales_data.xlsx")
  • 修改
from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill# 加载现有文件
wb = load_workbook("products.xlsx")
sheet = wb.active# 1. 遍历并修改数据(为价格低于100的商品标红)
red_font = Font(color="FF0000", bold=True)
for row in range(2, sheet.max_row + 1):  # 从第2行开始(跳过表头)price_cell = sheet.cell(row=row, column=3)  # 假设价格在第3列if price_cell.value and price_cell.value < 100:price_cell.font = red_font  # 价格标红# 添加备注sheet.cell(row=row, column=4).value = "促销商品"# 2. 添加新数据
new_products = [(104, "无线鼠标", 89, "促销商品"),(105, "机械键盘", 299, ""),
]
for product in new_products:sheet.append(product)# 3. 添加汇总行
last_row = sheet.max_row + 1
sheet.cell(row=last_row, column=1).value = "总计"
sheet.cell(row=last_row, column=3).value = f"=SUM(C2:C{last_row-1})"  # 计算总价
# 设置汇总行样式
total_fill = PatternFill(fill_type="solid", fgColor="FFFFCC")
for col in range(1, 4):sheet.cell(row=last_row, column=col).fill = total_fill# 保存修改
wb.save("products_updated.xlsx")
print("文件已更新为 products_updated.xlsx")
  • 样式设置
from openpyxl import Workbook
from openpyxl.styles import (Font, Alignment, Border, Side, PatternFill, GradientFill, Color
)# 创建工作簿和工作表
wb = Workbook()
sheet = wb.active
sheet.title = "样式示例"# 1. 定义样式组件
# 字体(名称、大小、加粗、颜色)
title_font = Font(name="微软雅黑",size=14,bold=True,color=Color(rgb="FFFFFF")  # 白色(RGB格式)
)
header_font = Font(name="宋体", size=12, bold=True)# 对齐方式(水平、垂直、自动换行)
center_align = Alignment(horizontal="center",vertical="center",wrap_text=True  # 自动换行
)# 边框(线条样式、颜色)
thin_border = Border(left=Side(style="thin", color="CCCCCC"),right=Side(style="thin", color="CCCCCC"),top=Side(style="thin", color="CCCCCC"),bottom=Side(style="thin", color="CCCCCC")
)# 填充(纯色或渐变)
title_fill = PatternFill(fill_type="solid",fgColor=Color(rgb="2E7D32")  # 深绿色
)
header_fill = PatternFill(fill_type="solid",fgColor=Color(rgb="E8F5E9")  # 浅绿色
)# 2. 应用样式
# 标题行(合并单元格)
sheet.merge_cells(start_row=1, start_column=1, end_row=1, end_column=4)
title_cell = sheet.cell(row=1, column=1)
title_cell.value = "员工信息表"
title_cell.font = title_font
title_cell.alignment = center_align
title_cell.fill = title_fill# 表头行
headers = ["ID", "姓名", "部门", "入职日期"]
for col, header in enumerate(headers, 1):cell = sheet.cell(row=2, column=col)cell.value = headercell.font = header_fontcell.alignment = center_aligncell.fill = header_fillcell.border = thin_border# 数据行
data = [(101, "张三", "技术部", "2020-01-15"),(102, "李四", "市场部", "2021-03-20"),(103, "王五", "人事部", "2022-05-10"),
]for row, item in enumerate(data, 3):for col, value in enumerate(item, 1):cell = sheet.cell(row=row, column=col)cell.value = valuecell.alignment = center_aligncell.border = thin_border# 3. 调整列宽
sheet.column_dimensions["A"].width = 8  # ID列
sheet.column_dimensions["B"].width = 12  # 姓名列
sheet.column_dimensions["C"].width = 15  # 部门列
sheet.column_dimensions["D"].width = 12  # 日期列# 保存文件
wb.save("styled_example.xlsx")
print("带样式的文件已保存为 styled_example.xlsx")

1.3、pandas

pandas 本身不直接处理 Excel 文件,需要依赖第三方库:

  • 处理 .xlsx 格式:openpyxl(写入)、xlrd(读取,旧版本支持)
  • 处理 .xls 格式:xlrd==1.2.0(新版本已移除对 xls 的支持)
  • 安装库
# 安装基础依赖(处理 xlsx)
pip install pandas openpyxl# 如需处理 xls 格式,额外安装
pip install xlrd==1.2.0
  • 读取 Excel 文件(read_excel)
    pd.read_excel() 是读取 Excel 的核心函数,支持多种参数控制读取范围和方式。
import pandas as pd# 1. 基本读取(默认读取第一个工作表)
df = pd.read_excel('data.xlsx')
print("基本读取结果(前5行):")
print(df.head())# 2. 读取指定工作表
# 通过工作表名称
df_sheet2 = pd.read_excel('data.xlsx', sheet_name='销售数据')
# 通过索引(0表示第一个工作表)
df_sheet3 = pd.read_excel('data.xlsx', sheet_name=2)# 3. 读取指定行列范围
df_range = pd.read_excel('data.xlsx',sheet_name='Sheet1',header=0,                # 指定表头行(0表示第1行)skiprows=0,              # 跳过前N行(不包括表头)nrows=10,                # 只读取10行数据usecols='A:C, E',        # 读取A、B、C、E列(支持列名或索引)# usecols=[0,1,2,4],    # 也可以用列索引
)
print("\n指定范围读取结果:")
print(df_range.shape)  # 查看数据形状(行数, 列数)# 4. 数据类型控制
df_dtype = pd.read_excel('data.xlsx',dtype={'订单号': str,       # 避免长数字被科学计数法显示'日期': 'datetime64[ns]',  # 指定日期类型'类别': 'category'   # 类别型数据节省内存},parse_dates=['日期'],    # 自动解析日期列converters={'金额': lambda x: x.replace(',', '')}  # 自定义转换函数
)
print("\n数据类型:")
print(df_dtype.dtypes)# 5. 处理缺失值
df_missing = pd.read_excel('data.xlsx',na_values=['', '无', 'NA'],  # 指定哪些值视为缺失值keep_default_na=False        # 不使用默认缺失值规则
)
print("\n缺失值数量:")
print(df_missing.isnull().sum())# 6. 批量读取多个工作表
# 读取所有工作表(返回字典:{工作表名: DataFrame})
all_sheets = pd.read_excel('data.xlsx', sheet_name=None)
print("\n所有工作表名称:", list(all_sheets.keys()))
  • 写入 Excel 文件(to_excel)
    df.to_excel() 用于将 DataFrame 写入 Excel,配合 ExcelWriter 可实现多工作表写入。
import pandas as pd
import numpy as np# 创建示例数据
data1 = {'姓名': ['张三', '李四', '王五'],'年龄': [25, 30, 35],'部门': ['技术部', '市场部', '人事部']
}
df1 = pd.DataFrame(data1)data2 = {'产品': ['手机', '电脑', '平板'],'销量': [150, 80, 120],'销售额': [450000, 400000, 240000]
}
df2 = pd.DataFrame(data2)# 1. 基本写入(单工作表)
df1.to_excel('output.xlsx',sheet_name='员工信息',  # 工作表名称index=False,           # 不写入索引列header=True,           # 写入表头startrow=0,            # 从第1行开始写入(0表示第一行)startcol=0             # 从第1列开始写入
)# 2. 多工作表写入(使用 ExcelWriter)
with pd.ExcelWriter('multi_sheet.xlsx',engine='openpyxl',     # 引擎选择(xlsx用openpyxl)mode='w'               # 模式:w=新建,a=追加
) as writer:df1.to_excel(writer, sheet_name='员工表', index=False)df2.to_excel(writer, sheet_name='产品表', index=False, startrow=2)  # 从第3行开始# 3. 写入指定列和格式控制
df2.to_excel('formatted.xlsx',sheet_name='销量数据',index=False,columns=['产品', '销售额'],  # 只写入指定列float_format='%.2f',         # 浮点数保留2位小数header=['产品名称', '总销售额']  # 重命名表头
)# 4. 处理日期格式
df_date = pd.DataFrame({'订单号': [1001, 1002, 1003],'下单日期': pd.date_range('2023-10-01', periods=3),'金额': [1500.5, 2300, 980.3]
})with pd.ExcelWriter('date_format.xlsx', engine='openpyxl') as writer:df_date.to_excel(writer, sheet_name='订单', index=False)# 获取工作表对象,进一步设置单元格格式(需结合openpyxl)worksheet = writer.sheets['订单']# 设置日期列(B列)格式为yyyy-mm-ddfrom openpyxl.styles import numbersfor row in range(2, len(df_date)+2):  # 从第2行开始(跳过表头)worksheet.cell(row, 2).number_format = numbers.FORMAT_DATE_YYYYMMDD2print("文件写入完成")
  • 数据处理与 Excel 交互
    pandas 结合 Excel 操作的典型场景,如数据筛选、分组、合并后写入 Excel。
import pandas as pd# 1. 读取数据并预处理
df = pd.read_excel('sales_data.xlsx',parse_dates=['日期'],dtype={'区域': 'category'}
)# 数据清洗
df['销售额'] = df['销售额'].replace(',', '', regex=True).astype(float)  # 清洗金额格式
df = df.dropna(subset=['订单号'])  # 删除订单号为空的行
df['月份'] = df['日期'].dt.to_period('M')  # 提取月份(用于分组)# 2. 数据分析
# 按区域和月份分组,计算销售总额
region_month_sales = df.groupby(['区域', '月份'])['销售额'].sum().reset_index()# 筛选出销售额大于10万的记录
high_sales = df[df['销售额'] > 100000][['订单号', '日期', '区域', '销售额']]# 3. 将处理结果写入Excel的不同工作表
with pd.ExcelWriter('sales_analysis.xlsx', engine='openpyxl') as writer:# 原始数据(前10行预览)df.head(10).to_excel(writer, sheet_name='原始数据预览', index=False)# 区域-月份销售汇总region_month_sales.to_excel(writer, sheet_name='区域月度汇总', index=False)# 高销售额订单high_sales.to_excel(writer, sheet_name='高价值订单', index=False)# 4. 自动调整列宽(结合openpyxl)for sheet_name in writer.sheets:worksheet = writer.sheets[sheet_name]for column_cells in worksheet.columns:# 计算列中最大字符串长度max_length = max(len(str(cell.value)) for cell in column_cells)# 设置列宽(留一些余量)worksheet.column_dimensions[column_cells[0].column_letter].width = max_length + 2print("数据分析结果已保存到 sales_analysis.xlsx")

总结

  1. xlrd负责责,xlwt负责写入。需要注意的是,xlrd从 2.0.0 版本开始不再支持.xlsx 格式,如果要处理不同Excel格式文件,建议安装 1.2.0 版本。
  2. xlwt不支持修改现有文件,只能创建新文件。
  3. openpyxl仅支持.xlsx/.xlsm 格式,不支持旧版.xls 格式。
  4. openpyxl处理大型文件时,使用read_only=True模式读取,write_only=True模式写入会获得较好性能。
  5. openpyxl使用data_only=True时读取公式计算后的值,否则读取公式本身(如=SUM(A1:A10))。
  6. 读写长数字(数字编号)时会变成科学记数法写法,如果要保持原样可以将数据内容设置为字符串。
http://www.dtcms.com/a/357258.html

相关文章:

  • java开发连接websocket接口
  • STM32CubeMX(十八)USB-MSC:外部flash模拟U盘
  • Day17_【机器学习—特征预处理(归一化和标准化)】
  • 期权杂记(二)
  • Hadoop(六)
  • 迁移学习实战:医疗影像识别快速突破方案
  • 【实时Linux实战系列】实时数据可视化技术实现
  • Python OpenCV图像处理与深度学习:Python OpenCV开发环境搭建与入门
  • 嵌入式Linux驱动开发:设备树与平台设备驱动
  • 2023年12月GESP5级C++真题解析,包括选择判断和编程
  • 嵌入式-定时器的输入捕获,超声波获距实验-Day23
  • 如何使用 Vector 连接 Easysearch
  • 【实时Linux实战系列】实时环境监控系统的架构与实现
  • PPT处理控件Aspose.Slides教程:使用 C# 编程将 PPTX 转换为 XML
  • 【实时Linux实战系列】基于实时Linux的虚拟现实应用开发
  • 趣味学Rust基础篇(所有权)
  • 【DeepSeek】公司内网部署离线deepseek+docker+ragflow本地模型实战
  • 《跳出“技术堆砌”陷阱,构建可演进的软件系统》
  • 【PyTorch】神经风格迁移项目
  • 每周资讯 | 《恋与深空》获科隆游戏展2025“最佳移动游戏奖”;8月173个版号下发
  • 【小白笔记】访问GitHub 账户的权限英文单词解释
  • nvm使用和node使用
  • 【前端教程】用 JavaScript 实现4个常用时间与颜色交互功能
  • centos8部署miniconda、nodejs
  • webpack升级
  • 飞牛Nas每天定时加密数据备份到网盘,基于restic的Backrest笔记分享
  • linux和RTOS架构区别
  • 通过 KafkaMQ 接入Skywalking 数据最佳实践
  • JAVA:Spring Boot 集成 Easy Rules 实现规则引擎
  • 滚珠导轨如何赋能精密制造?