迭代先前过滤的行openpyxl

时间:2016-07-28 16:42:55

标签: python excel vba excel-vba openpyxl

我编写了一个python代码,用于加载excel工作簿,遍历指定列中的所有行,将行保存在字典中并将该字典写入.txt文件。

引用的vb脚本在openpyxl执行之前打开工作簿,并将其过滤为仅显示一些数据。

唯一的问题是,当openpyxl遍历工作簿时,它会记录每个值而不是过滤后的数据。

例如,如果原始电子表格是:

   A   B   C
1  x   x   x
2  x   y   x
3  x   x   x

我过滤列B只显示包含" x"的行,然后保存工作簿。我希望openpyxl只迭代第1行和第3行。

这是我的代码:

from openpyxl import load_workbook
from openpyxl import workbook
import os
#sort using vba script
os.system(r"C:\script.vbs")

#load workbook
path = 'C:/public/temp/workbook.xlsm'
wb = load_workbook(filename = path)
ws=wb.get_sheet_by_name('Sheet3')
#make empty lists
proj_name = []
proj_num = []
proj_status = []

#iterate through rows and append values to lists
for row in ws.iter_rows('D{}:D{}'.format(ws.min_row,ws.max_row)):
    for cell in row:
        proj_name.append(cell.value)

for row in ws.iter_rows('R{}:R{}'.format(ws.min_row,ws.max_row)):
    for cell in row:
        proj_num.append(cell.value)

for row in ws.iter_rows('G{}:G{}'.format(ws.min_row,ws.max_row)):
    for cell in row:
        proj_status.append(cell.value)

#create dictionary from lists using defaultdict
from collections import defaultdict

dict1 = dict((z[0],list(z[1:])) for z in zip(proj_num,proj_name,proj_status))

with open(r"C:\public\list2.txt", "w") as text_file:
    text_file.write(str(dict1))
    text_file.close()

2 个答案:

答案 0 :(得分:1)

不幸的是,openpyxl目前不包含对其功能的过滤。正如the documentation所述:"过滤器和排序只能由openpyxl配置,但需要在Excel等应用程序中应用。"

看起来您可能需要找到另一种解决方案......

答案 1 :(得分:0)

f 是我要过滤的数据:(例如 'CISCO' only with(and)'PAI' or 'BD' only with(and) 'PAP' or 'H' is 42 )

f = {
    'C': ["CISCO", "BD"],
    'E': ["PAI", "PAP"],
    'H': [60]

}

from openpyxl import load_workbook
from openpyxl.utils.cell import column_index_from_string

def filter_data(rows, f_config, skip_header=False):
        # convert column alphabet string to index number (e.g. A=1, B=2)
        new_config = {}
        for col, fil in f_config.items():
            if type(col) == str:
                col = column_index_from_string(col)
            new_config[col] = fil

    output = []
    t_filter = len(new_config.items())
    for n, row in enumerate(rows):
        if n == 0:
            if skip_header == True:
                # first row header
                continue
        for i, (col,fil) in enumerate(new_config.items()):
            if type(fil) != list:
                fil = [fil]
            val = row[col-1].value
            # break the loop if any of the conditions not meet
            if not val in fil:
                break
            if i+1 == t_filter:
                # all conditions were met, add into output
                output.append(row)
    return output

#flexible to edit/filter which column of data you want
data1 = filter_data(sheet.rows, { "C": "CISCO", "E": "PAI" }, skip_header=True)

#filter 2 possibility, either str or value
data2 = filter_data(data1, { "H": [ "60", 60 ] } )
相关问题