使用 Python 管理演示文稿中的 OLE

简介

例如,在 Microsoft Excel 中创建并放置在 PowerPoint 幻灯片上的图表就是一个 OLE 对象。

  • OLE 对象可能以图标形式出现。双击图标会在其关联的应用程序(例如 Excel)中打开对象,或提示您选择应用程序来打开或编辑它。
  • OLE 对象也可能直接显示其内容(例如图表)。在这种情况下,PowerPoint 会激活嵌入的对象,加载图表界面,并允许您在 PowerPoint 中编辑图表数据。

Aspose.Slides for Python 允许您将 OLE 对象作为 OLE 对象帧插入幻灯片(OleObjectFrame)。

向幻灯片添加 OLE 对象

如果您已经在 Microsoft Excel 中创建了图表,并希望使用 Aspose.Slides for Python 将其作为 OLE 对象帧嵌入幻灯片,请按以下步骤操作:

  1. 创建一个 Presentation 类的实例。
  2. 按索引获取幻灯片的引用。
  3. 将 Excel 文件读取为字节数组。
  4. 向幻灯片添加一个 OleObjectFrame,提供字节数组和其他 OLE 对象详细信息。
  5. 将修改后的演示文稿保存为 PPTX 文件。

下面的示例将 Excel 文件中的图表嵌入为一个 OleObjectFrame。

注意: OleEmbeddedDataInfo 构造函数将可嵌入对象的文件扩展名作为第二个参数。PowerPoint 使用此扩展名来识别文件类型并选择相应的应用程序打开 OLE 对象。

import aspose.slides as slides

with slides.Presentation() as presentation:
    slide_size = presentation.slide_size.size
    slide = presentation.slides[0]

    # 为 OLE 对象准备数据。
    with open("book.xlsx", "rb") as file_stream:
        file_data = file_stream.read()
        data_info = slides.dom.ole.OleEmbeddedDataInfo(file_data, "xlsx")

    # 向幻灯片添加 OLE 对象帧。
    ole_frame = slide.shapes.add_ole_object_frame(0, 0, slide_size.width, slide_size.height, data_info)

    presentation.save("output.pptx", slides.export.SaveFormat.PPTX)

添加链接的 OLE 对象

Aspose.Slides for Python 允许您添加一个链接到文件而不是嵌入其数据的 OleObjectFrame。

下面的 Python 示例展示了如何在幻灯片上添加一个链接到 Excel 文件的 OleObjectFrame:

import aspose.slides as slides

with slides.Presentation() as presentation:
    slide = presentation.slides[0]

    # 添加一个链接到 Excel 文件的 OLE 对象帧。
    slide.shapes.add_ole_object_frame(20, 20, 200, 150, "Excel.Sheet.12", "book.xlsx")

    presentation.save("output.pptx", slides.export.SaveFormat.PPTX)

访问 OLE 对象

如果幻灯片中已经嵌入了 OLE 对象,您可以按如下方式访问它:

  1. 通过创建 Presentation 类的实例加载包含嵌入 OLE 对象的演示文稿。
  2. 按索引获取幻灯片的引用。
  3. 访问 OleObjectFrame 形状。
  4. 获取 OLE 对象帧后,对其执行所需的操作。

下面的示例访问 OLE 对象帧——一个嵌入的 Excel 图表,并检索其文件数据。该示例使用的 PPTX 在第一张幻灯片上只有一个形状。

import aspose.slides as slides

with slides.Presentation("sample.pptx") as presentation:
    slide = presentation.slides[0]
    shape = slide.shapes[0]

    if isinstance(shape, slides.OleObjectFrame):
        ole_frame = shape

        # 获取嵌入文件的数据。
        file_data = ole_frame.embedded_data.embedded_file_data

        # 获取嵌入文件的扩展名。
        file_extension = ole_frame.embedded_data.embedded_file_extension

        # ...

访问链接 OLE 对象的属性

Aspose.Slides 允许您访问链接 OLE 对象帧的属性。

下面的 Python 示例检查 OLE 对象是否为链接,如果是,则检索链接文件的路径:

import aspose.slides as slides

with slides.Presentation("sample.ppt") as presentation:
    slide = presentation.slides[0]
    shape = slide.shapes[0]

    if isinstance(shape, slides.OleObjectFrame):
        ole_frame = shape

        # 检查 OLE 对象是否为链接。
        if ole_frame.is_object_link:
            # 打印链接文件的完整路径。
            print("OLE object frame is linked to:", ole_frame.link_path_long)

            # 打印链接文件的相对路径(如果存在)。
            # 仅 .ppt 演示文稿可以包含相对路径。
            if ole_frame.link_path_relative:
                print("OLE object frame relative path:", ole_frame.link_path_relative)

