Python-pptx:“显示重叠图表的图例”

时间:2017-03-11 03:41:03

标签: python legend python-pptx

我正在使用Office 2007。 我发现我是否想在office2007中显示与图表重叠的图例。 XML应如下所示。

`-<c:legend>
   <c:overlay val="1"/>` 

但无论我使用python-pptx中的API&map; .legend.include_in_layout = True&#39;或者我将其保留为默认值。生成的XML将始终如下所示。

`-<c:legend>
   <c:overlay/>` 

如果没有val = 1,那么office2007将无法正确显示格式。 我该怎么做才能强制python-pptx写val = 1?感谢。

2 个答案:

答案 0 :(得分:1)

解释

简而言之,True值未明确设置(与False相比),因为True对应于overlay&#39; s {的默认值{1}}属性。

为了更详细地解释它 - 你可以按照以下方式遵循python-pptx层次结构:valmappedCT_Boolean(所有重叠的oxml元素都是从CT_Boolean实例化的)。然后,实际的overlay参数会通过OptionalAttribute进行映射,并使用默认值val进行定义:

True

现在,在将可选属性设置为其默认值时,实际上会跳过/删除它,因为您可以看到here class CT_Boolean(BaseOxmlElement): """ Common complex type used for elements having a True/False value. """ val = OptionalAttribute('val', XsdBoolean, default=True)

if value == self._default

修复 - 提供自定义CT_Boolean类

在需要使用叠加层之前,在某处添加这些线条。它将使用自定义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_value 类覆盖python-pptx overlay映射:

CT_Boolean_NoDefault

这对我有用,最后我得到了:

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)

修复 - 永久修改python-pptx

不推荐这样做,但您可能希望修改python-pptx,而不是为您运行的每个脚本添加上面的解决方案。

首先,将以下内容添加到<c:legend> <c:overlay val="1"/> </c:legend> ,它定义了一个没有默认值的新bool类:

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) 以添加新的bool类:

pptx/oxml/__init__.py

第三,修改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元素到新bool类的映射:

overlay

更好的解决方案

如果您有时间,请提交一张票here,以便它可能成为永久性修复。如果@scanny找到一些时间,他会读到这个。或许也有一些更好的解决方案,而且我完全错过了一些东西。

答案 1 :(得分:1)

@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规范的本地化不一致。正如潘森正确指出的那样,缺少val属性的解释与val=1True)相同。我有兴趣发现这种不一致性有多广泛,即其他元素表现出同样的行为。 CT_Boolean类型在PowerPoint中经常使用,例如粗体,斜体,varyColors,smooth,以及on和on。所以&#34;补偿&#34;需要谨慎应用修复,以避免报告其他元素的错误结果。

我想我会采用pansen的提示并仅为此元素使用专门的元素类。对于没有val属性的元素,它仍会报告True,这与此版本的PowerPoint中观察到的行为不一致;但假设其他版本的行为正确(根据规范),不一致性将被本地化,至少为该属性分配True将使图例以您希望的方式显示。