【问题标题】:How to extract OLE objects from Excel table using Python?如何使用 Python 从 Excel 表中提取 OLE 对象?
【发布时间】:2020-05-05 16:37:53
【问题描述】:

我想使用 Python 将 OLE 对象从 Excel 表中提取到 Windows 剪贴板中。

This post 没有进一步帮助,因为它适用于 VBA。 而this post 仍未得到答复。

假设给定的 Excel 表格(带有 ChemDraw 或 ChemSketch OLE 对象):

有一些 Python 模块可以处理 Excel 文件,例如openpyxlxlrd。 模块win32clipboard可以将数据放入剪贴板。

我的问题:

  1. 我看不到如何将嵌入的 OLE 对象放入剪贴板。可能openpyxlxlrd 加上win32clipboard 不适合这个?
  2. 有一个 Python 模块 oletools 可能可以做到,但我不明白它是如何工作的。 https://pypi.org/project/oletools/

从此页面:

oleobj:从 OLE 文件中提取嵌入对象。

这似乎正是我正在寻找的,但是,我找不到任何 MCVE。而不幸的是,oleobj 的文档基本上被简化为:“阅读源代码并找出自己”。我将不胜感激提示和帮助。

到目前为止我的代码:

### trying to extract OLE objects from Excel table into clipboard
from openpyxl import load_workbook
import win32clipboard as clpbd

def set_clipboard(data):
    clpbd.OpenClipboard()
    clpbd.EmptyClipboard()
    clpbd.SetClipboardText(data)    # I'm aware, this is only for text, is there anything for OLEs?
    clpbd.CloseClipboard()

def print_clipboard():
    clpbd.OpenClipboard()
    data = clpbd.GetClipboardData()
    clpbd.CloseClipboard()
    print(data)

wb = load_workbook(filename = 'tbChemOLE.xlsx')
ws = wb.active

myName = ws['A3'].value    # result: napthalene
myImage = ws['B3'].value   # result: None
myObject = ws['C3'].value  # result: None

set_clipboard(myName)
print_clipboard()          # result: Naphtalene
# set_clipboard(myImage)   # crash, because myImage is None
print_clipboard()     
# set_clipboard(myObject)  # crash, because myObject is None
print_clipboard()        

wb.close()
### end of code

【问题讨论】:

    标签: python excel ole cheminformatics


    【解决方案1】:

    我构建了一个 python 模块来执行此操作,请在此处查看。 https://pypi.org/project/AttachmentsExtractor/ 该模块也可以在任何操作系统上运行。

    安装库后使用以下代码 sn-p:

     from AttachmentsExtractor import extractor
                
     abs_path_to_file='Please provide absolute path here '
     path_to_destination_directory = 'Please provide path of the directory where the extracted attachments should be stored'
     extractor.extract(abs_path_to_file,path_to_destination_directory) # returns true if one or more attachments are found else returns false.
    

    【讨论】:

      【解决方案2】:

      与此同时,我发现了this post,OP 实际上不希望剪贴板上的 OLE 对象,但对我来说这很好。其实openpyxl或者xlrd不需要,但是win32com.client是必须的。

      我可以获取所有 OLE 对象,但是,它们(可能)按照它们添加的顺序被索引。 所以我需要创建一个字典,其中行索引作为键,一组 OLE 对象索引和名称作为值。

      代码:

      ### copy OLE object in certain cell to clipboard
      import win32com.client as win32
      import win32clipboard
      
      excel = win32.gencache.EnsureDispatch('Excel.Application')
      ffname = r'C:\Test\tbChemOLE.xlsx'
      wb = excel.Workbooks.Open(ffname)
      ws = wb.Worksheets.Item(1)
      objs = ws.OLEObjects()
      
      def get_all_OLEs():
          oleNo_dict = {}     # dictionary for all OLE objects
          for i in range(1,len(objs)+1):    # loop all OLE objects
              obj = objs.Item(i) 
              myRow = obj.TopLeftCell.Row        # row of OLE object
              myName = ws.Cells(myRow,1).Value   # corresponding name
              oleNo_dict[myRow] = (i, myName)
          return oleNo_dict
      
      def get_OLE(row):
          try: 
              objs[oleNo_dict[row][0]].Copy()
              win32clipboard.OpenClipboard()
              data = win32clipboard.GetClipboardData(0xC004) # Binary access
              win32clipboard.CloseClipboard()
          except Exception as e:
              print(e)
              win32clipboard.OpenClipboard()
              win32clipboard.EmptyClipboard()
              win32clipboard.CloseClipboard()
          return oleNo_dict[row]
          # and OLE is on clipboard if found
      
      oleNo_dict = get_all_OLEs()
      
      row = 4
      myMolecule = get_OLE(row)
      print(myMolecule[1], "OLE object is now on the clipboard.")
      
      wb.Close()
      excel.Application.Quit()
      ### end of code
      

      结果:

      Anthracene OLE object is now on the clipboard.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-04
        • 2012-05-29
        • 1970-01-01
        • 2012-04-14
        • 2010-09-25
        • 2012-08-29
        • 1970-01-01
        相关资源
        最近更新 更多