如何在Xlsxwriter关闭工作簿前读取已写入的单元格内容?
在Xlsxwriter调用workbook.close()前读取已写入单元格内容的方案
首先得明确一个关键点:Xlsxwriter是一个只写(write-only)的Excel生成库,它的设计目标是高效生成Excel文件,并没有内置的功能来读取已经写入的单元格内容——因为它不会在内存中保留一份可读取的单元格数据副本(你之前尝试的worksheet.table是库内部的私有结构,用来存储格式、单元格类型这类元信息,不是用来存实际值的,依赖它不仅不可靠,还可能因为版本更新失效)。
那怎么解决这个问题呢?其实很简单:自己维护一份和工作表同步的单元格数据副本,每次调用Xlsxwriter的写入方法时,同时把数据存入这个副本里,之后要读取的时候直接从副本里取就行。
具体实现示例
下面是一个完整的实用方案,包含自定义写入、读取和判断单元格是否为空的功能:
from xlsxwriter import Workbook from collections import defaultdict # 创建工作簿和工作表 wb = Workbook('output.xlsx') ws = wb.add_worksheet() # 用defaultdict维护单元格数据,key是行号,value是列号对应的值的字典 cell_data_store = defaultdict(dict) # 封装写入方法,自动同步数据到我们的存储结构 def write_cell(worksheet, row, col, value): # 调用Xlsxwriter原生写入方法 worksheet.write(row, col, value) # 将数据同步存入我们的存储 cell_data_store[row][col] = value # 测试写入一些数据 write_cell(ws, 0, 0, "产品名称") write_cell(ws, 0, 1, "单价") write_cell(ws, 1, 0, "笔记本电脑") write_cell(ws, 1, 1, 5999.99) # 自定义读取方法:获取指定单元格的值,未写入则返回None def get_cell_value(row, col): return cell_data_store[row].get(col, None) # 测试读取 print(get_cell_value(0, 0)) # 输出:产品名称 print(get_cell_value(1, 1)) # 输出:5999.99 print(get_cell_value(2, 0)) # 输出:None(该单元格未写入) # 改进你原来的cell_empty函数,基于我们维护的可靠数据 def cell_empty(row, col_start, col_end=None): if col_end is None: # 检查单个单元格 return get_cell_value(row, col_start) is None else: # 检查指定列范围的单元格 for col in range(col_start, col_end): if get_cell_value(row, col) is not None: return False return True # 测试判断函数 print(cell_empty(0, 0)) # False(已写入) print(cell_empty(0, 2)) # True(未写入) print(cell_empty(1, 0, 2)) # False(区域内有已写入的单元格) print(cell_empty(2, 0, 3)) # True(区域内全未写入) # 最后保存并关闭工作簿 wb.close()
进阶:批量改造现有写入代码
如果你已经写了大量ws.write()的代码,不想逐个改成自定义函数,可以用「猴子补丁」的方式包装原生的write方法,自动同步数据:
# 保存原生的write方法 original_write = ws.write # 定义包装后的write方法 def wrapped_write(row, col, *args, **kwargs): # 提取要写入的值(兼容Xlsxwriter的各种write参数格式) value = args[0] if args else kwargs.get('value') if value is not None: cell_data_store[row][col] = value # 调用原生方法完成写入 return original_write(row, col, *args, **kwargs) # 替换工作表的write方法 ws.write = wrapped_write # 之后正常调用ws.write即可自动同步数据 ws.write(2, 0, "无线鼠标") ws.write(2, 1, 99.9) print(get_cell_value(2, 0)) # 输出:无线鼠标
为什么不推荐依赖内部结构?
你之前尝试的worksheet.table是Xlsxwriter的内部私有结构,它的作用是跟踪单元格的格式、类型等元数据,并不存储实际的单元格值。而且库的开发者可能会在后续版本中修改这个结构的定义,导致你的代码突然失效——所以依赖私有结构是非常不可取的,自己维护数据副本才是稳定可靠的方案。
内容的提问来源于stack exchange,提问作者Aymen Jalal
相关产品推荐
相关产品推荐

