2016-11-21 105 views
0

对不起,我打了一堆深奥的代码,但遇到了一个我不知道如何解决的错误。使用OpenPyXL将Excel数据写入Python中的问题

基本上,我想读取电子表格列中的单个单元格,并将其数据写入相应的字典(称为dataSet)。

我创建了一个函数来做到这一点:

def loopCol(col, start_offset, write_list): 
''' 
Loop through 1 column (col) until it ends. Skip header by start_offset. 
Write data to list within DataSet dict 
''' 
from openpyxl.utils import column_index_from_string 

# Create list and capture str of its name 
list_string = str(write_list) 
print(list_string) 
if list_string not in dataSet: 
    raise KeyError('List name not within DataSet Keys') 
write_list = [] 

# Loop through column, capturing each cell's value 
# Use start_offset to skip header cells 
for i in range(column_index_from_string(col) + start_offset, 
       sheet.max_row + 1): 
    listItem = sheet[col + str(i)].value 
    print(listItem) 
    if listItem != None: 
     if isinstance(listItem, datetime.datetime): 
      listItem = listItem.strftime('%d/%m/%Y') 
      write_list.append(listItem) 
     else:    
      write_list.append(listItem) 

# Write data to dataSet 
for list_index in write_list: 
    dataSet[list_string] = [list_index for list_index in write_list] 

loopCol('A', 0, 'dates') 
loopCol('B', 0, 'ph') 
loopCol('C', 0, 'water_level') 
loopCol('D', 0, 'salinity') 
loopCol('E', 1, 'conductivity') 
loopCol('F', 0, 'tds') 

所以从理论上讲,这应该经历的所有单元格在一列中,如果有一个在他们一些值,这个值写在相应的地方本字典:

dataSet = { 
'dates': [], 
'ph': [], 
'water_level': [], 
'salinity': [], 
'conductivity': [], 
'tds': [] 
} 

但是,有一个问题。当所有的说法和完成字典看起来像:

{'ph': [3.4, 2.1, 7], 'salinity': [2.2, 1.2], 'conductivity': [5.3], 'water_level': ['2m', '3m', '1m'], 'tds': [], 'dates': ['Date', '21/01/2016', '28/01/2012', '06/03/2012']} 

现在我知道每个列中正好有3个单元格的值。但有些人并没有把它写进字典。 '盐度'只有2个值,'电导率'只有1个,'tds'是空的。这些确实是dataSet字典中的最后一个条目,所以也许这是原因的一部分。但我无法弄清楚逻辑中的错误在哪里。

Here's a screen of the file for context

是否有人可以帮忙吗?我真的很想给我的老板留下深刻印象;)(我不用IT工作,所以任何让人们生活更轻松的电脑魔法都会被惊叹和敬畏)。

如果我没有足够好地解释代码的确切做法,请告诉我,我会尽力澄清。

+1

请加好excel文件示例截图,好想象 – bzimor

+0

好主意。它现在正在运行 –

回答

1

你可以尝试这样的事:

def colValues(sheet, keys, offsets=None): 
    if offsets is None or not len(offsets): 
     # Set offsets default to 0 
     offsets = {k: 0 for k in keys} 
    if len(offsets) != len(keys): 
     # If offsets given, fail if length mismatch 
     raise AttributeError() 

    res = {} 
    for column in sheet.columns: 
     # Store current column header field (i.e. its name) 
     ch = column[0].value 
     if ch not in keys: 
      # Fail early: No need for any tests if this column's data 
      # is not desired in result set. 
      continue 
     # Append all row values to the result dict with respect to the 
     # given column offset. Note: Lowest possible row index is 1, 
     # because here we assume that header fields are present. 
     res[ch] = [c.value for c in column[offsets[keys.index(ch)] + 1:]] 
    return res 

if __name__ == '__main__': 
    xlsx = 'test.xlsx' 
    ws = load_workbook(xlsx)['Sheet1'] 

    ds = colValues(ws, ['foo', 'bar'], [0, 1]) 
    print(ds) 

对于我的小试,这会产生每列项数正确。请注意,关键'bar'这里少了一个项目,因为它在上述函数调用中的偏移更高。

{u'foo': [2.3, 3.5, 5.6, 7.9], u'bar': [6.2, 3.6, 9L]} 

此外,代码更轻。

+0

它工作得很好,你说得对,它比我写的更干净,更强大。非常感谢你的帮助! –