Descrição:
Este script foi desenvolvido para um cliente específico, com o objetivo de processar arquivos Excel contendo lançamentos financeiros. Ele realiza as seguintes tarefas:
pandas..xlsx de uma pasta, ignorando já processados.letra_para_indice).desmesclar_para_tempfile).processar_arquivo).processar_todos_na_pasta).python
CopyEdit
import os
import pandas as pd
from openpyxl import load_workbook
from tempfile import NamedTemporaryFile
def letra_para_indice(letra):
letra = letra.upper()
indice = 0
for char in letra:
indice = indice * 26 + (ord(char) - ord('A') + 1)
return indice - 1
def desmesclar_para_tempfile(caminho_arquivo):
try:
wb = load_workbook(caminho_arquivo)
for sheet in wb.sheetnames:
ws = wb[sheet]
if ws.merged_cells.ranges:
for merged_cell in list(ws.merged_cells):
ws.unmerge_cells(str(merged_cell))
tmp = NamedTemporaryFile(suffix=".xlsx", delete=False)
wb.save(tmp.name)
tmp.close()
return tmp.name
except Exception as e:
print(f"[ERRO] Desmesclar {caminho_arquivo}: {e}")
return None
def processar_arquivo(caminho_arquivo, pasta_saida):
caminho_temp = desmesclar_para_tempfile(caminho_arquivo)
if not caminho_temp:
return
try:
sheet = pd.read_excel(caminho_temp, sheet_name=0)
os.remove(caminho_temp)
except Exception as e:
print(f"[ERRO] Abrir {caminho_temp}: {e}")
return
coluna_data_idx = letra_para_indice('E')
coluna_valor_idx = letra_para_indice('Y')
coluna_historico_idx = letra_para_indice('G')
coluna_g_idx = letra_para_indice('G')
coluna_ar_idx = letra_para_indice('AE')
coluna_juros_idx = letra_para_indice('AF')
coluna_doc_origem_idx = letra_para_indice('A')
if len(sheet.columns) <= max(coluna_g_idx, coluna_ar_idx, coluna_juros_idx, coluna_doc_origem_idx):
print(f"[AVISO] Colunas insuficientes em {os.path.basename(caminho_arquivo)}")
return
dados_processados = []
for _, row in sheet.iterrows():
data = row.iloc[coluna_data_idx]
valor = row.iloc[coluna_valor_idx]
historico = row.iloc[coluna_historico_idx]
historico_principal = row.iloc[coluna_g_idx]
d_ou_c = row.iloc[coluna_ar_idx]
juros = row.iloc[coluna_juros_idx]
doc_origem = row.iloc[coluna_doc_origem_idx]
dados_processados.append([data, valor, historico, historico_principal, d_ou_c, juros, doc_origem])
df = pd.DataFrame(dados_processados, columns=[
"Data", "Valor", "Historico", "Histórico Principal",
"D ou C", "Juros/Desconto", "DOC de Origem"
])
df = df[df['Historico'].astype(str).str.strip() != '']
df.loc[df['Valor'].notna() & df['Historico'].isna(), 'Historico'] = df['Histórico Principal']
for index, row in df.iterrows():
if pd.notna(row['Valor']) and pd.notna(row['Historico']):
if index + 1 < len(df):
proxima = df.at[index + 1, 'Historico']
if pd.notna(proxima):
df.at[index, 'Historico'] = f"{row['Historico']} - {proxima}"
df = df[df['Valor'].notna()]
if 'Histórico Principal' in df.columns:
df.drop(columns=['Histórico Principal'], inplace=True)
df['Tipo de Lançamento'] = df['Data'].apply(lambda x: 'Sintético' if pd.notna(x) else 'Analítico')
df['Data'] = df['Data'].ffill()
df.reset_index(drop=True, inplace=True)
importar = []
for i in range(len(df)):
tipo = df.at[i, 'Tipo de Lançamento']
if tipo == 'Analítico':
importar.append('Sim')
else:
if i + 1 < len(df) and df.at[i + 1, 'Tipo de Lançamento'] == 'Sintético':
importar.append('Sim')
else:
importar.append('Não')
df['Importar'] = importar
nome_base = os.path.splitext(os.path.basename(caminho_arquivo))[0]
caminho_saida = os.path.join(pasta_saida, nome_base + "_processado.xlsx")
try:
df.to_excel(caminho_saida, index=False)
print(f"[OK] {os.path.basename(caminho_saida)} salvo com sucesso.")
except Exception as e:
print(f"[ERRO] Ao salvar {caminho_saida}: {e}")
def processar_todos_na_pasta():
pasta = input("Digite o caminho da pasta com arquivos .xlsx: ").strip()
if not os.path.isdir(pasta):
print("Caminho inválido. Verifique e tente novamente.")
return
arquivos = [f for f in os.listdir(pasta) if f.lower().endswith('.xlsx') and '_processado' not in f.lower()]
if not arquivos:
print("Nenhum arquivo .xlsx para processar.")
return
pasta_saida = os.path.join(pasta, "processados")
os.makedirs(pasta_saida, exist_ok=True)
for arquivo in arquivos:
caminho_arquivo = os.path.join(pasta, arquivo)
print(f"\\n--- Processando: {arquivo} ---")
processar_arquivo(caminho_arquivo, pasta_saida)
print(f"\\n✅ Todos os arquivos processados foram salvos em: {pasta_saida}")
# Executar
processar_todos_na_pasta()