我正在使用Office 2007。我发现如果我想在office2007中显示与图表重叠的图例。XML应该如下所示。
`-<c:legend>
<c:overlay val="1"/>` 但是,无论我使用来自python-pptx 'chart.legend.include_in_layout = True‘的API,还是将其保留为默认值。生成的XML总是如下所示。
`-<c:legend>
<c:overlay/>` 如果没有val=1,office2007将无法正确显示格式。我能做些什么来强制python-pptx写val=1?谢谢。
发布于 2017-03-12 03:23:38
解释
简而言之,True值没有显式设置(与False相反),因为True对应于overlay的val属性的默认值。
为了更详细地解释它,您可以遵循python-pptx层次结构,如下所示:overlay从mapped到CT_Boolean (所有覆盖oxml元素都是从CT_Boolean实例化的)。然后,通过OptionalAttribute映射实际的val参数,并使用默认值True进行定义
class CT_Boolean(BaseOxmlElement):
"""
Common complex type used for elements having a True/False value.
"""
val = OptionalAttribute('val', XsdBoolean, default=True)现在,当将可选属性设置为其默认值时,实际上会跳过/删除该属性,如here if value == self._default所示
class OptionalAttribute(BaseAttribute):
"""
Defines an optional attribute on a custom element class. An optional
attribute returns a default value when not present for reading. When
assigned |None|, the attribute is removed.
"""
@property
def _setter(self):
def set_attr_value(obj, value):
if value == self._default:
if self._clark_name in obj.attrib:
del obj.attrib[self._clark_name]
return
str_value = self._simple_type.to_xml(value)
obj.set(self._clark_name, str_value)
return set_attr_valueFix -提供自定义CT_Boolean类
在需要使用overlay之前,将这些行添加到某个位置。它将使用自定义CT_Boolean_NoDefault类覆盖python-pptx overlay映射:
from pptx.oxml import register_element_cls
from pptx.oxml.xmlchemy import BaseOxmlElement, OptionalAttribute
from pptx.oxml.simpletypes import XsdBoolean
class CT_Boolean_NoDefault(BaseOxmlElement):
"""
Common complex type used for elements having a True/False value with no
default value.
"""
val = OptionalAttribute('val', XsdBoolean)
register_element_cls('c:overlay', CT_Boolean_NoDefault)这对我很有效,最后我得到了:
<c:legend>
<c:overlay val="1"/>
</c:legend>修复-永久修改python-pptx
不建议这样做,但您可能希望修改python-pptx,而不是从上面为您运行的每个脚本添加解决方案。
首先,将以下内容添加到pptx/oxml/chart/shared.py中,它定义了一个没有默认值的新布尔类:
class CT_Boolean_NoDefault(BaseOxmlElement):
"""
Common complex type used for elements having a True/False value.
"""
val = OptionalAttribute('val', XsdBoolean)其次,修改pptx/oxml/__init__.py以添加新的bool类:
from .chart.shared import (
CT_Boolean, CT_Double, CT_Layout, CT_LayoutMode, CT_ManualLayout,
CT_NumFmt, CT_Tx, CT_UnsignedInt, CT_Boolean_NoDefault
)第三,修改pptx/oxml/__init__.py以更改overlay元素到新bool类的映射:
register_element_cls('c:overlay', CT_Boolean_NoDefault)更好的解决方案
如果您有时间,请提交工单here,以便它可能成为永久修复。如果@scanny有时间,他会读这篇文章。也许对此也有更好的解决方案,但我完全忽略了一些东西。
发布于 2017-03-19 03:59:25
@pansen的分析很准确。这里有一种替代方法,可以让它在你的情况下工作,可能会稍微轻一点:
def include_in_layout(legend):
legend_element = legend._element
overlay = legend_element.get_or_add_overlay()
overlay.set('val', '1')这似乎是该版本的PowerPoint与ISO/IEC 29500规范的本地化不一致。正如pansen正确指出的那样,缺少的val属性将被解释为与val=1 (True)相同。我很有兴趣了解这种不符合的程度,也就是说,还有哪些元素表现出同样的行为。在PowerPoint中,CT_Boolean类型经常用于粗体、斜体、varyColors、平滑等。因此,需要谨慎地应用“补偿”修复,以避免报告其他元素的不正确结果。
我想我将按照pansen的提示,只对这个元素使用一个专用的元素类。对于没有val属性的元素,它仍将报告True,这将与在此版本的PowerPoint上观察到的行为不一致;但假设其他版本的行为正确(根据规范),这种不一致将被定位,至少为该属性分配True将使图例以您想要的方式显示。
https://stackoverflow.com/questions/42731073
复制相似问题