Массовое преобразование xlsb в csv, потребляющее слишком много памяти с помощью win32com - PullRequest
1 голос
/ 11 июня 2019

Я скелетировал некоторый код для преобразования определенных листов файлов xlsb в файлы csv и использую эту функцию для перебора списка путей и преобразования> 200 файлов в csv.


import os
import win32com.client
import subprocess
from pathlib import Path, PurePath


def xl_file_to_csv(xl_file_path, save_path_raw, worksheet_name):
    """
    Open a workbook and save sheet as csv files
    :param xl_file_path: workbook path
    :return: csv file name
    :save_path_raw: raw string save path
    :worksheet_name: raw string worksheet name
    :output_csv_path: Outputs csv path
    """

    #
    FNULL = open(os.devnull, 'w')

    # Sets save_path as Path class and returns file name w/o suffix from path and initializes file names

    save_path = save_path_raw
    file_name = Path(xl_file_path).stem
    file_name = file_name + ' - ' + worksheet_name + '.csv'
    output_csv_path = save_path / file_name

    # Checks if current file exists and calls kill excel process just in case
    exist_check = os.path.isfile(save_path / file_name)

    if exist_check: 
        pass
        subprocess.call('taskkill.exe /f /im EXCEL.EXE', stdout=FNULL, 
                         stderr=subprocess.STDOUT)
    else:
        # kills excel.exe process just in case
        subprocess.call('taskkill.exe /f /im EXCEL.EXE', stdout=FNULL, 
                        stderr=subprocess.STDOUT)

        # Opens and initializes excel
        xl_app = win32com.client.Dispatch("Excel.Application")
        xl_app.Visible = 0
        xl_app.DisplayAlerts = 0

        # Opens workbook and work sheet
        work_book = xl_app.Workbooks.Open(xl_file_path)
        work_sheet = work_book.Worksheets(worksheet_name)

        # Saves as csv in excel and quits
        work_sheet.SaveAs(output_csv_path, 6)
        work_book.Close(SaveChanges=0)
        xl_app.Quit()

        # kills excel.exe process
        subprocess.call('taskkill.exe /f /im EXCEL.EXE', stdout=FNULL, 
                        stderr=subprocess.STDOUT)
    return output_csv_path

Однако эта функция, похоже, довольно сильно пропускает память (без функции подпроцесса), поэтому я использую подпроцесс для уничтожения EXCEL.EXE на каждой итерации, так как xl_app.Quit (), похоже, не заканчиваетсяПроцесс Excel, который выглядит как крайнее решение.Мне было интересно, есть ли лучший способ обойти эту проблему?

РЕДАКТИРОВАТЬ: функция вызывается в цикле for, как:

for index, row in df.interrows():
     output_csv_path = xl_file_to_csv(row['path'], save_path, 'Worksheet')
...