Win32Com 在 Python 3.6 中另存为变量名



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

import os
import glob
import win32com.client
path = r'C:UsersfolderDesktopTest 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 名称替换为另存为单独的文件?提前谢谢。

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

path = r'C:UsersfolderDesktopTest 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:UsersfolderDesktopTest Binary'
...
csv_name = os.path.basename(file).replace('.xlsb', '.csv')
doc.SaveAs(Filename = os.path.join(path, 'Conversion_Files', csv_name), FileFormat = 6)

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

它现在将失败的文件打印到sys.stdout(通过用重复的input()/f.readline()[:-1]调用替换for循环来恢复Unix风格(,并且只打开一次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:UsersfolderDesktopTest 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()

最新更新