在Python 2.6中用openpyxl遇到了一些问题

3 投票
1 回答
3922 浏览
提问于 2025-04-17 15:36

抱歉,如果这个问题之前已经被问过。

我在使用Python(这里是2.6版本)时导入了openpyxl(版本1.6.1)。到目前为止,它的功能都很好,但我想做的事情有点搞不清楚。

首先,我来列一下我需要读取的xlsx文件的结构。这个文件基本上是一个待命名单,长得像这样:

A1 B1 C1 D1
YYYY/MM/DD 系统1 系统2 系统3
A2 B2 C2 D2
2013/02/11 用户A 用户B 用户C
A3 B3 C3 D3
2013/02/12 用户D 用户E 用户F
A4 B4 C4 D4
2013/02/13 用户G 用户H 用户I

我需要做的事情是,首先扫描A列的所有单元格(不包括第一行,所以是从A2开始,一直到A的最后一行),然后根据今天的日期在A2到A最后一行的单元格中查找,如果找到了今天的日期,就打印出与今天日期相关的整行数据,以及用户对应的系统(也就是B3、C3和D3,还有B1、C1和D1)。

我可以把目前的代码粘贴出来,但还不多:

import openpyxl  
from openpyxl import load_workbook

wb = load_workbook(filename = 'standby.xlsx', use_iterators = True)  
ws = wb.get_sheet_by_name(name = 'Sheet1') # ws is now an IterableWorksheet  
for row in ws.iter_rows(): # it brings a new method: iter_rows()  
    for cell in row:  
        print cell.internal_value  

如果是标准的文本文件,我通常会这样做:

textfile = os.open('textfile', 'r')
textfiler = textfile.readlines()
for line in textfile:
    if "today's date" in line:
        print line

但我不太确定如何用openpyxl处理xlsx文件,就像我处理文本文件那样。有没有人能给我一点提示,告诉我该怎么做?

我想我需要做的是扫描A列下面的所有内容(不太确定怎么做),然后匹配今天的日期(日期的部分我想我能搞定),如果找到了今天的日期,就打印出整行数据(Bxxx、Cxxx、Dxxx等),但我也不太确定该怎么做。

希望我能清楚地解释我的问题,如果没有,请告诉我,我会再试一次。

编辑:多亏了Glen,我觉得我比之前进展了一些,但还是没完全搞定。我目前的代码是:

import openpyxl
from openpyxl import load_workbook

def find_row(today, ws):
    for a in ws.iter_rows():
        if today == a.internal_value:
            return (a)

def main():
    wb = load_workbook(filename = 'standby.xlsx', use_iterators = True)
    ws = wb.get_sheet_by_name(name = 'Sheet1') # ws is now an IterableWorksheet
    today = '2013-02-12 00:00:00' #whatever date format you're using
    row = find_row(today, ws)
    print row

def test():
    wb = load_workbook(filename = r'standby.xlsx')
    sheet_ranges = wb.get_sheet_by_name(name = 'Sheet1')
    print sheet_ranges.cell('A2607').value # D18

if __name__ == '__main__':
    main()

我现在遇到的错误是“AttributeError: 'tuple' object has no attribute 'internal_value'”(我还在谷歌搜索这个问题)。

之前的find_row部分看起来是这样的:

def find_row(today, ws):
    for a in ws.rows():
        if today == a.internal_value:
            return (a)

结果是这样的:NotImplementedError: use 'iter_rows()' instead

编辑 #2:多亏了Glen Swinfield的帮助和耐心,我想我终于搞定了。现在的代码长这样(请原谅如果看起来有点乱,发现这个表格里有很多列):
import datetime
import openpyxl
from openpyxl import load_workbook

def find_row(today, ws):
    for a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53,a54,a55,a56,a57,a58,a59,a60,a61,a62,a63,a64,a65,a66,a67,a68,a69,a70,a71,a72,a73,a74,a75,a76,a77,a78,a79,a80,a81,a82,a83,a84,a85,a86,a87,a88,a89,a90,a91,a92,a93 in ws.iter_rows():
        if today == a1.internal_value:
            print(a1.internal_value,a2.internal_value,a3.internal_value,a4.internal_value,a5.internal_value,a6.internal_value,a7.internal_value,a8.internal_value,a9.internal_value,a10.internal_value,a11.internal_value,a12.internal_value,a13.internal_value,a14.internal_value,a15.internal_value,a16.internal_value,a17.internal_value,a18.internal_value,a19.internal_value,a20.internal_value,a21.internal_value,a22.internal_value,a23.internal_value,a24.internal_value,a25.internal_value,a26.internal_value,a27.internal_value,a28.internal_value,a29.internal_value,a30.internal_value,a31.internal_value,a32.internal_value,a33.internal_value,a34.internal_value,a35.internal_value,a36.internal_value,a37.internal_value,a38.internal_value,a39.internal_value,a40.internal_value,a41.internal_value,a42.internal_value,a43.internal_value,a44.internal_value,a45.internal_value,a46.internal_value,a47.internal_value,a48.internal_value,a49.internal_value,a50.internal_value,a51.internal_value,a52.internal_value,a53.internal_value,a54.internal_value,a55.internal_value,a56.internal_value,a57.internal_value,a58.internal_value,a59.internal_value,a60.internal_value,a61.internal_value,a62.internal_value,a63.internal_value,a64.internal_value,a65.internal_value,a66.internal_value,a67.internal_value,a68.internal_value,a69.internal_value,a70.internal_value,a71.internal_value,a72.internal_value,a73.internal_value,a74.internal_value,a75.internal_value,a76.internal_value,a77.internal_value,a78.internal_value,a79.internal_value,a80.internal_value,a81.internal_value,a82.internal_value,a83.internal_value,a84.internal_value,a85.internal_value,a86.internal_value,a87.internal_value,a88.internal_value,a89.internal_value,a90.internal_value,a91.internal_value,a92.internal_value,a93.internal_value)

def main():
    wb = load_workbook(filename = 'standby.xlsx', use_iterators = True)
    ws = wb.get_sheet_by_name(name = 'Sheet1') # ws is now an IterableWorksheet
    today = datetime.datetime(2013, 02, 12, 0, 0) #whatever date format you're using
    row = find_row(today, ws)

def test():
    wb = load_workbook(filename = r'standby.xlsx')
    sheet_ranges = wb.get_sheet_by_name(name = 'Sheet1')
    print sheet_ranges.cell('A2607').value # D18

if __name__ == '__main__':
    main()

1 个回答

2

我现在不能测试这个,但原则上你需要逐行遍历数据,逐个取出每个单元格,然后检查A列的单元格是否是今天的日期,如果是,就返回这一行。

import openpyxl  
from openpyxl import load_workbook

def find_row(today, ws):
    for a,b,c,d in ws.rows():
        if today == a.internal_value:
            return (a, b, c, d)
    raise someException('row not found')

wb = load_workbook(filename = 'standby.xlsx', use_iterators = True)  
ws = wb.get_sheet_by_name(name = 'Sheet1') # ws is now an IterableWorksheet
today = '' #whatever date format you're using
try:
    row = find_row(today, ws) 
except someException:
    # handle exception

在Python中,有几种方法可以做到这一点,比如使用while/else循环,但这就是它的核心思路。

根据评论更新:

def find_row(today, ws):
    for a,b,c,d in ws.iter_rows():
        if today == a.internal_value:
            return (a, b, c, d)
    raise someException('row not found')

use_iterators = True这个标志意味着你会得到一个迭代器,所以你需要使用iter_rows()而不是直接用.rows

撰写回答