
影刀RPA Excel单元格读写精确定位与批量操作作者林焱Excel操作是影刀RPA最核心的能力之一。大部分自动化流程都涉及Excel数据的读取或写入——读取配置表、写入采集结果、更新数据状态、生成报表。但很多新手在操作Excel时效率很低逐个单元格读取一百行数据要跑好几分钟写入数据后格式全丢了合并单元格读出来一堆None。这篇文章把Excel单元格读写的正确方法讲全从单格操作到批量操作从影刀指令到Python代码。一、读取单个单元格1.1 用影刀指令读取【读取Excel单元格】 文件路径D:\data\product.xlsx Sheet名Sheet1 单元格A1  → 输出到变量 cell_value坑1Excel文件被占用文件正被其他程序打开读取报错文件被占用。确保读取前文件没有被打开或者用只读模式打开。坑2Sheet名写错Sheet名大小写敏感Sheet1和sheet1不一样。如果不确定Sheet名先用【获取Sheet列表】获取所有Sheet名再操作。1.2 读取带公式的单元格如果单元格里的值是公式计算结果如A1B1影刀读取的是公式还是计算后的值【读取Excel单元格】默认读取计算后的值如果需要读取公式本身用Python节点importopenpyxl wbopenpyxl.load_workbook(D:\\data\\product.xlsx,data_onlyFalse)wswb[Sheet1]# 读取公式formulaws[C1].value# 返回 A1B1# 读取计算后的值需要文件曾被Excel打开保存过wb2openpyxl.load_workbook(D:\\data\\product.xlsx,data_onlyTrue)ws2wb2[Sheet1]valuews2[C1].value# 返回计算结果set_variable(formula,str(formula))set_variable(value,str(value))坑data_onlyTrue读到Noneopenpyxl的data_onlyTrue只能读取被Excel应用计算并保存过的值。如果文件从没被Excel打开过比如用程序生成的公式的计算结果是None。解决方法先用Excel打开保存一次或者用其他方式计算。二、写入单个单元格2.1 用影刀指令写入【写入Excel单元格】 文件路径D:\data\product.xlsx Sheet名Sheet1 单元格A1 写入内容变量 product_name2.2 写入不同类型的数据Excel单元格可以存储文本、数字、日期、布尔值。写入时注意数据类型店群矩阵自动化突破运营极限importopenpyxlfromdatetimeimportdatetime wbopenpyxl.load_workbook(D:\\data\\product.xlsx)wswb[Sheet1]# 写入文本ws[A1]商品名称# 写入数字ws[B1]123.45# 写入日期Excel会自动识别为日期类型ws[C1]datetime(2026,7,1)# 写入公式ws[D1]B1*1.1# 写入布尔值ws[E1]Truewb.save(D:\\data\\product.xlsx)坑数字写成文本如果用影刀【写入Excel单元格】写入数字123Excel可能把它存为文本123而不是数字123。文本数字不能参与计算排序也会出错。解决方法用Python写入时确保数据类型正确或者在写入后设置单元格的数字格式ws[B1]float(123)# 确保是浮点数ws[B1].number_format0.00# 保留两位小数三、批量读取数据3.1 读取区域逐个单元格读取100行数据需要100次操作非常慢。用【读取Excel区域】一次读取【读取Excel区域】 文件路径D:\data\product.xlsx Sheet名Sheet1 区域范围A1:D100 → 输出到变量 data_table二维列表返回的是一个二维列表data_table[0][0]是A1的值data_table[0][1]是B1的值。3.2 读取整个Sheet如果不确定数据有多少行【读取Excel区域】 文件路径D:\data\product.xlsx Sheet名Sheet1 区域范围A1 只填起始单元格自动读到最后一行最后一列 读取方式读取到末尾 → 输出到变量 all_data或者用Pythonimportopenpyxl wbopenpyxl.load_workbook(D:\\data\\product.xlsx)wswb[Sheet1]# 读取所有数据data[]forrowinws.iter_rows(values_onlyTrue):data.append(list(row))set_variable(all_data,data)3.3 用pandas读取推荐pandas读取Excel更简洁高效importpandasaspd# 读取整个Sheetdfpd.read_excel(D:\\data\\product.xlsx,sheet_nameSheet1)# 读取指定列dfpd.read_excel(D:\\data\\product.xlsx,usecolsA:D)# 读取指定行范围dfpd.read_excel(D:\\data\\product.xlsx,skiprows2,nrows100)# 读取结果转成列表data_listdf.values.tolist()# 读取结果转成字典列表用第一行做keydata_dictdf.to_dict(records)set_variable(data,data_dict)坑pandas读取时第一行被当表头pandas默认把第一行作为列名header。如果第一行不是表头是数据设置headerNonedfpd.read_excel(D:\\data\\product.xlsx,headerNone)四、批量写入数据4.1 写入区域【写入Excel区域】 文件路径D:\data\product.xlsx Sheet名Sheet1 起始单元格A1  写入数据变量 data_table二维列表4.2 用openpyxl批量写入importopenpyxl wbopenpyxl.load_workbook(D:\\data\\product.xlsx)wswb[Sheet1]dataget_variable(data_list)# 从第2行开始写入第1行是表头forrow_idx,row_datainenumerate(data,2):forcol_idx,valueinenumerate(row_data,1):ws.cell(rowrow_idx,columncol_idx,valuevalue)wb.save(D:\\data\\product.xlsx)4.3 用pandas批量写入importpandasaspd dataget_variable(data_list)dfpd.DataFrame(data,columns[商品名,价格,库存,状态])# 写入新文件df.to_excel(D:\\data\\output.xlsx,sheet_name结果,indexFalse)# 追加到已有文件需要用openpyxl引擎fromopenpyxlimportload_workbookimportosifos.path.exists(D:\\data\\output.xlsx):bookload_workbook(D:\\data\\output.xlsx)withpd.ExcelWriter(D:\\data\\output.xlsx,engineopenpyxl,modea)aswriter:writer.bookbook df.to_excel(writer,sheet_name新数据,indexFalse)else:df.to_excel(D:\\data\\output.xlsx,sheet_name新数据,indexFalse)坑pandas写入会覆盖原有Sheetto_excel默认覆盖整个文件。如果要保留原有Sheet需要用modea追加模式或者用ExcelWriter配合openpyxl。五、精确定位单元格5.1 用行列号定位# 第3行第2列即B3ws.cell(row3,column2,value数据)# 读取第3行第2列valuews.cell(row3,column2).value5.2 用字母坐标定位# A1, B3, C5等ws[B3]数据valuews[B3].value5.3 行列号和字母坐标互转fromopenpyxl.utilsimportget_column_letter,column_index_from_string# 列号转字母1→A, 2→B, 26→Z, 27→AAcol_letterget_column_letter(27)# AA# 字母转列号A→1, B→2, AA→27col_numcolumn_index_from_string(AA)# 275.4 定位最后一行数据# 方法一openpyxlws.max_row# 返回有数据的最后一行行号# 方法二从下往上找last_rowws.max_rowwhilelast_row1andws.cell(rowlast_row,column1).valueisNone:last_row-1# 方法三pandasdfpd.read_excel(D:\\data\\product.xlsx)last_rowlen(df)1# 1因为第一行是表头坑max_row不准确openpyxl的max_row返回的是曾经有数据的最后一行包括已经删除但格式还在的行。如果你删除了数据但保留了格式max_row会比实际数据行数大。用方法二从下往上找更准确。六、合并单元格的处理6.1 读取合并单元格# 合并单元格的值只存在左上角单元格# 其他位置的值为Nonews[A1]# 有值ws[B1]# None被合并了ws[C1]# None被合并了坑遍历时遇到Nonetemu店群自动化报活动案例合并单元格区域的非左上角位置都是None遍历时需要特殊处理# 把合并区域的None填充为左上角的值merged_rangesws.merged_cells.rangesformerged_rangeinmerged_ranges:min_rowmerged_range.min_row min_colmerged_range.min_col valuews.cell(rowmin_row,columnmin_col).valueforrowinrange(min_row,merged_range.max_row1):forcolinrange(min_col,merged_range.max_col1):ifws.cell(rowrow,columncol).valueisNone:ws.cell(rowrow,columncol,valuevalue)6.2 写入合并单元格# 合并A1:C1ws.merge_cells(A1:C1)ws[A1]合并标题# 取消合并ws.unmerge_cells(A1:C1)七、常见场景速查7.1 读取表头和数据importpandasaspd dfpd.read_excel(D:\\data\\product.xlsx)headersdf.columns.tolist()# 表头列表datadf.values.tolist()# 数据列表# 按列名访问pricesdf[价格].tolist()namesdf[商品名].tolist()7.2 按条件查找数据dfpd.read_excel(D:\\data\\product.xlsx)# 找价格大于100的商品resultdf[df[价格]100]# 找名称包含手机的商品resultdf[df[商品名].str.contains(手机)]# 找状态为在售且库存大于0的商品resultdf[(df[状态]在售)(df[库存]0)]7.3 在最后一行追加数据importopenpyxl wbopenpyxl.load_workbook(D:\\data\\product.xlsx)wswb[Sheet1]# 找最后一行last_rowws.max_rowwhilelast_row1andws.cell(rowlast_row,column1).valueisNone:last_row-1# 在下一行追加new_rowlast_row1ws.cell(rownew_row,column1,value新商品)ws.cell(rownew_row,column2,value99.9)ws.cell(rownew_row,column3,value100)wb.save(D:\\data\\product.xlsx)7.4 更新已有数据dfpd.read_excel(D:\\data\\product.xlsx)# 更新ID为1001的商品价格df.loc[df[ID]1001,价格]199.9# 保存df.to_excel(D:\\data\\product.xlsx,indexFalse)八、避坑清单坑1写入后文件格式丢失用pandas写入Excel会丢失原有格式颜色、边框、合并单元格等。如果需要保留格式用openpyxl直接操作单元格不要用pandas覆盖整个文件。坑2大数据量写入慢逐个单元格写入1000行数据要几十秒。用批量写入# 慢逐个写入fori,rowinenumerate(data,2):forj,valinenumerate(row,1):ws.cell(rowi,columnj,valueval)# 快批量写入ws.append(row)# 每次写一整行坑3日期格式变成数字Excel内部把日期存储为数字从1900年1月1日起的天数。读取时可能得到一个数字而不是日期字符串。设置单元格的数字格式ws[A1].number_formatYYYY-MM-DD坑4文件太大打不开Excel文件超过几十MB时openpyxl加载会很慢甚至内存溢出。用read_only模式wbopenpyxl.load_workbook(big_file.xlsx,read_onlyTrue)坑5多个流程同时写同一个文件两个流程同时写同一个Excel文件一个会报错。用文件锁或者分时段写入。