需求說明
已知要提取的目標值:例如所在表的名稱是“A.xlsx”,該數(shù)據(jù)在該表中所屬行是“合計”,所屬列是“銷售額”。
“所屬行”、“所屬列”的意思是:行標簽和列標簽的名稱,通常在最左一列和最上一行。
實際實現(xiàn)時:會找到某單元格的內(nèi)容等于該標簽名稱,該單元格的行序和列序就是要找是目標行和目標列。
如果Cfg.txt某些數(shù)據(jù)(如 其他值)無法提取,而是通過其他方式獲得,可直接寫成下面的形式。
在最終生成的提取結(jié)果.txt中會保留原始描述。
在配置文件Cfg.txt中這樣填寫
{
"目標值":["A","合計","銷售額"],
"其他值":"描述數(shù)據(jù)來源"
}
在最終生成的提取結(jié)果.txt中,可看到提取到的值(例如是500)
{
"目標值":"500",
"其他值":"描述數(shù)據(jù)來源"
}
如果提取失敗,則顯示為null
{
"目標值": null,
"其他值":"描述數(shù)據(jù)來源"
}
成品設(shè)想
將工具和所有表(.xlsx)、Cfg.txt放在同一目錄下。
運行后,在該目錄下生成:提取結(jié)果.txt。形式和Cfg.txt一致,只是提取值替換了原本對提取值所屬表、行、列的描述。
實現(xiàn)思路
生成數(shù)據(jù)字典
2個字典。
- 各表的名稱及各單元格的值和其行序列序
- Key是各表(.xlsx)的名稱,無后綴,即Cfg.txt對目標值的描述中的3個子項中的第1項
- Value是若干個子字典
Key:單元格中的值
Value:該單元格所屬的行序、列序
- 各表的名稱及各表
目標值位置描述 -> 目標值
根據(jù)目標值的位置描述,從數(shù)據(jù)字典1找到該值所屬的表以及行序列序,從數(shù)據(jù)字典2找到目標值。
具體代碼
# 打包命令
# pyinstaller --hidden-import json -F -c D:\Fanjc\PythonProjects\從多個excel表中提取目標數(shù)據(jù)\從多個excel表中提取目標數(shù)據(jù).py D:\Fanjc\PythonProjects\ReadAndWriteTable.py
import os
import sys
from openpyxl import load_workbook
sys.path.append('D:\Fanjc\PythonProjects')
# .py文件(模塊)名稱是ReadAndWriteTable
from ReadAndWriteTable import readJson, writeJson
def getPathList(path, suffix):
'''獲取path下所有后綴為suffix的文件的路徑'''
pathList = []
for mainDir, subDir, fileNameList in os.walk(path):
for fileName in fileNameList:
currentPath = os.path.join(mainDir, fileName)
if currentPath.endswith(suffix):
pathList.append(currentPath)
return pathList
def getValueByTableRowColName(nameList, dataDict, tableDict):
'''nameList長度應(yīng)為3:表名、行名、列名;
dataDict的key是表名,值是行列名-[對應(yīng)的行序號,列序號];
tableDict:表名-表'''
ret = None
if len(nameList) == 3:
tableName = curValue[0]
rowName = curValue[1]
colName = curValue[2]
if tableName in dataDict.keys() and rowName in dataDict[tableName].keys() and colName in dataDict[tableName].keys():
rowIndex = dataDict[tableName][rowName][0]
colIndex = dataDict[tableName][colName][1]
ret = tableDict[tableName].cell(row = rowIndex, column = colIndex).value
return ret
if __name__ == "__main__":
'''從多個excel表中提取目標數(shù)據(jù)'''
# 獲取本目錄下的所有.xlsx
curDir = os.path.realpath(os.path.dirname(sys.argv[0]))
suffix = '.xlsx'
tablesPath = getPathList(curDir,suffix)
# 獲取所有表格內(nèi)容
tableDict = {}
tableNameAndValueDict = {}
for path in tablesPath:
curName = os.path.basename(path)
# 剔除后綴
curName = os.path.splitext(curName)[0]
curTable = load_workbook(path).active
tableDict[curName] = curTable
curValueAndRowColDict = {}
for row in curTable.iter_rows(values_only = False):
for cell in row:
curValue = cell.value
# 剔除空格、換行
if type(curValue) == str:
curValue = curValue.replace(' ','')
curValue = curValue.replace('\n','')
curValueAndRowColDict[curValue] = [cell.row, cell.column]
tableNameAndValueDict[curName] = curValueAndRowColDict
# 輸出的是字典
output = {}
# 讀配置
cfgFileDir = os.path.dirname(sys.argv[0])
cfgPath =os.path.join(cfgFileDir,'Cfg.txt')
cfg = readJson(cfgPath)
for item in cfg.items():
curKey = item[0]
curValue = item[1]
outputValue = curValue
if type(curValue) == list:
# 嘗試找到curValue對應(yīng)的表中的值
outputValue = getValueByTableRowColName(curValue, tableNameAndValueDict, tableDict)
output[curKey] = outputValue
# 導出
outputPath = os.path.join(curDir,'提取結(jié)果.txt')
writeJson(outputPath,output)
print('成功提??!\n',outputPath)
# 讓打包后不自己退出
input()