Cómo nombrar automáticamente archivos de Excel recién generados a part

Cómo nombrar automáticamente archivos de Excel recién generados a partir de archivos csv con Python

Necesito transformar archivos csv en archivos Excel de forma automática. Estoy fallando al nombrar archivos de Excel con el nombre del archivo csv correspondiente. Guardé archivos csv como 'Trials_1', 'Trials_2', Trilas_3' pero con el código que escribí Python me da un error y me pide un archivo csv llamado 'Trials_4'. Luego, si cambio el nombre del archivo csv 'Trials_1' a 'Trials_4', el programa funciona y genera un archivo de Excel llamado 'Trials_1'. ¿Cómo puedo corregir mi código?

'''

import csv

import openpyxl as xl

import os, os.path

directory=r'C:\\Users\\PycharmProjects\\input\\'

folder=r'C:\\Users\\PycharmProjects\\output\\'

for csv_file in os.listdir(directory):

def csv_to_excel(csv_file, excel_file):

    csv_data=[]

    with open(os.path.join(directory, csv_file)) as file_obj:

        reader=csv.reader(file_obj)

        for row in reader:

            csv_data.append(row)

    workbook= xl.Workbook()

    sheet=workbook.active

    for row in csv_data:

        sheet.append(row)

        workbook.save(os.path.join(folder,excel_file))


if __name__=="__main__":
    m = sum(1 for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f)))
    new_name = "{}Trial_{}.csv".format(directory, m + 1)
    k = sum(1 for file in os.listdir(folder) if os.path.isfile(os.path.join(folder, file)))
    new_name_e = "{}Trial_{}.xlsx".format(folder, k + 1)
    csv_to_excel(new_name,new_name_e)

'''

Gracias.

Mostrar la mejor respuesta

Hola, Annachiara, bienvenida a StackOverflow,

Yo modificaría la función "csv_to_excel" usando solo pandas.

Antes de eso, debe instalar 'xlsxwriter' con:

pip install XlsxWriter

Entonces la función sería así:

def csv_to_excel(csv_file,excel_file,csv_sep=';'):

    # read the csv file with pandas
    df=pd.read_csv(csv_file,sep=csv_sep)
    # create the excel file
    writer=pd.ExcelWriter(excel_file, engine='xlsxwriter')
    # copy the csv content (df) into the excel file
    df.to_excel(writer,index=False)
    # save the excel file
    writer.save()
    # print what you converted for reference
    print(f'csv file {csv_file} saved as excel in {excel_file}')

Solo asegúrese de que el csv se lea correctamente: agregué solo el parámetro del separador, pero es posible que desee agregar todos los demás parámetros (como fechas de análisis, etc.)

Luego puede convertir la lista de archivos csv con un bucle for (utilicé más pasos para hacerlo más claro)

dir_in=r'C:\\Users\\PycharmProjects\\input\\'

dir_out=r'C:\\Users\\PycharmProjects\\output\\'

csvs_to_convert=os.listdir(dir_in)

for csv_file_in in csvs_to_convert:
    
    # remove extension from csv files
    file_name_no_extension=os.path.splitext(csv_file_in)[0]
    # add excel extension .xlsx
    excel_name_out=file_name_no_extension+'.xlsx'
    # write names with their directories
    complete_excel_name_out=os.path.join(dir_out,excel_name_out)
    complete_csv_name_in=os.path.join(dir_in,csv_file_in)
    # convert csv file to excel file
    csv_to_excel(complete_csv_name_in,complete_excel_name_out,csv_sep=';')

Muchas gracias, agregué la parte final de tu código al mío y ahora funciona sin problemas.

¡Grande Annachiara! ¿Puedes marcarlo como respuesta aceptada?

Cada csv como archivo de Excel separado>

import glob
import pandas as pd
import os

csv_files = glob.glob('*.csv')
for filename in csv_files:
    sheet_name = os.path.split(filename)[-1].replace('.csv', '.xlsx')
    df = pd.read_csv(filename)
    df.to_excel(sheet_name, index=False)

Todos los csv en el mismo Excel en diferentes hojas

import glob
import pandas as pd
import os

# Create excel file
writer = pd.ExcelWriter('all_csv.xlsx')

csv_files = glob.glob('*.csv')
for filename in csv_files:
    sheet_name = os.path.split(filename)[-1].replace('.csv', '')
    df = pd.read_csv(filename)
    # Append each csv as sheet
    df.to_excel(writer, sheet_name=sheet_name, index=False)
writer.save()

Suponiendo que le gustaría mantener la misma estructura de su código, acabo de solucionar algunos problemas técnicos en su código para que funcione (cambie la ruta de las carpetas a la suya):

import csv

import openpyxl as xl

import glob, os, os.path

directory= 'input'

folder= '../output' # Since 'input' would be my cwd, need to step back a directory to reach 'output'

# Using your function, just passing different arguments for convinient.
def csv_to_excel(f_path, f_name):

    csv_data=[]

    with open(f_path, 'r') as file_obj:

        reader=csv.reader(file_obj)

        for row in reader:

            csv_data.append(row)

    workbook= xl.Workbook()

    sheet=workbook.active

    for row in csv_data:

        sheet.append(row)

        workbook.save(os.path.join(folder, f_name + ".xlsx"))


def main():
    os.chdir(directory) # Defining input directory as your cwd
    # Searching for all files with csv extention and sending each to your function
    for file in glob.glob("*.csv"):
        f_path = os.getcwd() + '\\' + file # Saving the absolute path to the file
        f_name = (os.path.splitext(file)[0]) # Saving the name of the file
        csv_to_excel(f_path, f_name) 

if __name__=="__main__":
    main()

PD: Evite iterar una definición de una función ya que solo necesita definir una función una vez.

Gracias por la sugerencia, he excluido la definición del bucle.