更改 OLE 对象数据

如果 OLE 对象已经嵌入幻灯片,您可以按以下步骤访问并修改其数据:

  1. 通过创建 Presentation 类的实例加载演示文稿。
  2. 按索引获取目标幻灯片。
  3. 访问 OleObjectFrame 形状。
  4. 获得 OLE 对象帧后,对其执行所需操作。
  5. 创建 Workbook 对象并读取 OLE 数据。
  6. 打开所需的 Worksheet 并编辑数据。
  7. 将更新后的 Workbook 保存到流中。
  8. 使用该流替换 OLE 对象的数据。

下面的示例访问一个 OLE 对象帧(嵌入的 Excel 图表),并修改其文件数据以更新图表。示例使用先前创建的 PPTX,其中第一张幻灯片只有一个形状。

import io
import aspose.slides as slides
import aspose.cells as cells

with slides.Presentation("sample.pptx") as presentation:
    slide = presentation.slides[0]
    shape = slide.shapes[0]

    if isinstance(shape, slides.OleObjectFrame):
        ole_frame = shape

        with io.BytesIO(ole_frame.embedded_data.embedded_file_data) as ole_stream:
            # 读取 OLE 对象数据为 Workbook 对象。
            workbook = cells.Workbook(ole_stream)

        with io.BytesIO() as new_ole_stream:
            # 修改工作簿数据。
            workbook.worksheets.get(0).cells.get(0, 4).put_value("E")
            workbook.worksheets.get(0).cells.get(1, 4).put_value(12)
            workbook.worksheets.get(0).cells.get(2, 4).put_value(14)
            workbook.worksheets.get(0).cells.get(3, 4).put_value(15)

            file_options = cells.OoxmlSaveOptions(cells.SaveFormat.XLSX)
            workbook.save(new_ole_stream, file_options)

            # 更改 OLE 框对象数据。
            new_data = slides.dom.ole.OleEmbeddedDataInfo(new_ole_stream.getvalue(), ole_frame.embedded_data.embedded_file_extension)
            ole_frame.set_embedded_data(new_data)

    presentation.save("output.pptx", slides.export.SaveFormat.PPTX)

在幻灯片中嵌入文件

除了 Excel 图表,Aspose.Slides for Python 还允许您在幻灯片中嵌入其他文件类型。例如,您可以将 HTML、PDF 和 ZIP 文件作为对象插入。用户双击插入的对象时,会自动在关联的应用程序中打开,或提示用户选择合适的程序。

下面的 Python 代码展示了如何在幻灯片中嵌入 HTML 和 ZIP 文件:

import aspose.slides as slides

with slides.Presentation() as presentation:
    slide = presentation.slides[0]

    with open("sample.html", "rb") as html_stream:
        html_data = html_stream.read()

    html_data_info = slides.dom.ole.OleEmbeddedDataInfo(html_data, "html")
    html_ole_frame = slide.shapes.add_ole_object_frame(150, 120, 50, 50, html_data_info)
    html_ole_frame.is_object_icon = True

    with open("sample.zip", "rb") as zip_stream:
        zip_data = zip_stream.read()

    zip_data_info = slides.dom.ole.OleEmbeddedDataInfo(zip_data, "zip")
    zip_ole_frame = slide.shapes.add_ole_object_frame(150, 220, 50, 50, zip_data_info)
    zip_ole_frame.is_object_icon = True

    presentation.save("output.pptx", slides.export.SaveFormat.PPTX)

设置嵌入对象的文件类型

在处理演示文稿时,您可能需要用新对象替换旧的 OLE 对象,或将不受支持的 OLE 对象替换为受支持的对象。Aspose.Slides for Python 允许您设置嵌入对象的文件类型,从而更新 OLE 帧数据或其文件扩展名。

下面的 Python 代码展示了如何将嵌入 OLE 对象的文件类型设置为 zip:

import aspose.slides as slides

