Python: Access embedded OLE from Office/Excel document without clipboard

前端 未结 3 961
不思量自难忘°
不思量自难忘° 2020-12-18 23:11

I want to add and extract files from an Office/Excel document using Python. So far adding things is easy but for extracting I haven\'t found a clean solution.

To mak

3条回答
  •  心在旅途
    2020-12-18 23:58

    Consider using the Windows temp directory that will temporarily store the OLE Object's file source when embedded in workbook. No clipboard is used in this solution but physical files.

    With this approach, you will need to retrieve the current user's name and iterate through all files of the temp directory: C:\Documents and Settings\{username}\Local Settings\Temp (standard Excel dump folder for Windows Vista/7/8/10). Also, a conditional like-name search with in is used that contains original file's basename as multiple versions with number suffixes (1), (2), (3),... may exist depending on how many times script runs. Try even a regex search here.

    Finally, the below routine uses try...except...finally block to cleanly exist the Excel objects regardless of error but will output any exception message. Do note this is only a Windows solution using a text file.

    import win32com.client as win32
    import os, shutil
    from tkinter import messagebox
    
    # (0) Setup
    dir_path = cd = os.path.dirname(os.path.abspath(__file__))
    print(dir_path)
    
    try:
        excel = win32.gencache.EnsureDispatch('Excel.Application')    
        wb = excel.Workbooks.Open(os.path.join(dir_path, "test_excel.xlsx"))
        ws = wb.Worksheets(1)
        objs = ws.OLEObjects()
    
        # (1) Embed file
        f = os.path.join(dir_path, "test_txt.txt")    
        name = "test_txt_ole.txt"
        objs.Add(Filename=f, IconLabel=name).Name = 'Test'
    
        # (2) Open file from temporary folder
        ole = ws.OLEObjects(1)        
        ole.Activate()
    
        # (3) Grab the recent like-named file
        user = os.environ.get('USERNAME')
        outfile = os.path.join(dir_path, "test_txt_out.txt")
    
        tempfolder = r"C:\Documents and Settings\{}\Local Settings\Temp".format(user)
    
        for subdir, dirs, files in os.walk(tempfolder):
            for file in sorted(files, reverse=True):
                if 'test_txt' in file:                
                    tempfile = os.path.join(tempfolder, file)
                    break
    
        shutil.copyfile(tempfile, outfile)
    
        # (4) Read text content
        with open(outfile, 'r') as f:        
            content = f.readlines()
    
        # (5) Output message with content
        messagebox.showinfo(title="test_txt_ole.txt", message="".join(content))
    
    except Exception as e:
        print(e)
    
    finally:
        wb.Close(True)      # CLOSES AND SAVES WORKBOOK
        excel.Quit          # QUITS EXCEL APP
    
        # RELEASES COM RESOURCES
        ws = None; wb = None; objs = None; ole = None; excel = None
    

    Tkinter Messagebox

提交回复
热议问题