我目前正在使用 openpyxl 将新工作表添加到 .xlsm 文件中,并使用 (read_only=False)
例如。
wb = openpyxl.load_workbook("Input_file.xlsm", read_only=False, keep_vba=True)
sheet = wb.create_sheet('Source_Data')
final_row = dataframe_to_rows(final_df)
# code to add final row to sheet Source_Data
wb.save("Input_file.xlsm")
wb.close()
Below is the error message
~\AppData\Local\Programs\Python\Python39\lib\zipfile.py in getinfo(self, name)
1427 info = self.NameToInfo.get(name)
1428 if info is None:
-> 1429 raise KeyError(
1430 'There is no item named %r in the archive' % name)
1431
KeyError: "There is no item named 'xl/drawings/NULL' in the archive"
我也遇到了完全相同的问题。我设法轻松解决它(我不明白为什么,但它有效)。 显然,一些隐藏的纸张中粘贴了一些图像。
您需要找到并删除它们。 (也许让它们可见也能达到目的 - 我没有检查) 有两种方法可以做到这一点。选择工作簿中的每个工作表。然后:
选项1: 按 F5 -> 特殊 -> 对象 这将突出显示工作表上的所有隐藏图像
选项2: 转到“主页”选项卡 -> 按“查找并选择” -> 按“选择窗格” 您可以查看所有隐藏的图像 - 并删除它们
如果您对猴子补丁 openpyxl 感到满意,这可以修复它:
from openpyxl import load_workbook
import openpyxl.reader.drawings
import openpyxl.reader.excel
from openpyxl.reader.drawings import (
fromstring,
SpreadsheetDrawing,
get_rel,
get_rels_path,
get_dependents,
ChartSpace,
read_chart,
PILImage,
IMAGE_NS,
Image,
BytesIO,
warn,
)
# monkey patching to fix the issue with the openpyxl library
# where it doesn't allow hidden images
# here: https://openpyxl.readthedocs.io/en/3.1.2/api/openpyxl.reader.drawings.html#openpyxl.reader.drawings.find_images
def new_find_images(archive, path):
"""
Our monkey patched version of the openpyxl.reader.drawings.find_images
Given the path to a drawing file extract charts and images
Ignore errors due to unsupported parts of DrawingML
Also ignore hidden images (our monkey patch)
"""
src = archive.read(path)
tree = fromstring(src)
try:
drawing = SpreadsheetDrawing.from_tree(tree)
except TypeError:
warn(
"DrawingML support is incomplete and limited to charts and images only. Shapes and drawings will be lost."
)
return [], []
rels_path = get_rels_path(path)
print(path, rels_path)
deps = []
if rels_path in archive.namelist():
deps = get_dependents(archive, rels_path)
charts = []
for rel in drawing._chart_rels:
try:
cs = get_rel(archive, deps, rel.id, ChartSpace)
except TypeError as e:
warn(f"Unable to read chart {rel.id} from {path} {e}")
continue
chart = read_chart(cs)
chart.anchor = rel.anchor
charts.append(chart)
images = []
if not PILImage: # Pillow not installed, drop images
return charts, images
for rel in drawing._blip_rels:
dep = deps[rel.embed]
if dep.target == "xl/drawings/NULL":
# new line to skip hidden images
msg = "Hidden images are not supported so the image is being dropped"
warn(msg)
continue
if dep.Type == IMAGE_NS:
try:
print(dep.target)
image = Image(BytesIO(archive.read(dep.target)))
except OSError:
msg = "The image {0} will be removed because it cannot be read".format(
dep.target
)
warn(msg)
continue
if image.format.upper() == "WMF": # cannot save
msg = "{0} image format is not supported so the image is being dropped".format(
image.format
)
warn(msg)
continue
image.anchor = rel.anchor
images.append(image)
return charts, images
# apply monkey patched function
openpyxl.reader.drawings.find_images = new_find_images
openpyxl.reader.excel.find_images = new_find_images # type: ignore[attr-defined]
kwargs = {} # enter yours
wb = load_workbook("Input_file.xlsm", **kwargs)