如何解决Python Pptx无法正确捕获幻灯片母版名称
在使用Python PPTX玩耍,似乎无法正确读取幻灯片母版名称。
但是,当我通过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可以。让我感到困惑。
感谢您的时间和精力
编辑:
所有这些之后,我找到了解决方案,并感谢@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 举报,一经查实,本站将立刻删除。