openpyxl.worksheet.Worksheet.iter_rows()
またはopenpyxl.worksheet.Worksheet.iter_columns()
メソッドを使用してワークシートを反復処理できます。
openpyxl.worksheet.Worksheet.rows
またはopenpyxl.worksheet.Worksheet.colums
プロパティを使用することもできます。これらは、ファイル全体を処理するはずのイテレータです。
しかしxlsx
ファイルを読み込むの私自身の限定された目的のために、私はちょうどZipFile
としてそれらを開いて、私は正規表現を使用して個々のシートから必要なデータをつかむ傾向にあります。私のためにうまく動作します。
以下は例です。 1年間のタイムシートを含むxlsxファイルからさまざまなプロジェクトで作業した時間を抽出します。すべてのシート(1つの勤務日を表す)に対して、私はプロジェクト番号と時間を特定の範囲のセルから抽出する必要があります。
from collections import defaultdict
from zipfile import ZipFile
import os.path
import re
import sys
__version__ = '1.1.0'
if len(sys.argv) == 1:
binary = os.path.basename(sys.argv[0])
print("{} ver. {}".format(binary, __version__), file=sys.stderr)
print("Usage: {} [file ...]".format(binary), file=sys.stderr)
sys.exit(0)
del sys.argv[0] # delete the name of the script.
# Real work starts here.
projects = defaultdict(int)
wbre = re.compile('<sheet name="[0-9]{4}-?[0-9]{1,2}-?[0-9]{1,2}'
'".*?"rId([0-9]{1,3})"/>')
Anum = re.compile('<c r="A([0-9]{1,2})" s="[^"]+"><v>(.*?)</v></c>')
Astr = re.compile('<c r="A([0-9]{1,2})" s="[^"]+" t="s"><v>(.*?)</v></c>')
shre = re.compile('<t[^>]*>(.*?)</t>')
Fre = re.compile('<c r="F([0-9]{1,2})" s="[^"]+"><f.*?><v>(.*?)</v></c>')
for fn in sys.argv:
z = ZipFile(fn)
# Create a list of the shared strings.
with z.open('xl/sharedStrings.xml') as sstr:
ssdata = sstr.read().decode('utf-8')
shstr = shre.findall(ssdata)
# Create a list of worksheet numbers. The name of the workheets matches
# NNNN-NN-NN where N is in 0--9.
with z.open('xl/workbook.xml') as wb:
wbdata = wb.read().decode('utf-8')
matches = wbre.findall(wbdata)
for shnum in matches:
with z.open('xl/worksheets/sheet{}.xml'.format(shnum)) as ws:
wsdata = ws.read().decode('utf-8')
# Extract the data from column A, rows 4 - 22.
A = {int(k): v for k, v in Anum.findall(wsdata) if 3 < int(k) < 23}
As = {int(k): shstr[int(v)] for k, v in Astr.findall(wsdata)
if 3 < int(k) < 23}
A.update(As)
# Extract the data from column F, rows 4 - 22.
F = {int(k): float(v) for k, v in Fre.findall(wsdata)
if 3 < int(k) < 23}
idxA, idxF = set(A.keys()), set(F.keys())
# Cross-reference project numbers and hours.
for k in idxA & idxF:
projects[A[k]] += F[k]
for k in idxF - idxA:
projects['geen'] += F[k]
z.close()
t = sorted([(k, v) for k, v in projects.items()], key=lambda x: x[1],
reverse=True)
total = sum(d[1] for d in t)
for k, v in t:
print('{:5}: {:.1f} uur ({:.1f}%)'.format(k, v, 100*v/total))
print('totaal: {:.0f} uur'.format(sum(projects.values())))
このコードを開発するために、私はXLSXファイルを解凍し、それらを人間が読みやすくするためにxmllint --format
でそれでXMLファイルをリストされています。
これは、APIを使用する最も確実な方法ではありません。 openpyxlのドキュメントを読んでもう少し時間をかけてください。 –