記事ディレクトリ
前書き
毎日多数のExcelレポートの要約処理タスクがあるため、それを処理するスクリプトを作成しました。
各Excelで特定のシートを見つけ、これらのシートの特定の列を読み取り、それらを1つのシートにマージします。
各シートのデータは同じではないので少し面倒です以下はopenpyxlとpandasを使って処理しています。
openpyxl way
openpyxlを使用してマージロジックを自分で実装します。これは少し面倒です。Excelには数式が含まれている可能性があることに注意してください。Excelを読み取る場合は、次の方法を使用できます。
load_workbook(data_file_path、data_only = True)
data_only = Trueを使用すると、式自体ではなく、計算後に式の値を取得できます。式自体が別のシートにマージされているため、式が無効または正しくない場合もあります。
以下は参照用のサンプルコードです。
"""
pip install openpyxl
"""
from openpyxl import load_workbook
from openpyxl import Workbook
import os
import re
# 模板文件
TEMPLATE_FILE = r'H:\合并\合并模板.xlsx'
# 合并结果文件
RESULT_FILE = r'H:\合并\结果.xlsx'
# 数据文件目录
DATA_ROOT_DIR = r"H:\合并"
# 文件名称正则
DATA_FILE_REG = r"(.*?)-合同导入台账\d{8}.xlsx"
# 获取要处理的文件
def get_deal_file_map():
file_sn_map = {
}
fs = os.listdir(DATA_ROOT_DIR)
for f in fs:
match = re.match(DATA_FILE_REG, f)
if match:
city = match.group(1)
sn = 2
if city == '成都':
sn = 4
elif city == '杭州':
sn = 3
file_sn_map[os.path.join(DATA_ROOT_DIR, f)] = sn
return file_sn_map
# 规范化列名
def get_normal_column_name(origin_col_name):
if origin_col_name:
start = origin_col_name.find("(")
if start == -1:
return origin_col_name.strip()
else:
return origin_col_name[0:start].strip()
# 获取列名与列坐标的映射
def get_col_name_coordinate_map(sheet_row):
name_coor_map = {
}
for cell in sheet_row:
# name_coor_map[get_normal_column_name(cell.value)] = cell.column_letter
name_coor_map[get_normal_column_name(cell.value)] = cell.column
return name_coor_map
# 获取模板文件的列名与列坐标映射
def get_template_name_coordinate_map(template_file_path):
template_wbook = load_workbook(template_file_path)
table = template_wbook[template_wbook.sheetnames[0]]
row = table[1:1]
return get_col_name_coordinate_map(row)
def deal_data_content():
"""
合并文件内容
"""
dfile_sn_map = get_deal_file_map()
save_book = Workbook()
wsheet = save_book.active
wsheet.title = 'merge-data'
tmp_col_coor_map = get_template_name_coordinate_map(TEMPLATE_FILE)
wsheet.append(list(tmp_col_coor_map.keys()))
line = 2
for data_file_path in dfile_sn_map.keys():
sheet_num = dfile_sn_map[data_file_path]
wbook = load_workbook(data_file_path, data_only=True)
names = wbook.sheetnames
for i in range(0, sheet_num):
table = wbook[names[i]]
row = table[1:1]
data_col_coor_map = get_col_name_coordinate_map(row)
use_col = data_col_coor_map.keys() & tmp_col_coor_map.keys()
for row in table.iter_rows(min_row=2, values_only=True):
rcol_index = data_col_coor_map['城市']
city = row[rcol_index - 1]
if (city is None) or len(city.strip()) == 0:
continue
for col_name in use_col:
rcol_index = data_col_coor_map[col_name]
wcol_index = tmp_col_coor_map[col_name]
wsheet.cell(line, wcol_index, row[rcol_index - 1])
line += 1
save_book.save(RESULT_FILE)
if __name__ == '__main__':
deal_data_content()
パンダウェイ
openpyxlを直接使用する場合と比較して、pandasを使用する方がはるかに便利です。concatメソッドを直接使用するだけです。
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,keys=None, levels=None, names=None,verify_integrity=False,copy=True)
パラメータの意味
パラメータ | 意味 |
---|---|
objs | kist、シリーズ、DataFrame、パネル |
軸 | デフォルトは0で、線で接続します |
加わる | 内部、外部、デフォルトは「外部」 |
キー | リスト、階層インデックスを構築するための最も外側のレイヤー、マルチインデックスの場合はタプルを使用します |
レベル | リスト、特定のレベルのMultiIndexを構築するために使用 |
名 | リスト、結果階層インデックス内のレベルの名前 |
写す | ブール値。デフォルトはTrueです。Falseの場合、不必要にデータをコピーしないでください |
join_axes | 破棄されます。結果セットで再インデックスを使用することをお勧めします |
ignore_index | ブール値。デフォルトはFalseです。Trueの場合、インデックスを無視 |
verify_integrity | ブール値。デフォルトはFalseです。新しく接続された軸に重複が含まれているかどうかを確認します |
以下の例を直接見てみましょう。
# coding:utf-8
import pandas as pd
# 读取指定文件的指定sheet
df1 = pd.read_excel(r'H:\merge\cd-contract-charge-1-20200807.xlsx', header=0, sheet_name=0)
df2 = pd.read_excel(r'H:\merge\cd-contract-charge-2-20200807.xlsx', header=0, sheet_name=1)
df3 = pd.read_excel(r'H:\merge\cd-contract-charge-3-20200807.xlsx', header=0, sheet_name=2)
df4 = pd.read_excel(r'H:\merge\hz-contract-charge-1-20200807.xlsx', header=0, sheet_name=0)
df5 = pd.read_excel(r'H:\merge\hz-contract-charge-2-20200807.xlsx', header=0, sheet_name=1)
# 按行拼接
data = pd.concat([df1, df2, df3, df4, df5], sort=False, ignore_index=True)
# 选择需要的列
header = ['日期', '合同号', '城市', '姓名', 'charge']
data = data.loc[:, header]
# 将结果写到值得excel文件
data.to_excel(r'H:\merge\result.xlsx', index=False)
主にExcelファイルを読み込むためのパンダのファイルを読み書きするために、あなたはを参照してくださいすることができます。ファイルを読み書きパンダ
concatメソッドの使用に加えて、appendメソッドも使用できます。appendメソッドは特別なconcatメソッドです。つまり、concatパラメータaxis = 0の場合、concatメソッドaxisのデフォルト値でもあります。
もちろんパンダを使用しているので、一部のデータのフィルタリング、入力、変換の操作も可能です。