微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python Pptx无法正确捕获幻灯片母版名称

如何解决Python Pptx无法正确捕获幻灯片母版名称

在使用Python PPTX玩耍,似乎无法正确读取幻灯片母版名称

您可以在此处看到我将幻灯片母版重命名

enter image description here

,甚至在尝试添加幻灯片时也会显示

enter image description here

但是,当我通过pptx加载演示文稿时,名称''

In [14]: import pptx
In [15]: pres = pptx.Presentation("adsf.pptx")
In [16]: pres.slide_master.name
Out[17]: ''

也许我在Powerpoint方面做错了。我很想知道。我正在使用Office2016。作为一个旁注,我正在研究xml,看来slidemaster xml没有保存与ooxml中的name属性相关的任何属性。但是主题xml可以。让我感到困惑。

感谢您的时间和精力

编辑:

enter image description here

enter image description here

所有这些之后,我找到了解决方案,并感谢@Scanny

import pptx
import re
from lxml import etree

# This causes pres.slide_master.layout.placeholder.name to be passed to pres.slide.placeholder
@property
def placeholder_name(self):
    """Name of the placeholder inherited from slide master"""
    return self._inherited_value("name")

def Presentation(powerpoint=None):
    """
    Return a |Presentation| object loaded from *pptx*,where *pptx* can be
    either a path to a ``.pptx`` file (a string) or a file-like object. If
    *pptx* is missing or ``None``,the built-in default presentation
    "template" is loaded.
    """
    if powerpoint is None:
        powerpoint = pptx.api._default_pptx_path()

    # get the package and not just the presentation package
    package = pptx.package.Package.open(powerpoint)

    # Now extract the document
    presentation_part = package.main_document_part

    if not pptx.api._is_pptx_package(presentation_part):
        tmpl = "file '%s' is not a PowerPoint file,content type is '%s'"
        raise ValueError(tmpl % (powerpoint,presentation_part.content_type))

    # the theme names are the slide master names
    themes = (part for part in package.parts if re.search("^/ppt/theme/theme\d+\.xml$",part.partname))
    theme_names = [etree.fromstring(theme.blob).get("name") for theme in themes]


    # Now get the presentation
    presentation = presentation_part.presentation

    # change the slide master names
    for idx,sld_mstr in enumerate(presentation.slide_masters):
        sld_mstr.name = theme_names[idx]


    return presentation

pptx.Presentation = Presentation
pptx.shapes.placeholder._InheritsDimensions.placeholder_name = placeholder_name
In [2]: pres = pptx.Presentation("adsf.pptx")
In [3]: for sm in pres.slide_masters: print(sm.name)
my master
number 3
my second
In [4]: layout = pres.slide_masters[0].slide_layouts[0]
In [5]: layout.name
Out[5]: 'my master title slide layout'
In [6]: new_slide = pres.slides.add_slide(layout)
In [7]: new_slide.placeholders[0].name
Out[7]: 'Title 1'
In [8]: new_slide.placeholders[0].placeholder_name
Out[8]: 'Main Title'
In [9]: pres.save("test.pptx")                             

解决方法

是的,这就是我要进行的工作,在XML中查找字符串“ my master”,并查看其显示位置。

PowerPoint主题包括母版和布局,因此UI可以使用此 rename 操作对主题进行重命名,从UI角度来看这很有意义,就像您要保存此主题一样然后在列表中选择该名称即可使用它。

反向操作可能很有意义,这意味着使用python-pptx设置主名称,将其读出以进行确认,然后查看该名称在以后的UI中的位置(如果有的话)。


您可以直接从演示文稿转到演示文稿部分:

prs = Presentation(...)
presentation_part = prs._part

所有部分都对该包进行了引用,您不必自己加载它:

package = presentation_part._package

但是您可能不需要,因为您可以直接从演示文稿部分进入演示文稿主题(与Notes页面主题等相对):

from pptx.opc.constants import RELATIONSHIP_TYPE as RT

theme_rels = [rel for rel in presentation_part.rels if rel.reltype == RT.THEME]
theme_parts = [presentation_part.related_parts[rel.rId] for rel in theme_rels]

然后只需将每个主题作为XmlPart加载,例如:

theme_parts = [
    XmlPart.load(
        part._partname,part._content_type,part._blob,part._package,)
    for part in theme_parts
]

然后您可以在theme_part._element上获取主题XML文档的根,并可以在该树上使用lxml.etree._Element方法来遍历该树,或者仅使用{{1}来获取根元素名称}。

这只是内存中的空代码,但希望能给您足够的空间,一旦到达那里就可以发布工作代码。

如果您所做的工作一定可以使用它,但这可能更直接,并且可以使用那里已有的实现,因此您不必担心出乎意料的错误:)

几乎所有执行的代码都在theme_part._element.attribs["name"]中。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。