使用 openpyxl 打开 .xlsm 文件时出现问题

问题描述 投票:0回答:2

我目前正在使用 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"
python openpyxl xlsm
2个回答
0
投票

我也遇到了完全相同的问题。我设法轻松解决它(我不明白为什么,但它有效)。 显然,一些隐藏的纸张中粘贴了一些图像。

您需要找到并删除它们。 (也许让它们可见也能达到目的 - 我没有检查) 有两种方法可以做到这一点。选择工作簿中的每个工作表。然后:

选项1: 按 F5 -> 特殊 -> 对象 这将突出显示工作表上的所有隐藏图像

选项2: 转到“主页”选项卡 -> 按“查找并选择” -> 按“选择窗格” 您可以查看所有隐藏的图像 - 并删除它们


0
投票

如果您对猴子补丁 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)
© www.soinside.com 2019 - 2024. All rights reserved.