def buscaArquivosEmPasta(caminho="entrada", extensao=(".XLS", "XLSX")): arquivos = os.listdir(caminho) lista_arquivos = [] for arquivo in arquivos: arquivo = funcoesUteis.removerAcentosECaracteresEspeciais( str(arquivo).upper()) if arquivo.endswith(extensao): lista_arquivos.append(caminho + "\\" + arquivo) return lista_arquivos
def leCsv(arquivos=buscaArquivosEmPasta(caminho="entrada", extensao=(".csv")), saida="temp\\baixas.csv", separadorCampos=';'): saida = open(saida, "w", encoding='utf-8') lista_dados = [] dados_linha = [] for arquivo in arquivos: with open(arquivo, 'rt') as csvfile: csvreader = csv.reader(csvfile, delimiter=separadorCampos) for row in csvreader: for campo in row: valor_celula = funcoesUteis.removerAcentosECaracteresEspeciais( str(campo)) # retira espaços e quebra de linha da célula valor_celula = str(valor_celula).strip().replace('\n', '') # gera o resultado num arquivo resultado = valor_celula + ';' resultado = resultado.replace('None', '') saida.write(resultado) # adiciona o valor da célula na lista de dados_linha dados_linha.append(valor_celula) # faz uma quebra de linha para passar pra nova linha saida.write('\n') # copia os dados da linha para o vetor de lista_dados lista_dados.append(dados_linha[:]) # limpa os dados da linha para ler a próxima dados_linha.clear() # fecha o arquivo saida.close() # retorna uma lista dos dados return lista_dados
def leXls_Xlsx(arquivos=buscaArquivosEmPasta(caminho="entrada"), saida="temp\\baixas.csv"): saida = open(saida, "w", encoding='utf-8') lista_dados = [] dados_linha = [] for arquivo in arquivos: try: arquivo = xlrd.open_workbook(arquivo, logfile=open(os.devnull, 'w')) except Exception: arquivo = xlrd.open_workbook(arquivo, logfile=open(os.devnull, 'w'), encoding_override='Windows-1252') # guarda todas as planilhas que tem dentro do arquivo excel planilhas = arquivo.sheet_names() # lê cada planilha for p in planilhas: # pega o nome da planilha planilha = arquivo.sheet_by_name(p) # pega a quantidade de linha que a planilha tem max_row = planilha.nrows # pega a quantidade de colunca que a planilha tem max_column = planilha.ncols # lê cada linha e coluna da planilha e imprime for i in range(0, max_row): valor_linha = planilha.row_values(rowx=i) # ignora linhas em branco if valor_linha.count("") == max_column: continue # lê as colunas for j in range(0, max_column): # as linhas abaixo analisa o tipo de dado que está na planilha e retorna no formato correto, sem ".0" para números ou a data no formato numérico tipo_valor = planilha.cell_type(rowx=i, colx=j) valor_celula = funcoesUteis.removerAcentosECaracteresEspeciais( str(planilha.cell_value(rowx=i, colx=j))) if tipo_valor == 2: valor_casas_decimais = valor_celula.split('.') valor_casas_decimais = valor_casas_decimais[1] if int(valor_casas_decimais) == 0: valor_celula = valor_celula.split('.') valor_celula = valor_celula[0] elif tipo_valor == 3: valor_celula = float( planilha.cell_value(rowx=i, colx=j)) valor_celula = xlrd.xldate.xldate_as_datetime( valor_celula, datemode=0) valor_celula = valor_celula.strftime("%d/%m/%Y") # retira espaços e quebra de linha da célula valor_celula = str(valor_celula).strip().replace('\n', '') # gera o resultado num arquivo resultado = valor_celula + ';' resultado = resultado.replace('None', '') saida.write(resultado) # adiciona o valor da célula na lista de dados_linha dados_linha.append(valor_celula) # faz uma quebra de linha para passar pra nova linha saida.write('\n') # copia os dados da linha para o vetor de lista_dados lista_dados.append(dados_linha[:]) # limpa os dados da linha para ler a próxima dados_linha.clear() # fecha o arquivo saida.close() # retorna uma lista dos dados return lista_dados
def organizaExtrato(saida="temp\\baixas.csv"): saida = open(saida, "w", encoding='utf-8') saida.write( "Data;Documento;Historico;Historico Complementar;Valor;Operacao\n") lista_arquivos = leLinhasExtrato() for linhas in lista_arquivos.values(): posicao_data = 0 posicao_documento = 0 posicao_historico = 0 posicao_valor = 0 data = datetime.datetime.strptime("01/01/1900", "%d/%m/%Y").date() data = data.strftime("%d/%m/%Y") documento = "" historico = "" valor = 0 operador = "" fornecedor_cliente = "" for num_row, row in enumerate(linhas): # ---- pega as posições onde estão os dados ---- posicao_data_temp = row.upper().find("DATA") if posicao_data_temp > 0: posicao_data = posicao_data_temp posicao_documento_temp = row.upper().find("DOCUMENTO") if posicao_documento_temp > 0: posicao_documento = posicao_documento_temp posicao_historico_temp = row.upper().find("HISTÓRICO") if posicao_historico_temp > 0: posicao_historico = posicao_historico_temp posicao_valor_temp = row.upper().find("VALOR") if posicao_valor_temp > 0: posicao_valor = posicao_valor_temp - 10 # pega 10 posições atrás da palavra valor # ---- termina de pegar os dados das posições # ---- começa o tratamento de cada campo ---- data_temp = row[posicao_data:posicao_data + 10] data_temp = funcoesUteis.retornaCampoComoData(data_temp) if data_temp is not None: data = funcoesUteis.transformaCampoDataParaFormatoBrasileiro( data_temp) if data == "01/01/1900": continue documento_temp = funcoesUteis.trataCampoTexto( row[posicao_documento:posicao_documento + 12]) if documento_temp != "" and data_temp is not None: documento = documento_temp historico_temp = funcoesUteis.trataCampoTexto( row[posicao_historico:posicao_historico + 56]) if data_temp is not None and historico_temp != "": historico = historico_temp if historico_temp.count("SALDO") > 0: continue valor_temp = funcoesUteis.removerAcentosECaracteresEspeciais( row[posicao_valor:posicao_valor + 20]) try: operador_temp = valor_temp[-1] except Exception: operador_temp = "" valor_temp = funcoesUteis.trataCampoDecimal(valor_temp) if valor_temp > 0 and data_temp is not None: valor = valor_temp operador = operador_temp if operador == "D": operador = "-" else: operador = "+" # lê a próxima linha pra saber se é uma linha com complementação dos dados da atual ou não try: proxima_linha = linhas[num_row + 1] except Exception: proxima_linha = "" data_temp_proxima_linha = proxima_linha[posicao_data:posicao_data + 10] data_temp_proxima_linha = funcoesUteis.retornaCampoComoData( data_temp_proxima_linha) valor_temp_proxima_linha = funcoesUteis.removerAcentosECaracteresEspeciais( proxima_linha[posicao_valor:posicao_valor + 20]) valor_temp_proxima_linha = funcoesUteis.trataCampoDecimal( valor_temp_proxima_linha) # primeira geração dos dados quando todas as informações estão em uma linha apenas if data_temp is not None and data_temp_proxima_linha is not None: saida.write( f"{data};{documento};{historico};;{valor:.2f};{operador}\n" ) # limpa dados do fornecedor_cliente if data_temp is not None: fornecedor_cliente = "" # segunda geração dos dados quando as informações complementares está em APENAS uma LINHA ABAIXO if data_temp is None and valor_temp == 0 and historico_temp != "" and data_temp_proxima_linha is None and valor_temp_proxima_linha == 0: fornecedor_cliente = fornecedor_cliente + " " + historico_temp # analisa se na verdade é um histórico válido, pois pode ser uma linha que contenha um tanto de carecter que não serve pra nada. Então considera como # histórico somente se conter o historico_temp válido historico_temp_inicio = funcoesUteis.trataCampoTexto( row[0:posicao_historico]) if len(historico_temp_inicio) > 0: fornecedor_cliente = "" # terceira geração dos dados quando as informações complementares está em MAIS de uma LINHA ABAIXO if data_temp is None and valor_temp == 0 and historico_temp != "" and data_temp_proxima_linha is not None and valor_temp_proxima_linha > 0: fornecedor_cliente = fornecedor_cliente + " " + historico_temp fornecedor_cliente = fornecedor_cliente.strip() # analisa se na verdade é um histórico válido, pois pode ser uma linha que contenha um tanto de carecter que não serve pra nada. Então considera como # histórico somente se conter o historico_temp válido historico_temp_inicio = funcoesUteis.trataCampoTexto( row[0:posicao_historico]) if len(historico_temp_inicio) > 0: fornecedor_cliente = "" saida.write( f"{data};{documento};{historico};{fornecedor_cliente};{valor:.2f};{operador}\n" ) saida.close()
def organizaExtratoSicoob(linhas): linhasExtrato = [] posicao_historico = 0 posicao_data = 0 data = datetime.datetime.strptime("01/01/1900", "%d/%m/%Y").date() data = data.strftime("%d/%m/%Y") documento = "" valor = 0 operador = "" fornecedor_cliente = "" historico = "" conta_corrente = "" for num_row, row in enumerate(linhas): row = str(row) conta_corrente_temp = row.strip().split(':') if conta_corrente_temp[0] == 'CONTA': conta_corrente = conta_corrente_temp[1].split('-') conta_corrente = funcoesUteis.trataCampoTexto(conta_corrente[0]) # DAQUI PRA BAIXO analisando a complementação do depósito posicao_historico_temp = row.upper().find("HISTÓRICO") if posicao_historico_temp > 0: posicao_historico = posicao_historico_temp - 10 # pega 10 posições a menos pra questão de 'segurança' historico_temp = funcoesUteis.trataCampoTexto( row[posicao_historico:posicao_historico + 65]) # ignora as linhas que são referente à saldos if historico_temp.count("SALDO") > 0: continue posicao_data_temp = str(row).upper().find("DATA") if posicao_data_temp > 0: if posicao_data_temp > 5: posicao_data = posicao_data_temp - 5 else: posicao_data = 0 # lê a próxima linha pra saber se é uma linha com complementação dos dados da atual ou não try: proxima_linha = linhas[num_row + 1] except Exception: proxima_linha = "" data_temp_proxima_linha = proxima_linha[posicao_data:posicao_data + 17] data_temp_proxima_linha = funcoesUteis.retornaCampoComoData( data_temp_proxima_linha) # ---- começa o tratamento de cada campo ---- data_temp = row[posicao_data:posicao_data + 17] data_temp = funcoesUteis.retornaCampoComoData(data_temp) # verifica se é uma data válida pra começar os tratamentos de cada campo if data_temp is not None: data = funcoesUteis.transformaCampoDataParaFormatoBrasileiro( data_temp) # ignora linhas que não são de pagamentos if data == "01/01/1900": continue # retira os espaços excessivos row = funcoesUteis.trataCampoTexto(row) # divide as linhas em espaço pois as posições do BB variam muito, então vamos pegar os dados de acordo a posição base deles (agencia e tipo_operacao(D,C) ) row_dividida = row.split() #print(row_dividida) tamanho_linha = len(row_dividida) - 1 documento_temp = funcoesUteis.trocaCaracteresTextoPraLetraX( row_dividida[1]) # serve pra sabermos onde começar o processamento do histórico posicao_inicio_historico = 0 if documento_temp.count('X') > 0: posicao_inicio_historico = 1 documento = "" else: posicao_inicio_historico = 2 documento = funcoesUteis.trataCampoTexto(row_dividida[1]) historico = "" for i in range(posicao_inicio_historico, tamanho_linha): historico = historico + " " + funcoesUteis.trataCampoTexto( row_dividida[i]) historico = historico.strip() valor = funcoesUteis.removerAcentosECaracteresEspeciais( row_dividida[tamanho_linha]) try: operador = valor[-1] except Exception: operador = "" valor = funcoesUteis.trataCampoDecimal(valor) if operador == "D": operador = "-" else: operador = "+" fornecedor_cliente = "" valor_imprimir = str(f"{valor:.2f}") valor_imprimir = valor_imprimir.replace('.', ',') # primeira geração dos dados quando todas as informações estão em uma linha apenas, ou seja, a próxima linha também já outro campo com data if data_temp_proxima_linha is not None and valor > 0: linhasExtrato.append( f"756;{conta_corrente};;{data};{operador};{valor_imprimir};{documento};{historico};{fornecedor_cliente}\n" ) # segunda geração dos dados quando as informações complementares está em APENAS uma LINHA ABAIXO if data_temp is None and historico_temp != "" and data_temp_proxima_linha is None and valor > 0: fornecedor_cliente = fornecedor_cliente + " " + historico_temp # analisa se na verdade é um histórico válido, pois pode ser uma linha que contenha um tanto de carecter que não serve pra nada. Então considera como # histórico somente se conter o historico_temp válido historico_temp_inicio = funcoesUteis.trataCampoTexto( row[0:posicao_historico]) if len(historico_temp_inicio) > 0: fornecedor_cliente = "" # segundo geração dos dados quando as informações complementares está na LINHA ABAIXO if data_temp is None and historico_temp != "" and data_temp_proxima_linha is not None and valor > 0: fornecedor_cliente = fornecedor_cliente + " " + historico_temp fornecedor_cliente = fornecedor_cliente.strip() # analisa se na verdade é um histórico válido, pois pode ser uma linha que contenha um tanto de carecter que não serve pra nada. Então considera como # histórico somente se conter o historico_temp válido historico_temp_inicio = funcoesUteis.trataCampoTexto( row[0:posicao_historico]) if len(historico_temp_inicio) > 0: fornecedor_cliente = "" linhasExtrato.append( f"756;{conta_corrente};;{data};{operador};{valor_imprimir};{documento};{historico};{fornecedor_cliente}\n" ) return linhasExtrato
def organizaExtrato(saida="temp\\baixas.csv"): saida = open(saida, "w", encoding='utf-8') saida.write( "Data;Documento;Historico;Historico Complementar;Valor;Operacao\n") lista_arquivos = leLinhasExtrato() for linhas in lista_arquivos.values(): linha_ja_impressa = {} posicao_historico = 0 posicao_data = 0 posicao_documento = 0 data = datetime.datetime.strptime("01/01/1900", "%d/%m/%Y").date() data = data.strftime("%d/%m/%Y") documento = "" valor = 0 operador = "" fornecedor_cliente = "" historico = "" ano_extrato = 0 for num_row, row in enumerate(linhas): row = str(row) try: linha_ja_impressa[num_row] = linha_ja_impressa[num_row] except Exception: linha_ja_impressa[num_row] = 0 posicao_data_temp = row.upper().find("DATA") if posicao_data_temp > 0: if posicao_data_temp > 5: posicao_data = posicao_data_temp - 5 else: posicao_data = 0 posicao_documento_temp = row.upper().find("DOCUMENTO") if posicao_documento_temp > 0: posicao_documento = posicao_documento_temp # DAQUI PRA BAIXO analisando a complementação do depósito posicao_historico_temp = row.upper().find("HISTORICO") if posicao_historico_temp > 0: # serve pra identificar onde o historico começa, visto que algumas vezes não tem o documento no PDF if posicao_documento == 0: posicao_historico = posicao_historico_temp - posicao_data_temp + 8 # pega 8 posições a menos pra questão de 'segurança' else: posicao_historico = posicao_historico_temp - 10 # pega 10 posições a menos pra questão de 'segurança' if posicao_historico > posicao_historico_temp: posicao_historico = posicao_historico_temp historico_temp = funcoesUteis.trataCampoTexto( row[posicao_historico:posicao_historico + 65]) # ignora as linhas que são referente à saldos if historico_temp.count("SALDO") > 0: historico_temp = " " # serve pros extratos que não tem a data com o ano, e sim apenas com o dia e mês periodo_temp = row.strip().split(':') if periodo_temp[0] == 'PERIODO': ano_extrato = periodo_temp[1].split('-') ano_extrato = funcoesUteis.trataCampoTexto(ano_extrato[0]) ano_extrato = ano_extrato[-4:] # serve pra identificar o tamanho das datas if posicao_documento == 0: qtd_char_data = posicao_historico - posicao_data if qtd_char_data > 17: qtd_char_data = 17 else: qtd_char_data = posicao_documento - posicao_data if qtd_char_data > 17: qtd_char_data = 17 # lê a próxima linha pra saber se é uma linha com complementação dos dados da atual ou não try: proxima_linha = linhas[num_row + 1] except Exception: proxima_linha = "" data_temp_proxima_linha = proxima_linha[posicao_data:posicao_data + qtd_char_data - 1] data_temp_proxima_linha = data_temp_proxima_linha.strip() # caso a data esteja apenas no forma DD/MM ele coloca o ano if len(data_temp_proxima_linha) == 5: data_temp_proxima_linha = ( f'{data_temp_proxima_linha}/{ano_extrato}') data_temp_proxima_linha = funcoesUteis.retornaCampoComoData( data_temp_proxima_linha) # ---- começa o tratamento de cada campo ---- data_temp = row[posicao_data:posicao_data + qtd_char_data - 1] data_temp = data_temp.strip() # caso a data esteja apenas no forma DD/MM ele coloca o ano if len(data_temp) == 5: data_temp = (f'{data_temp}/{ano_extrato}') data_temp = funcoesUteis.retornaCampoComoData(data_temp) historico_temp_proxima_linha = funcoesUteis.trataCampoTexto( proxima_linha[posicao_historico:posicao_historico + 65]) # ignora as linhas que são referente à saldos if historico_temp_proxima_linha.count("SALDO") > 0: historico_temp_proxima_linha = 1 else: historico_temp_proxima_linha = 0 # verifica se é uma data válida pra começar os tratamentos de cada campo if data_temp is not None: data = funcoesUteis.transformaCampoDataParaFormatoBrasileiro( data_temp) # ignora linhas que não são de pagamentos if data == "01/01/1900": continue # retira os espaços excessivos row = funcoesUteis.trataCampoTexto(row) # divide as linhas em espaço pois as posições do BB variam muito, então vamos pegar os dados de acordo a posição base deles (agencia e tipo_operacao(D,C) ) row_dividida = row.split() #print(row_dividida) tamanho_linha = len(row_dividida) - 1 documento_temp = funcoesUteis.trocaCaracteresTextoPraLetraX( row_dividida[1]) # serve pra sabermos onde começar o processamento do histórico posicao_inicio_historico = 0 if documento_temp.count('X') > 0: posicao_inicio_historico = 1 documento = "" else: posicao_inicio_historico = 2 documento = funcoesUteis.trataCampoTexto(row_dividida[1]) historico = "" for i in range(posicao_inicio_historico, tamanho_linha): historico = historico + " " + funcoesUteis.trataCampoTexto( row_dividida[i]) historico = historico.strip() valor = funcoesUteis.removerAcentosECaracteresEspeciais( row_dividida[tamanho_linha]) try: operador = valor[-1] except Exception: operador = "" valor = funcoesUteis.trataCampoDecimal(valor) if operador == "D": operador = "-" else: operador = "+" fornecedor_cliente = "" if historico_temp_proxima_linha == 1: linha_ja_impressa[num_row + 1] = 1 # primeira geração dos dados quando todas as informações estão em uma linha apenas, ou seja, a próxima linha também já outro campo com data if (data_temp_proxima_linha is not None or historico_temp_proxima_linha == 1) and valor > 0: saida.write( f"{data};{documento};{historico};{fornecedor_cliente};{valor:.2f};{operador}\n" ) # segunda geração dos dados quando as informações complementares está em APENAS uma LINHA ABAIXO if data_temp is None and historico_temp != "" and data_temp_proxima_linha is None and valor > 0 and linha_ja_impressa[ num_row] == 0: fornecedor_cliente = fornecedor_cliente + " " + historico_temp # analisa se na verdade é um histórico válido, pois pode ser uma linha que contenha um tanto de carecter que não serve pra nada. Então considera como # histórico somente se conter o historico_temp válido historico_temp_inicio = funcoesUteis.trataCampoTexto( row[0:posicao_historico]) if len(historico_temp_inicio) > 0: fornecedor_cliente = "" # segundo geração dos dados quando as informações complementares está na LINHA ABAIXO if data_temp is None and historico_temp != "" and data_temp_proxima_linha is not None and valor > 0 and linha_ja_impressa[ num_row] == 0: fornecedor_cliente = fornecedor_cliente + " " + historico_temp fornecedor_cliente = fornecedor_cliente.strip() # analisa se na verdade é um histórico válido, pois pode ser uma linha que contenha um tanto de carecter que não serve pra nada. Então considera como # histórico somente se conter o historico_temp válido historico_temp_inicio = funcoesUteis.trataCampoTexto( row[0:posicao_historico]) if len(historico_temp_inicio) > 0: fornecedor_cliente = "" saida.write( f"{data};{documento};{historico};{fornecedor_cliente};{valor:.2f};{operador}\n" ) saida.close()
def leXls_Xlsx(arquivo, nameSheetToFilter='filterAll'): lista_dados = [] dados_linha = [] if os.path.getsize(arquivo) > 0: try: arquivo = xlrd.open_workbook(arquivo, logfile=open(os.devnull, 'w')) except Exception: try: arquivo = xlrd.open_workbook(arquivo, logfile=open(os.devnull, 'w'), encoding_override='Windows-1252') except Exception: return [] # guarda todas as planilhas que tem dentro do arquivo excel planilhas = arquivo.sheet_names() # lê cada planilha for sheetName in planilhas: # pega os dados da planilha planilha = arquivo.sheet_by_name(sheetName) # continue only if name sheet equal the name filter of argument if funcoesUteis.treatTextField( sheetName) == funcoesUteis.treatTextField( nameSheetToFilter) or nameSheetToFilter == 'filterAll': # pega a quantidade de linha que a planilha tem max_row = planilha.nrows # pega a quantidade de colunca que a planilha tem max_column = planilha.ncols # lê cada linha e coluna da planilha e imprime for i in range(0, max_row): valor_linha = planilha.row_values(rowx=i) # ignora linhas em branco if valor_linha.count("") == max_column: continue # lê as colunas for j in range(0, max_column): # as linhas abaixo analisa o tipo de dado que está na planilha e retorna no formato correto, sem ".0" para números ou a data no formato numérico tipo_valor = planilha.cell_type(rowx=i, colx=j) valor_celula = funcoesUteis.removerAcentosECaracteresEspeciais( str(planilha.cell_value(rowx=i, colx=j))) if tipo_valor == 2: valor_casas_decimais = valor_celula.split('.') valor_casas_decimais = funcoesUteis.treatNumberFieldInVector( valor_casas_decimais, 2, isInt=True) try: if valor_casas_decimais == 0: valor_celula = valor_celula.split('.') valor_celula = valor_celula[0] except Exception: valor_celula = valor_celula elif tipo_valor == 3: valor_celula = float( planilha.cell_value(rowx=i, colx=j)) valor_celula = xlrd.xldate.xldate_as_datetime( valor_celula, datemode=0) valor_celula = valor_celula.strftime("%d/%m/%Y") # retira espaços e quebra de linha da célula valor_celula = str(valor_celula).strip().replace( '\n', '') # adiciona o valor da célula na lista de dados_linha dados_linha.append(valor_celula) # copia os dados da linha para o vetor de lista_dados lista_dados.append(dados_linha[:]) # limpa os dados da linha para ler a próxima dados_linha.clear() else: continue # retorna uma lista dos dados return lista_dados