如何使用 Python 从 Excel table 中提取 OLE 对象?
How to extract OLE objects from Excel table using Python?
我想使用 Python 从 Excel table 中提取 OLE 对象到 Windows 剪贴板中。
没有进一步帮助,因为它用于 VBA。
this post 仍未得到答复。
假设给定 Excel table(使用 ChemDraw 或 ChemSketch OLE 对象):
有一些 Python 模块可以处理 Excel 文件,例如openpyxl
、xlrd
。
模块win32clipboard
可以将数据放入剪贴板。
我的问题:
- 我不知道如何将嵌入的 OLE 对象添加到剪贴板。可能
openpyxl
和 xlrd
以及 win32clipboard
不适合这个?
- 有一个 Python 模块
oletools
也许可以做到,但我不明白它是如何工作的。
https://pypi.org/project/oletools/
从这个页面:
oleobj
: to extract embedded objects from OLE files.
这似乎正是我要找的东西,但是,我找不到任何 MCVE。不幸的是,oleobj
的文档基本上缩减为:"read the source code and find out yourself"。如果能提供提示和帮助,我将不胜感激。
到目前为止我的代码:
### 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
与此同时,我发现 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.
我构建了一个 python 模块来执行此操作,请在此处查看。 https://pypi.org/project/AttachmentsExtractor/ 模块也可以是 运行 在任何 os.
安装库后使用以下代码片段:
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.
我想使用 Python 从 Excel table 中提取 OLE 对象到 Windows 剪贴板中。
假设给定 Excel table(使用 ChemDraw 或 ChemSketch OLE 对象):
有一些 Python 模块可以处理 Excel 文件,例如openpyxl
、xlrd
。
模块win32clipboard
可以将数据放入剪贴板。
我的问题:
- 我不知道如何将嵌入的 OLE 对象添加到剪贴板。可能
openpyxl
和xlrd
以及win32clipboard
不适合这个? - 有一个 Python 模块
oletools
也许可以做到,但我不明白它是如何工作的。 https://pypi.org/project/oletools/
从这个页面:
oleobj
: to extract embedded objects from OLE files.
这似乎正是我要找的东西,但是,我找不到任何 MCVE。不幸的是,oleobj
的文档基本上缩减为:"read the source code and find out yourself"。如果能提供提示和帮助,我将不胜感激。
到目前为止我的代码:
### 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
与此同时,我发现 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.
我构建了一个 python 模块来执行此操作,请在此处查看。 https://pypi.org/project/AttachmentsExtractor/ 模块也可以是 运行 在任何 os.
安装库后使用以下代码片段:
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.