1

我正在使用 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?谢谢。

4

2 回答 2

1

解释

简而言之,该True值没有显式设置(与 相比False),因为True对应于overlay'sval属性的默认值。

为了更详细地解释它 - 您可以按照以下方式遵循 python-pptx 层次结构:overlay映射到(所有覆盖oxmlCT_Boolean元素都从 CT_Boolean 实例化)。实际val参数然后通过映射OptionalAttribute并使用默认值定义True

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看到的:

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

修复 - 提供自定义 CT_Boolean 类

在需要使用叠加层之前将这些行添加到某处。它将使用自定义类覆盖 python-pptxoverlay映射: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)

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

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

修复 - 永久修改 python-pptx

不建议这样做,但您可能想要修改 python-pptx 而不是从上面为您运行的每个脚本添加解决方案。

首先,添加以下内容,pptx/oxml/chart/shared.py其中定义了一个没有默认值的新 bool 类:

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
)

三、修改改变元素到新的bool类pptx/oxml/__init__.py的映射:overlay

register_element_cls('c:overlay', CT_Boolean_NoDefault)

更好的解决方案

如果您有时间,请提交一张票here,以便它可能成为永久修复。万一@scanny有时间,他会阅读这篇文章。也许对此也有更好的解决方案,我完全错过了一些东西。

于 2017-03-11T19:23:38.010 回答
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=1( True) 相同。我很想知道这种不符合的范围有多大,即其他元素表现出同样的行为。该CT_Boolean类型在 PowerPoint 中使用得非常频繁,例如粗体、斜体、variableColors、smooth 等。因此,需要仔细应用“补偿”修复,以避免报告其他元素的错误结果。

我想我会听从 pansen 的建议,只为这个元素使用一个专门的元素类。它仍然会报告True没有 val 属性的元素,这将与在此版本的 PowerPoint 上观察到的行为不一致;但假设其他版本行为正确(根据规范),不一致将被本地化,并且至少分配True给该属性将使图例以您想要的方式显示。

于 2017-03-18T19:59:25.250 回答