Directorio de artículos
Introducción
Debido a que hay una gran cantidad de tareas de procesamiento de resumen de informes de Excel todos los días, escribí un script para manejarlo.
Es encontrar la hoja específica en cada Excel, leer las columnas específicas de estas hojas y fusionarlas en una sola hoja.
Debido a que los datos de cada hoja no son los mismos, es un poco problemático. Lo siguiente usa openpyxl y pandas para procesar.
camino openpyxl
Use openpyxl para implementar la lógica de fusión usted mismo, que es un poco más problemático. Vale la pena señalar que puede haber fórmulas en Excel. Los siguientes métodos se pueden utilizar al leer Excel:
load_workbook (ruta_archivo_datos, solo_datos = Verdadero)
Usando data_only = True, puede obtener el valor después de que se calcule la fórmula, no la fórmula en sí, porque la fórmula en sí está combinada en otra hoja, la fórmula puede no ser válida o incluso incorrecta.
Aquí hay un código de muestra solo como referencia:
"""
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()
camino de los pandas
En comparación con el uso de openpyxl directamente, usar pandas es mucho más conveniente, solo use el método concat directamente.
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,keys=None, levels=None, names=None,verify_integrity=False,copy=True)
Significado del parámetro
parámetro | sentido |
---|---|
objs | kist, Series, DataFrame, Panel |
eje | El valor predeterminado es 0, conectarse por línea |
unirse | interno, externo, el valor predeterminado es "externo" |
llaves | list, la capa más externa para construir un índice jerárquico, si es un índice múltiple, use una tupla |
niveles | lista, usada para construir un nivel específico de MultiIndex |
nombres | lista, el nombre del nivel en el índice de jerarquía de resultados |
Copiar | booleano, el valor predeterminado es Verdadero. Si es Falso, no copie datos innecesariamente |
join_axes | Se descartará, se recomienda usar reindex en el conjunto de resultados |
ignore_index | booleano, el valor predeterminado es Falso. Si es verdadero, ignore el índice |
Verificar integridad | booleano, el valor predeterminado es Falso. Compruebe si el eje recién conectado contiene duplicados |
Veamos directamente el ejemplo:
# 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)
Principalmente para leer archivos de Excel. Para leer y escribir archivos pandas, puede consultar: pandas leyendo y escribiendo archivos
Además de usar el método concat, también puede usar el método append. El método append es un método concat especial, es decir, cuando el parámetro concat axis = 0, también es el valor predeterminado del eje del método concat.
Dado que se utilizan pandas, por supuesto, también se pueden realizar algunas operaciones de filtrado, llenado y conversión de datos.