戰(zhàn)指南——批量讀寫公式處理與常見報錯)
影刀RPA新手教程Excel自動化實(shí)戰(zhàn)指南——批量讀寫公式處理與常見報錯我第一次用影刀把采集到的100個商品數(shù)據(jù)寫入Excel時遇到了一個報錯Can not convert Array to String。排查了一下午才發(fā)現(xiàn)是因?yàn)槲矣谩狙h(huán)Excel內(nèi)容】指令時循環(huán)項是列表不能直接寫入單元格。后來我總結(jié)了Excel自動化的完整用法和5個常見報錯的處理方法現(xiàn)在寫Excel基本不會報錯。Excel讀取4種讀取方式直接給用法1. 讀取單元格什么時候用只需要讀取一個單元格的數(shù)據(jù)比如讀取A1單元格的內(nèi)容。怎么用指令讀取Excel內(nèi)容 Excel對象excel_obj 讀取方式讀取單元格 單元格A1 讀取格式值 保存到cell_value讀取格式的選擇值讀取單元格顯示的值比如公式B1C1的結(jié)果是10就讀到10公式讀取單元格的公式文本比如公式B1C1就讀到B1C1單元格顯示值讀取單元格格式化后顯示的值比如日期單元格顯示為2024-01-01就讀到2024-01-01我踩過的坑用openpyxl驅(qū)動讀取Excel時公式會被以字符串的形式讀取到而不是公式的計算結(jié)果。解決方法是在【啟動Excel】指令中選擇office或wps驅(qū)動方式。2. 讀取行什么時候用需要讀取一整行的數(shù)據(jù)比如讀取第1行的標(biāo)題行。怎么用指令讀取Excel內(nèi)容 Excel對象excel_obj 讀取方式讀取行 行號1 讀取格式值 保存到row_data真實(shí)場景讀取Excel的第一行作為標(biāo)題行然后根據(jù)標(biāo)題行的內(nèi)容來寫入數(shù)據(jù)。關(guān)鍵點(diǎn)row_data是一個列表比如[標(biāo)題1, 標(biāo)題2, 標(biāo)題3]。如果要把這個列表寫入單元格需要用【獲取列表指定位置項】指令取出每一個元素不能直接寫入。3. 讀取區(qū)域什么時候用需要讀取一個區(qū)域的數(shù)據(jù)比如讀取A1:C10這個區(qū)域的所有數(shù)據(jù)。怎么用指令讀取Excel內(nèi)容 Excel對象excel_obj 讀取方式讀取區(qū)域 讀取范圍A1:C10 讀取格式值 保存到range_data真實(shí)場景讀取Excel中的一個表格區(qū)域然后進(jìn)行處理。關(guān)鍵點(diǎn)range_data是一個二維列表比如[[標(biāo)題1, 標(biāo)題2], [數(shù)據(jù)1, 數(shù)據(jù)2]]。如果需要處理這個數(shù)據(jù)需要用兩層循環(huán)。4. 讀取全部數(shù)據(jù)什么時候用需要讀取整個Sheet頁的所有數(shù)據(jù)。怎么用指令讀取Excel內(nèi)容 Excel對象excel_obj 讀取方式讀取全部數(shù)據(jù) 讀取格式值 保存到all_data我第一次做的時候用【讀取全部數(shù)據(jù)】讀取了一個大文件10萬行數(shù)據(jù)結(jié)果內(nèi)存不足報錯。后來改成用【循環(huán)Excel內(nèi)容】指令一行一行讀取才解決這個問題。Excel寫入3種寫入方式直接給用法1. 寫入單元格什么時候用只需要寫入一個單元格比如把Hello寫入A1單元格。怎么用指令寫入Excel內(nèi)容 Excel對象excel_obj 寫入方式寫入單元格 單元格A1 寫入內(nèi)容Hello真實(shí)場景把采集到的商品標(biāo)題寫入Excel的A1單元格。我踩過的坑寫入的內(nèi)容是列表類型比如[商品標(biāo)題]會報錯Can not convert Array to String。解決方法是用【獲取列表指定位置項】指令取出列表中的元素再寫入單元格。2. 寫入行什么時候用需要寫入一整行的數(shù)據(jù)比如把[標(biāo)題1, 標(biāo)題2, 標(biāo)題3]寫入第1行。怎么用指令寫入Excel內(nèi)容 Excel對象excel_obj 寫入方式寫入行 起始列A 行號1 寫入內(nèi)容[標(biāo)題1, 標(biāo)題2, 標(biāo)題3]真實(shí)場景把采集到的商品數(shù)據(jù)標(biāo)題、價格、銷量寫入Excel的一行。關(guān)鍵點(diǎn)寫入內(nèi)容是列表類型列表中的每一個元素會依次寫入同一行的不同列。3. 追加數(shù)據(jù)什么時候用需要在Excel的最后追加一行數(shù)據(jù)不知道當(dāng)前有多少行數(shù)據(jù)。怎么用指令可視化打開Excel工作表 文件路徑D:\test.xlsx Sheet名稱Sheet1 指令在數(shù)據(jù)表格的最后追加一行內(nèi)容 起始寫入單元格的列名A 內(nèi)容[1, 2, 3, 4, 5]真實(shí)場景把采集到的100個商品數(shù)據(jù)逐個追加到Excel中。我的一般做法優(yōu)先用【追加數(shù)據(jù)】指令因?yàn)椴恍枰喇?dāng)前有多少行數(shù)據(jù)直接追加到最后一行的后面。批量處理循環(huán)讀取→處理→寫入場景把一個Excel文件中的數(shù)據(jù)讀取出來進(jìn)行處理比如計算價格乘以2然后寫入另一個Excel文件。完整流程1. 啟動Excel文件源文件 - 指令啟動Excel - 文件路徑D:\source.xlsx - 驅(qū)動方式office - 保存到source_excel 2. 啟動Excel文件目標(biāo)文件 - 指令啟動Excel - 文件路徑D:\target.xlsx - 驅(qū)動方式office - 保存到target_excel 3. 循環(huán)讀取源文件的數(shù)據(jù) - 指令循環(huán)Excel內(nèi)容 - Excel對象source_excel - 讀取方式讀取行 - 循環(huán)變量row_data 4. 處理數(shù)據(jù)比如價格乘以2 - 指令獲取列表指定位置項 - 目標(biāo)列表row_data - 索引1 # 假設(shè)價格在第2列索引從0開始 - 保存到price - 指令乘法運(yùn)算 - 被乘數(shù)price - 乘數(shù)2 - 保存到new_price - 指令更新列表指定位置項 - 目標(biāo)列表row_data - 索引1 - 新值new_price 5. 寫入目標(biāo)文件 - 指令寫入Excel內(nèi)容 - Excel對象target_excel - 寫入方式追加數(shù)據(jù) - 寫入內(nèi)容row_data 6. 結(jié)束循環(huán) 7. 保存并關(guān)閉Excel文件 - 指令保存Excel - Excel對象target_excel - 指令關(guān)閉Excel - Excel對象source_excel - 指令關(guān)閉Excel - Excel對象target_excel我第一次做的時候沒有關(guān)閉Excel文件導(dǎo)致文件一直被占用下次打開時提示文件被另一個程序占用。后來在流程結(jié)束前加了【關(guān)閉Excel】指令才解決這個問題。公式處理讀取公式結(jié)果vs公式文本場景1讀取公式的計算結(jié)果怎么用在【讀取Excel內(nèi)容】指令中將讀取格式設(shè)置為值。指令讀取Excel內(nèi)容 Excel對象excel_obj 讀取方式讀取單元格 單元格A1 讀取格式值 保存到result場景2讀取公式的文本方法1用openpyxl驅(qū)動指令啟動Excel 文件路徑D:\test.xlsx 驅(qū)動方式openpyxl 保存到excel_obj 指令讀取Excel內(nèi)容 Excel對象excel_obj 讀取方式讀取單元格 單元格A1 讀取格式公式 保存到formula_text方法2用Python代碼讀取from openpyxl import load_workbook def get_formula(file, row, col): wb load_workbook(file, data_onlyFalse) fm wb.worksheets[0].cell(row, col).value return fm def main(args): a get_formula(rC:\臨時\1.xlsx, 1, 1) print(a) # 輸出B1C1我踩過的坑用openpyxl驅(qū)動讀取Excel時公式會被以字符串的形式讀取到而不是公式的計算結(jié)果。如果需要讀取計算結(jié)果要用office或wps驅(qū)動方式。格式處理設(shè)置單元格格式場景把寫入Excel的數(shù)據(jù)進(jìn)行格式化比如設(shè)置字體、顏色、邊框、數(shù)字格式等。方法1用【設(shè)置格式】指令指令設(shè)置格式 Excel對象excel_obj 格式化方式設(shè)置字體 單元格A1 字體名稱微軟雅黑 字體大小12 字體顏色紅色我踩過的坑用【設(shè)置格式】指令設(shè)置邊框線時會丟失掉表格原來的字體、加粗、單元格顏色等格式。解決方法是用Python代碼來設(shè)置格式可以保留原來的格式。方法2用Python代碼設(shè)置格式import xlwings as xw def set_format(file): app xw.App(visibleFalse, add_bookFalse) wb app.books.open(file) sht wb.sheets[0] # 設(shè)置A1單元格的字體 sht.range(A1).api.Font.Name 微軟雅黑 sht.range(A1).api.Font.Size 12 sht.range(A1).api.Font.Color 255 # 紅色 wb.save() wb.close() app.quit() def main(args): set_format(rD:\test.xlsx)5個常見報錯與解決方法報錯1Can not convert Array to StringArray to String原因?qū)懭雴卧竦膬?nèi)容是列表類型而單元格只能寫入字符串或數(shù)字。解決方法用【獲取列表指定位置項】指令取出列表中的元素或者用【文本處理】指令將列表轉(zhuǎn)換為字符串真實(shí)代碼指令獲取列表指定位置項 目標(biāo)列表loop_excel # 循環(huán)Excel內(nèi)容時的循環(huán)項 索引0 保存到cell_value 指令填寫輸入框 目標(biāo)捕獲的輸入框元素 內(nèi)容cell_value # 現(xiàn)在是字符串不是列表我第一次遇到這個報錯時排查了一下午一直以為是【填寫輸入框】指令用錯了后來用【打印日志】指令打印loop_excel的值才發(fā)現(xiàn)是列表類型。報錯2日期偏移日期時間數(shù)據(jù)少了8個小時原因使用office和wps驅(qū)動寫入日期時間數(shù)據(jù)時時間會早8個小時。因?yàn)橛暗妒褂玫腜ython的datetime.datetime類型而office和wps需要的是COM類型的pywintypes.datetime。解決方法方法1將datetime.datetime類型轉(zhuǎn)換為字符串類型后再寫入指令日期時間轉(zhuǎn)換為文本 日期時間my_datetime 格式化字符串%Y-%m-%d %H:%M:%S 保存到date_str 指令寫入Excel內(nèi)容 Excel對象excel_obj 寫入方式寫入單元格 單元格A1 寫入內(nèi)容date_str方法2使用openpyxl驅(qū)動寫入日期數(shù)據(jù)指令啟動Excel 文件路徑D:\test.xlsx 驅(qū)動方式openpyxl 保存到excel_obj 指令寫入Excel內(nèi)容 Excel對象excel_obj 寫入方式寫入單元格 單元格A1 寫入內(nèi)容my_datetime我踩過的坑用方法1轉(zhuǎn)換后Excel中的日期變成了文本格式不能進(jìn)行日期計算。解決方法是在Excel中設(shè)置單元格格式為日期格式。報錯3內(nèi)存不足原因操作較大的Excel文件比如10萬行數(shù)據(jù)進(jìn)行讀取、寫入操作時容易引發(fā)內(nèi)存不足問題。解決方法方法1安裝影刀64位版本64位版本可以使用更多的內(nèi)存減少內(nèi)存不足的問題。方法2使用pandas處理數(shù)據(jù)量較大的Excelimport pandas as pd def process_large_excel(file): # 用pandas讀取Excel性能更好 df pd.read_excel(file) # 處理數(shù)據(jù) df[新列] df[原列] * 2 # 寫入Excel df.to_excel(file, indexFalse) def main(args): process_large_excel(rD:\大文件.xlsx)方法3一行一行讀取和處理不要一次性讀取全部數(shù)據(jù)指令循環(huán)Excel內(nèi)容 Excel對象excel_obj 讀取方式讀取行 ...處理當(dāng)前行數(shù)據(jù)... 指令寫入Excel內(nèi)容 Excel對象target_excel 寫入方式追加數(shù)據(jù) 寫入內(nèi)容processed_row 指令結(jié)束循環(huán)我的一般做法如果Excel文件超過1萬行就用pandas來處理不用影刀的【讀取Excel內(nèi)容】指令。報錯4文件被占用原因Excel文件已經(jīng)被其他程序打開比如你手動打開了Excel文件然后影刀也要操作這個文件或者影刀沒有正確關(guān)閉Excel文件。解決方法方法1確保Excel文件沒有被其他程序打開在操作Excel文件之前先關(guān)閉所有打開的Excel程序。方法2在影刀流程結(jié)束前關(guān)閉Excel文件指令關(guān)閉Excel Excel對象excel_obj方法3檢查文件是否被占用指令文件是否被占用 文件路徑D:\test.xlsx 保存到is_locked if is_locked True: 指令打印日志 內(nèi)容文件被占用請關(guān)閉所有打開的Excel程序 指令終止流程我第一次遇到這個報錯時流程跑到一半報錯文件被占用但是我不知道哪個程序占用了文件。后來用【文件是否被占用】指令檢查才發(fā)現(xiàn)是我手動打開了這個Excel文件沒有關(guān)閉。報錯5Sheet不存在原因指定的Sheet名稱不存在于Excel文件中。解決方法方法1檢查Sheet名稱是否正確確保Sheet名稱和你Excel文件中的Sheet名稱完全一致包括大小寫和空格。方法2獲取所有Sheet名稱然后選擇存在的Sheet指令獲取所有Sheet頁 Excel對象excel_obj 保存到all_sheets 指令for每個循環(huán) 列表all_sheets 循環(huán)變量sheet if sheet.name Sheet1: 指令激活Sheet頁 Excel對象excel_obj Sheet頁sheet方法3如果Sheet不存在就創(chuàng)建它指令獲取所有Sheet頁 Excel對象excel_obj 保存到all_sheets 指令設(shè)置變量 變量名sheet_exists 變量值False 指令for每個循環(huán) 列表all_sheets 循環(huán)變量sheet if sheet.name 新Sheet: 指令設(shè)置變量 變量名sheet_exists 變量值True 指令if條件判斷 條件sheet_exists False 指令新建Sheet頁 Excel對象excel_obj Sheet名稱新Sheet 指令結(jié)束判斷我的一般做法在【啟動Excel】指令中不指定Sheet名稱而是獲取第一個Sheet頁作為默認(rèn)Sheet頁。這樣可以避免Sheet不存在的報錯。案例主線把采集的100個商品數(shù)據(jù)批量寫入Excel并自動格式化場景從網(wǎng)頁上采集100個商品的數(shù)據(jù)標(biāo)題、價格、銷量然后寫入Excel并自動格式化設(shè)置標(biāo)題行加粗、設(shè)置價格列格式為貨幣、自動調(diào)整列寬。完整流程1. 啟動Excel文件 - 指令啟動Excel - 文件路徑D:\商品數(shù)據(jù).xlsx - 驅(qū)動方式office - 保存到excel_obj 2. 寫入標(biāo)題行 - 指令寫入Excel內(nèi)容 - Excel對象excel_obj - 寫入方式寫入行 - 起始列A - 行號1 - 寫入內(nèi)容[標(biāo)題, 價格, 銷量] 3. 循環(huán)采集商品數(shù)據(jù)假設(shè)已經(jīng)采集到列表product_list中 - 指令for每個循環(huán) - 列表product_list - 循環(huán)變量product 4. 寫入商品數(shù)據(jù) - 指令寫入Excel內(nèi)容 - Excel對象excel_obj - 寫入方式追加數(shù)據(jù) - 寫入內(nèi)容product 5. 結(jié)束循環(huán) 6. 自動格式化 - 指令設(shè)置格式 - Excel對象excel_obj - 格式化方式設(shè)置字體 - 單元格A1:C1 # 標(biāo)題行 - 字體加粗是 - 指令設(shè)置格式 - Excel對象excel_obj - 格式化方式設(shè)置數(shù)字格式 - 單元格B2:B101 # 價格列 - 數(shù)字格式貨幣 - 指令設(shè)置格式 - Excel對象excel_obj - 格式化方式自動調(diào)整列寬 - 單元格A1:C101 # 所有數(shù)據(jù) 7. 保存并關(guān)閉Excel文件 - 指令保存Excel - Excel對象excel_obj - 指令關(guān)閉Excel - Excel對象excel_obj關(guān)鍵點(diǎn)先寫入標(biāo)題行再追加商品數(shù)據(jù)格式化要在所有數(shù)據(jù)寫入完成后進(jìn)行流程結(jié)束前要保存并關(guān)閉Excel文件12大模塊覆蓋檢查認(rèn)識影刀/安裝【啟動Excel】指令的使用元素定位四合一不需要元素定位Excel操作是后臺操作變量與數(shù)據(jù)類型保存讀取的單元格數(shù)據(jù)、保存列表數(shù)據(jù)流程控制for循環(huán)批量寫入數(shù)據(jù)、if判斷Sheet是否存在網(wǎng)頁自動化從網(wǎng)頁采集數(shù)據(jù)本文的前提數(shù)據(jù)處理讀取Excel數(shù)據(jù)→處理→寫入Excel本文核心鼠標(biāo)鍵盤圖像自動化不需要Excel操作是后臺操作進(jìn)階技能用Python代碼處理Excelpandas、xlwings平臺實(shí)戰(zhàn)可以把Excel文件上傳到home.linyan.cloud我搭建的一個數(shù)據(jù)展示頁面系統(tǒng)聯(lián)動Excel操作是系統(tǒng)聯(lián)動的一部分工程化與規(guī)范Excel操作的規(guī)范先關(guān)閉文件再操作、定期檢查文件是否被占用速查表/常見報錯Can not convert Array to String列表直接寫入單元格報錯日期偏移日期變成數(shù)字或少8個小時內(nèi)存不足大文件處理文件被占用文件打不開Sheet不存在速查表Excel讀取方式的選擇讀取方式使用場景返回值類型優(yōu)先級讀取單元格讀取一個單元格字符串或數(shù)字最高最簡單讀取行讀取一整行列表高讀取一行數(shù)據(jù)讀取區(qū)域讀取一個區(qū)域二維列表中讀取表格數(shù)據(jù)讀取全部數(shù)據(jù)讀取整個Sheet頁二維列表低大文件會內(nèi)存不足速查表Excel寫入方式的選擇寫入方式使用場景寫入內(nèi)容類型優(yōu)先級寫入單元格寫入一個單元格字符串或數(shù)字最高最簡單寫入行寫入一整行列表高寫入一行數(shù)據(jù)追加數(shù)據(jù)在最后追加一行列表高不知道當(dāng)前有多少行我總結(jié)的Excel自動化黃金法則優(yōu)先用office或wps驅(qū)動openpyxl驅(qū)動讀取公式時會有問題寫入單元格前檢查類型確保不是列表類型否則會報錯Can not convert Array to String日期時間數(shù)據(jù)要轉(zhuǎn)換格式直接寫入會導(dǎo)致日期偏移8個小時大文件處理要用pandas不要用【讀取全部數(shù)據(jù)】指令會內(nèi)存不足操作前檢查文件是否被占用如果被占用先關(guān)閉所有打開的Excel程序流程結(jié)束前要保存并關(guān)閉Excel文件否則文件會一直被占用Sheet不存在時要先創(chuàng)建不要假設(shè)Sheet一定存在常見報錯與解決方法補(bǔ)充報錯6單元格格式無法解析內(nèi)容原因單元格的內(nèi)容是一個電話號碼但是格式是日期Excel就會顯示為######等無法識別的內(nèi)容。解決方法在Excel中手動設(shè)置單元格格式為文本或者在影刀中用【設(shè)置格式】指令設(shè)置單元格格式為文本報錯7循環(huán)Excel內(nèi)容時斷點(diǎn)調(diào)試導(dǎo)致報錯原因在循環(huán)內(nèi)部打斷點(diǎn)然后繼續(xù)運(yùn)行可能會導(dǎo)致循環(huán)項變量類型錯誤。解決方法不要在循環(huán)內(nèi)部打斷點(diǎn)如果需要調(diào)試在循環(huán)外部打印日志最后的建議Excel自動化是影刀RPA中最常用的功能之一幾乎所有的業(yè)務(wù)流程都會用到。我建議先在小范圍測試不要一上來就處理10萬行數(shù)據(jù)先用100行數(shù)據(jù)測試通再處理大文件多用【打印日志】指令記錄當(dāng)前處理到第幾行、處理結(jié)果是什么方便排查問題大文件處理要用pandas影刀原生的Excel指令性能有限處理大文件要用pandas定期檢查文件是否被占用如果流程報錯文件被占用先檢查是否有其他程序在占用這個文件如果你在實(shí)踐過程中遇到問題可以訪問home.linyan.cloud查看我整理的更多案例和解決方案。內(nèi)容標(biāo)簽影刀RPA Excel自動化 批量讀寫 公式處理 常見報錯 新手教程作者林焱