2026-05-25 ·
日常编程 ·
19751
openpyxl写入指定单元格前必须先加载或新建工作表:需通过load_workbook()加载文件并获取ws=wb['Sheet1']或wb.active,或用Workbook()新建后操作wb.active;否则ws为None会导致AttributeError。
写入指定单元格前必须先加载或新建工作表
Openpyxl 不像 pandas 那样能直接“追加”到某个单元格而不关心上下文;它要求你明确操作的是哪个 Worksheet 对象,且该对象必须已存在(从文件加载)或已创建(新建工作簿)。如果跳过这步直接调用 ws['A1'] = value,会报 AttributeError: 'NoneType' object has no attribute '__setitem__'——本质是 ws 为 None。
实操建议:
用 load_workbook() 加载已有 Excel 文件,并通过 wb['Sheet1'] 或 wb.active 获取目标工作表
若从零开始,用 Workbook() 新建,再用 wb.create_sheet() 或直接操作 wb.active
注意:新建的 Workbook() 默认带一个名为 Sheet 的工作表(不是 Sheet1),名称可通过 ws.title 检查
支持三种单元格定位方式:坐标字符串、行列索引、cell() 方法
Openpyxl 提供了灵活但语义不同的写入入口,选错容易覆盖错位置或抛出 ValueError。比如 ws['Z1000'] = 42 看似简单,但如果列号超出 Excel 限制(XFD 列,即 16384 列),运行时不会报错,但保存后 Excel 打开会提示“已修复”,数据可能丢失。
推荐按场景选择:
固定小范围写入(如报告头):直接用坐标字符串,如 ws['B2'] = '模型准确率',可读性高
循环写入行列规律数据:用 ws.cell(row=3, column=5, value=0.92),row 和 column 从 1 开始计数,比手动拼 'E3' 更安全
需要动态计算列号(如第 27 列是 AA):别自己转,直接传 column=27 给 cell(),Openpyxl 内部自动处理
写入数值、字符串、日期、公式要注意类型和格式
Openpyxl 会尝试推断值类型,但不总是可靠。例如把字符串 '123' 写入单元格,Excel 可能自动识别为数字并左对齐变右对齐;把 datetime.datetime 对象写入,若未设置单元格格式,打开后可能显示为一串浮点数(Excel 底层日期序列)。
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
关键控制点:
强制当文本:赋值前加空字符串,如 ws['C4'] = "'" + str(123),或设 ws['C4'].number_format = '@'
日期时间:直接写 datetime 对象即可,但建议同步设格式,如 ws['D5'].number_format = 'yyyy-mm-dd hh:mm'
公式:以 = 开头的字符串,如 ws['E1'] = '=SUM(A1:A10)';注意公式中引用的单元格必须存在,否则打开 Excel 会显示 #REF!
布尔值:写 True/False 即可,Openpyxl 自动映射为 Excel 的 TRUE/FALSE,无需引号
保存前务必调用 wb.save(),且路径不能被 Excel 进程占用
这是最常被忽略的一步:变量赋值只是修改内存中的 Workbook 对象,不触发磁盘写入。没调 wb.save('output.xlsx'),所有操作都白做。更隐蔽的问题是——如果目标文件正被 Excel 程序打开,save() 会抛出 PermissionError: [Errno 13] Permission denied,而不是友好提示。
稳妥做法:
始终在写入逻辑结束后显式调用 wb.save()
避免覆盖正在打开的文件;开发时可用不同文件名测试,如 output_v2.xlsx
若需覆盖原文件,确保 Excel 已关闭,或改用临时路径 + 文件替换(shutil.move())
大文件写入耗时明显,不要在循环里反复 save(),一次写完再存
真正麻烦的不是“怎么写进单元格”,而是“写进去之后 Excel 能不能正常打开、数值有没有被意外转换、别人双击编辑时会不会崩”。Openpyxl 的自由度高,也意味着更多隐式行为要主动干预——尤其是日期格式、数字精度、公式引用范围这些看似细枝末节的地方,往往决定下游是否要手动修半天表格。
本文详解如何使用 ThreadPoolExecutor 和 ProcessPoolExecutor 构建非阻塞、阶段解耦的并发流水线,避免原代码中因 as_completed 顺序等待导致的串行瓶颈,并确保 I/O 与 CPU 密集型任务各司其职、无缝衔接。 本文详解如何使用 `threadpoolexecutor` 和 `processpoolexecutor` 构建非阻塞、阶段解耦的并发流水线...
2026-05-29 · 日常编程 · 222062
根本原因是aioinflux默认逐点发送、未批量提交、连接未复用且并发控制不当;需传入Point列表批量写、复用Client实例、用asyncio.gather/Semaphore控并发、禁用gzip、配连接池及合理超时,并调优InfluxDB服务端限速参数。 为什么直接用 aioinflux 写 InfluxDB 还是慢? 很多人以为换上 aioinflux 就自动“高并发写入”,结果发现吞吐量...
2026-05-29 · 日常编程 · 119128
本文解析 AWS Lambda 环境下 snowflake-connector-python[pandas] 的 write_pandas 出现多份重复记录的根本原因——并非函数本身逻辑缺陷,而是 Lambda 异步调用机制与超时重试策略引发的并发重复执行,并提供可落地的排查路径与工程化防御方案。 本文解析 aws lambda 环境下 `snowflake-connector-python[pa...
2026-05-29 · 日常编程 · 32675
Django的DatabaseRouter仅支持分库,无法自动分表,因其只在查询前选择数据库别名,不干预SQL生成与表名替换,分表需手动处理建表、查询、写入及迁移。 分库分表不能靠 Django 的 DatabaseRouter 完全实现,它只负责“路由到库”,不处理“表拆分逻辑”;真正要分表(比如按时间/用户ID哈希),必须手动干预查询、写入和迁移流程。 为什么 DatabaseRouter 只...
2026-05-28 · 日常编程 · 207431
本文介绍在 Pandas apply() 场景下,如何消除 global 语句依赖,通过可变容器(如字典)或面向对象方式封装跨行计算所需的状态变量,提升代码可测试性、可重入性与线程安全性。 本文介绍在 pandas `apply()` 场景下,如何消除 `global` 语句依赖,通过可变容器(如字典)或面向对象方式封装跨行计算所需的状态变量,提升代码可测试性、可重入性与线程安全性。 在电信计费逻...
本文介绍两种不依赖 global 关键字的优雅方案,将跨函数调用需持续维护的状态(如日期标记和已用分钟数)转为局部可控结构:一是使用可变字典传参,二是封装为有状态类,兼顾可读性、可测试性与线程安全性。 本文介绍两种不依赖 global 关键字的优雅方案,将跨函数调用需持续维护的状态(如日期标记和已用分钟数)转为局部可控结构:一是使用可变字典传参,二是封装为有状态类,兼顾可读性、可测试性与线程安全性...
2026-05-28 · 日常编程 · 167418
本文详解如何基于已有张量 x 的形状,无需预先知晓其维数,构造形如 (k, x.shape) 的新张量——核心是利用 Python 解包语法 *x.shape 将 torch.Size 对象无缝转为位置参数。 本文详解如何基于已有张量 `x` 的形状,**无需预先知晓其维数**,构造形如 `(k, x.shape)` 的新张量——核心是利用 python 解包语法 `*x.shape` 将 `to...
2026-05-27 · 日常编程 · 238884
Flask应用打包前必须确认的三个路径:app.py须置于根目录以避免ModuleNotFoundError;requirements.txt须与Dockerfile同目录或显式指定路径;import路径须适配容器内结构,确保config.py等依赖文件被正确COPY且不在被忽略目录中。 Flask应用打包前必须确认的三个路径 你的 app.py(或主入口文件)不能藏在子目录里,Docker 构建...
2026-05-27 · 日常编程 · 105991
xlsxwriter 必须预定义格式对象再写入,不支持事后补加样式;openpyxl 可先写后设样式,但需注意批量赋值和合并单元格的样式同步问题。 用 xlsxwriter 设置单元格样式必须先创建格式对象 直接对已写入的单元格“补加”样式在 xlsxwriter 中不可行——它只支持“边写边设”,所有样式必须通过 workbook.add_format() 预定义,再传给 write() 或 w...
2026-05-27 · 日常编程 · 123756
importlib.import_module仅支持绝对模块名导入,需确保模块在sys.path中可见或使用完整包路径;若只有文件路径,则应改用importlib.util.spec_from_file_location配合module_from_spec动态加载。 直接用 importlib.import_module 就行,但模块名必须是完整路径(含包层级),不能只传文件名或相对路径。 为什么...
2026-05-27 · 日常编程 · 264734