with slides.Presentation("sample.pptx") as presentation:
    slide = presentation.slides[0]
    ole_frame = slide.shapes[0]

    file_extension = ole_frame.embedded_data.embedded_file_extension
    file_data = ole_frame.embedded_data.embedded_file_data

    print(f"Current embedded file extension is: {file_extension}")

    # 将文件类型更改为 ZIP。
    ole_frame.set_embedded_data(slides.dom.ole.OleEmbeddedDataInfo(file_data, "zip"))

    presentation.save("output.pptx", slides.export.SaveFormat.PPTX)

设置嵌入对象的图标图像和标题

嵌入 OLE 对象后,系统会自动添加基于图标的预览。此预览是用户在访问或打开 OLE 对象前看到的内容。如果您想在预览中使用特定的图像和文字,可以使用 Aspose.Slides for Python 设置图标图像和标题。

下面的 Python 代码展示了如何为嵌入对象设置图标图像和标题:

import aspose.slides as slides

with slides.Presentation("sample.pptx") as presentation:
    slide = presentation.slides[0]
    ole_frame = slide.shapes[0]

    # 将图像添加到演示文稿资源。
    with slides.Images.from_file("image.png") as image:
        ole_image = presentation.images.add_image(image)

    # 设置 OLE 预览的标题和图像。
    ole_frame.substitute_picture_title = "My title"
    ole_frame.substitute_picture_format.picture.image = ole_image
    ole_frame.is_object_icon = True

    presentation.save("output.pptx", slides.export.SaveFormat.PPTX)

防止 OLE 对象帧被重新调整大小和重新定位

在幻灯片中添加链接的 OLE 对象后,打开演示文稿时 PowerPoint 可能会提示更新链接。选择“更新链接”会因 PowerPoint 使用链接对象的数据刷新预览而改变 OLE 对象帧的大小和位置。为防止 PowerPoint 提示更新对象数据,请将 OleObjectFrame 类的 update_automatic 属性设为 False:

import aspose.slides as slides

with slides.Presentation("sample.pptx") as presentation:
    slide = presentation.slides[0]
    ole_frame = slide.shapes[0]

    ole_frame.update_automatic = False

    presentation.save("output.pptx", slides.export.SaveFormat.PPTX)

提取嵌入文件

Aspose.Slides for Python 允许您按以下方式提取嵌入幻灯片中的 OLE 对象文件:

  1. 创建一个包含要提取的 OLE 对象的 Presentation 类实例。
  2. 遍历演示文稿中的所有形状,定位 OLEObjectFrame 形状。
  3. 从每个 OLEObjectFrame 中检索嵌入的文件数据并写入磁盘。

下面的 Python 代码展示了如何提取幻灯片中作为 OLE 对象嵌入的文件:

import aspose.slides as slides

with slides.Presentation("sample.pptx") as presentation:
    slide = presentation.slides[0]

    for index, shape in enumerate(slide.shapes):
        if isinstance(shape, slides.OleObjectFrame):
            ole_frame = shape

            file_data = ole_frame.embedded_data.embedded_file_data
            file_extension = ole_frame.embedded_data.embedded_file_extension

            file_path = f"OLE_object_{index}{file_extension}"
            with open(file_path, 'wb') as file_stream:
                file_stream.write(file_data)

常见问题

在将幻灯片导出为 PDF/图像时,OLE 内容会被渲染吗?

渲染的是幻灯片上可见的内容——图标/替代图像(预览)。“实时” OLE 内容在渲染过程中不会执行。如有需要,可设置自己的预览图像,以确保在导出的 PDF 中得到预期的外观。

如果还想将嵌入的文件作为 PDF 附件保留,请将 PdfOptions.include_ole_data 设为 True。此选项默认禁用。有关示例和检查附件的说明,请参阅 Preserve Embedded OLE Files as PDF Attachments。

如何锁定幻灯片上的 OLE 对象,使用户在 PowerPoint 中无法移动或编辑它?

锁定形状:Aspose.Slides 提供了 shape-level locks。这不是加密,但可有效防止意外编辑和移动。

为什么在打开演示文稿时,链接的 Excel 对象会“跳动”或改变大小?

PowerPoint 可能会刷新链接 OLE 的预览。为获得稳定的外观,请遵循 Working Solution for Worksheet Resizing 的做法——要么让帧适应范围,要么将范围缩放到固定帧并设置合适的替代图像。

在 PPTX 格式中,链接的 OLE 对象的相对路径会被保留吗?

在 PPTX 中没有“相对路径”信息——仅有完整路径。相对路径出现在旧的 PPT 格式中。为实现可移植性,建议使用可靠的绝对路径/可访问的 URI 或嵌入方式。