Win32Com 另存为 Python 3.6 中的变量名

Win32Com Save As Variable Name in Python 3.6

我正在尝试遍历文件夹中的 .xlsb 文件类型,并将它们转换为 Python 3+ 和 Windows 10 中的 .csv,并在来自的帮助下拼凑了下面的代码所以。我想将新的 .csv 保存为原始的 .xlsb 名称,但遇到问题 - 到目前为止我遇到了这个问题:

import os
import glob
import win32com.client

path = r'C:\Users\folder\Desktop\Test Binary'
all_files_test = glob.glob(os.path.join(path, "*.xlsb"))
for file in all_files_test:
    excel = win32com.client.Dispatch("Excel.Application")
    excel.Visible = False
    doc = excel.Workbooks.Open(file)
    doc.SaveAs(Filename="C:\Users\folder\Desktop\Test Binary\file.csv",FileFormat = 6) #overwrites file each time, need to substitute 'file'
    doc.Close(True)
    excel.Quit()
excel.Quit()

当然每次都会将每个新迭代覆盖为 'file.csv'。如何将每个 .csv 名称的 .xlsb 名称替换为另存为单独的文件?提前致谢。

只需在 file 变量上使用 str.replace 即可更改扩展名。并考虑包装在 try/except 中以干净地释放 COM 对象,无论是否有错误。

path = r'C:\Users\folder\Desktop\Test Binary'

all_files_test = glob.glob(os.path.join(path, "*.xlsb"))

for file in all_files_test:    
    try: 
        excel = win32com.client.Dispatch("Excel.Application")
        excel.Visible = False
        doc = excel.Workbooks.Open(file)

        csv_name = file.replace('.xlsb', '.csv')

        doc.SaveAs(Filename = csv_name, FileFormat = 6)
        doc.Close(True)
        excel.Quit()

    except Exception as e:
        print(e)

    finally:    
        doc = None
        excel = None

并更深入地使用 os.path.basenameos.path.join 的组合:

path = r'C:\Users\folder\Desktop\Test Binary'

...
csv_name = os.path.basename(file).replace('.xlsb', '.csv')

doc.SaveAs(Filename = os.path.join(path, 'Conversion_Files', csv_name), FileFormat = 6)

很好,但有一些缺陷。我已经在这个答案中修正了那些(我注意到的),并重构了一些上下文管理器以使逻辑更容易理解(因此更容易修改)。

它现在将失败的文件打印到 sys.stdout(让您恢复,Unix 风格,通过用重复的 input() / f.readline()[:-1] 调用替换 for 循环) , 并且只打开 Excel COM 对象一次;这应该会快很多。

我还添加了对递归执行此匹配的支持,但此功能需要 Python 3.5 或更高版本才能工作。

import os
import glob
import traceback
from contextlib import contextmanager
import win32com.client
from pythoncom import com_error

PATH = r'C:\Users\folder\Desktop\Test Binary'

@contextmanager
def open_excel():
    excel = win32com.client.Dispatch("Excel.Application")
    excel.Visible = False
    try:
        yield excel
    finally:
        excel.Quit()

@contextmanager
def open_workbook(excel, filename):
    doc = excel.Workbooks.Open(filename)
    try:
        yield doc
    finally:
        doc.Close(True)

all_files_test = glob.glob(os.path.join(PATH, "**.xlsb"), recursive=True)

with excel_cm() as excel:
    for file in all_files_test:    
        try: 
            with open_workbook(file) as doc:
                doc.SaveAs(Filename=file[:-4] + 'csv', FileFormat=6)
        except com_error as e:
            print(file)
            traceback.print_exc()