Updated script that can be controled by Nodejs web app

This commit is contained in:
mac OS
2024-11-25 12:24:18 +07:00
parent c440eda1f4
commit 8b0ab2bd3a
8662 changed files with 1803808 additions and 34 deletions

View File

@ -0,0 +1,4 @@
# Copyright (c) 2010-2024 openpyxl
from .drawing import Drawing

View File

@ -0,0 +1,435 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Alias,
Typed,
Integer,
Set,
MinMax,
)
from openpyxl.descriptors.excel import Percentage
from openpyxl.descriptors.nested import (
NestedNoneSet,
NestedValue,
NestedInteger,
EmptyTag,
)
from openpyxl.styles.colors import RGB
from openpyxl.xml.constants import DRAWING_NS
from openpyxl.descriptors.excel import ExtensionList as OfficeArtExtensionList
PRESET_COLORS = [
'aliceBlue', 'antiqueWhite', 'aqua', 'aquamarine',
'azure', 'beige', 'bisque', 'black', 'blanchedAlmond', 'blue',
'blueViolet', 'brown', 'burlyWood', 'cadetBlue', 'chartreuse',
'chocolate', 'coral', 'cornflowerBlue', 'cornsilk', 'crimson', 'cyan',
'darkBlue', 'darkCyan', 'darkGoldenrod', 'darkGray', 'darkGrey',
'darkGreen', 'darkKhaki', 'darkMagenta', 'darkOliveGreen', 'darkOrange',
'darkOrchid', 'darkRed', 'darkSalmon', 'darkSeaGreen', 'darkSlateBlue',
'darkSlateGray', 'darkSlateGrey', 'darkTurquoise', 'darkViolet',
'dkBlue', 'dkCyan', 'dkGoldenrod', 'dkGray', 'dkGrey', 'dkGreen',
'dkKhaki', 'dkMagenta', 'dkOliveGreen', 'dkOrange', 'dkOrchid', 'dkRed',
'dkSalmon', 'dkSeaGreen', 'dkSlateBlue', 'dkSlateGray', 'dkSlateGrey',
'dkTurquoise', 'dkViolet', 'deepPink', 'deepSkyBlue', 'dimGray',
'dimGrey', 'dodgerBlue', 'firebrick', 'floralWhite', 'forestGreen',
'fuchsia', 'gainsboro', 'ghostWhite', 'gold', 'goldenrod', 'gray',
'grey', 'green', 'greenYellow', 'honeydew', 'hotPink', 'indianRed',
'indigo', 'ivory', 'khaki', 'lavender', 'lavenderBlush', 'lawnGreen',
'lemonChiffon', 'lightBlue', 'lightCoral', 'lightCyan',
'lightGoldenrodYellow', 'lightGray', 'lightGrey', 'lightGreen',
'lightPink', 'lightSalmon', 'lightSeaGreen', 'lightSkyBlue',
'lightSlateGray', 'lightSlateGrey', 'lightSteelBlue', 'lightYellow',
'ltBlue', 'ltCoral', 'ltCyan', 'ltGoldenrodYellow', 'ltGray', 'ltGrey',
'ltGreen', 'ltPink', 'ltSalmon', 'ltSeaGreen', 'ltSkyBlue',
'ltSlateGray', 'ltSlateGrey', 'ltSteelBlue', 'ltYellow', 'lime',
'limeGreen', 'linen', 'magenta', 'maroon', 'medAquamarine', 'medBlue',
'medOrchid', 'medPurple', 'medSeaGreen', 'medSlateBlue',
'medSpringGreen', 'medTurquoise', 'medVioletRed', 'mediumAquamarine',
'mediumBlue', 'mediumOrchid', 'mediumPurple', 'mediumSeaGreen',
'mediumSlateBlue', 'mediumSpringGreen', 'mediumTurquoise',
'mediumVioletRed', 'midnightBlue', 'mintCream', 'mistyRose', 'moccasin',
'navajoWhite', 'navy', 'oldLace', 'olive', 'oliveDrab', 'orange',
'orangeRed', 'orchid', 'paleGoldenrod', 'paleGreen', 'paleTurquoise',
'paleVioletRed', 'papayaWhip', 'peachPuff', 'peru', 'pink', 'plum',
'powderBlue', 'purple', 'red', 'rosyBrown', 'royalBlue', 'saddleBrown',
'salmon', 'sandyBrown', 'seaGreen', 'seaShell', 'sienna', 'silver',
'skyBlue', 'slateBlue', 'slateGray', 'slateGrey', 'snow', 'springGreen',
'steelBlue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet',
'wheat', 'white', 'whiteSmoke', 'yellow', 'yellowGreen'
]
SCHEME_COLORS= ['bg1', 'tx1', 'bg2', 'tx2', 'accent1', 'accent2', 'accent3',
'accent4', 'accent5', 'accent6', 'hlink', 'folHlink', 'phClr', 'dk1', 'lt1',
'dk2', 'lt2'
]
class Transform(Serialisable):
pass
class SystemColor(Serialisable):
tagname = "sysClr"
namespace = DRAWING_NS
# color transform options
tint = NestedInteger(allow_none=True)
shade = NestedInteger(allow_none=True)
comp = Typed(expected_type=Transform, allow_none=True)
inv = Typed(expected_type=Transform, allow_none=True)
gray = Typed(expected_type=Transform, allow_none=True)
alpha = NestedInteger(allow_none=True)
alphaOff = NestedInteger(allow_none=True)
alphaMod = NestedInteger(allow_none=True)
hue = NestedInteger(allow_none=True)
hueOff = NestedInteger(allow_none=True)
hueMod = NestedInteger(allow_none=True)
sat = NestedInteger(allow_none=True)
satOff = NestedInteger(allow_none=True)
satMod = NestedInteger(allow_none=True)
lum = NestedInteger(allow_none=True)
lumOff = NestedInteger(allow_none=True)
lumMod = NestedInteger(allow_none=True)
red = NestedInteger(allow_none=True)
redOff = NestedInteger(allow_none=True)
redMod = NestedInteger(allow_none=True)
green = NestedInteger(allow_none=True)
greenOff = NestedInteger(allow_none=True)
greenMod = NestedInteger(allow_none=True)
blue = NestedInteger(allow_none=True)
blueOff = NestedInteger(allow_none=True)
blueMod = NestedInteger(allow_none=True)
gamma = Typed(expected_type=Transform, allow_none=True)
invGamma = Typed(expected_type=Transform, allow_none=True)
val = Set(values=( ['scrollBar', 'background', 'activeCaption',
'inactiveCaption', 'menu', 'window', 'windowFrame', 'menuText',
'windowText', 'captionText', 'activeBorder', 'inactiveBorder',
'appWorkspace', 'highlight', 'highlightText', 'btnFace', 'btnShadow',
'grayText', 'btnText', 'inactiveCaptionText', 'btnHighlight',
'3dDkShadow', '3dLight', 'infoText', 'infoBk', 'hotLight',
'gradientActiveCaption', 'gradientInactiveCaption', 'menuHighlight',
'menuBar'] )
)
lastClr = RGB(allow_none=True)
__elements__ = ('tint', 'shade', 'comp', 'inv', 'gray', "alpha",
"alphaOff", "alphaMod", "hue", "hueOff", "hueMod", "hueOff", "sat",
"satOff", "satMod", "lum", "lumOff", "lumMod", "red", "redOff", "redMod",
"green", "greenOff", "greenMod", "blue", "blueOff", "blueMod", "gamma",
"invGamma")
def __init__(self,
val="windowText",
lastClr=None,
tint=None,
shade=None,
comp=None,
inv=None,
gray=None,
alpha=None,
alphaOff=None,
alphaMod=None,
hue=None,
hueOff=None,
hueMod=None,
sat=None,
satOff=None,
satMod=None,
lum=None,
lumOff=None,
lumMod=None,
red=None,
redOff=None,
redMod=None,
green=None,
greenOff=None,
greenMod=None,
blue=None,
blueOff=None,
blueMod=None,
gamma=None,
invGamma=None
):
self.val = val
self.lastClr = lastClr
self.tint = tint
self.shade = shade
self.comp = comp
self.inv = inv
self.gray = gray
self.alpha = alpha
self.alphaOff = alphaOff
self.alphaMod = alphaMod
self.hue = hue
self.hueOff = hueOff
self.hueMod = hueMod
self.sat = sat
self.satOff = satOff
self.satMod = satMod
self.lum = lum
self.lumOff = lumOff
self.lumMod = lumMod
self.red = red
self.redOff = redOff
self.redMod = redMod
self.green = green
self.greenOff = greenOff
self.greenMod = greenMod
self.blue = blue
self.blueOff = blueOff
self.blueMod = blueMod
self.gamma = gamma
self.invGamma = invGamma
class HSLColor(Serialisable):
tagname = "hslClr"
hue = Integer()
sat = MinMax(min=0, max=100)
lum = MinMax(min=0, max=100)
#TODO add color transform options
def __init__(self,
hue=None,
sat=None,
lum=None,
):
self.hue = hue
self.sat = sat
self.lum = lum
class RGBPercent(Serialisable):
tagname = "rgbClr"
r = MinMax(min=0, max=100)
g = MinMax(min=0, max=100)
b = MinMax(min=0, max=100)
#TODO add color transform options
def __init__(self,
r=None,
g=None,
b=None,
):
self.r = r
self.g = g
self.b = b
class SchemeColor(Serialisable):
tagname = "schemeClr"
namespace = DRAWING_NS
tint = NestedInteger(allow_none=True)
shade = NestedInteger(allow_none=True)
comp = EmptyTag(allow_none=True)
inv = NestedInteger(allow_none=True)
gray = NestedInteger(allow_none=True)
alpha = NestedInteger(allow_none=True)
alphaOff = NestedInteger(allow_none=True)
alphaMod = NestedInteger(allow_none=True)
hue = NestedInteger(allow_none=True)
hueOff = NestedInteger(allow_none=True)
hueMod = NestedInteger(allow_none=True)
sat = NestedInteger(allow_none=True)
satOff = NestedInteger(allow_none=True)
satMod = NestedInteger(allow_none=True)
lum = NestedInteger(allow_none=True)
lumOff = NestedInteger(allow_none=True)
lumMod = NestedInteger(allow_none=True)
red = NestedInteger(allow_none=True)
redOff = NestedInteger(allow_none=True)
redMod = NestedInteger(allow_none=True)
green = NestedInteger(allow_none=True)
greenOff = NestedInteger(allow_none=True)
greenMod = NestedInteger(allow_none=True)
blue = NestedInteger(allow_none=True)
blueOff = NestedInteger(allow_none=True)
blueMod = NestedInteger(allow_none=True)
gamma = EmptyTag(allow_none=True)
invGamma = EmptyTag(allow_none=True)
val = Set(values=(['bg1', 'tx1', 'bg2', 'tx2', 'accent1', 'accent2',
'accent3', 'accent4', 'accent5', 'accent6', 'hlink', 'folHlink', 'phClr',
'dk1', 'lt1', 'dk2', 'lt2']))
__elements__ = ('tint', 'shade', 'comp', 'inv', 'gray', 'alpha',
'alphaOff', 'alphaMod', 'hue', 'hueOff', 'hueMod', 'sat', 'satOff',
'satMod', 'lum', 'lumMod', 'lumOff', 'red', 'redOff', 'redMod', 'green',
'greenOff', 'greenMod', 'blue', 'blueOff', 'blueMod', 'gamma',
'invGamma')
def __init__(self,
tint=None,
shade=None,
comp=None,
inv=None,
gray=None,
alpha=None,
alphaOff=None,
alphaMod=None,
hue=None,
hueOff=None,
hueMod=None,
sat=None,
satOff=None,
satMod=None,
lum=None,
lumOff=None,
lumMod=None,
red=None,
redOff=None,
redMod=None,
green=None,
greenOff=None,
greenMod=None,
blue=None,
blueOff=None,
blueMod=None,
gamma=None,
invGamma=None,
val=None,
):
self.tint = tint
self.shade = shade
self.comp = comp
self.inv = inv
self.gray = gray
self.alpha = alpha
self.alphaOff = alphaOff
self.alphaMod = alphaMod
self.hue = hue
self.hueOff = hueOff
self.hueMod = hueMod
self.sat = sat
self.satOff = satOff
self.satMod = satMod
self.lum = lum
self.lumOff = lumOff
self.lumMod = lumMod
self.red = red
self.redOff = redOff
self.redMod = redMod
self.green = green
self.greenOff = greenOff
self.greenMod = greenMod
self.blue = blue
self.blueOff = blueOff
self.blueMod = blueMod
self.gamma = gamma
self.invGamma = invGamma
self.val = val
class ColorChoice(Serialisable):
tagname = "colorChoice"
namespace = DRAWING_NS
scrgbClr = Typed(expected_type=RGBPercent, allow_none=True)
RGBPercent = Alias('scrgbClr')
srgbClr = NestedValue(expected_type=str, allow_none=True) # needs pattern and can have transform
RGB = Alias('srgbClr')
hslClr = Typed(expected_type=HSLColor, allow_none=True)
sysClr = Typed(expected_type=SystemColor, allow_none=True)
schemeClr = Typed(expected_type=SchemeColor, allow_none=True)
prstClr = NestedNoneSet(values=PRESET_COLORS)
__elements__ = ('scrgbClr', 'srgbClr', 'hslClr', 'sysClr', 'schemeClr', 'prstClr')
def __init__(self,
scrgbClr=None,
srgbClr=None,
hslClr=None,
sysClr=None,
schemeClr=None,
prstClr=None,
):
self.scrgbClr = scrgbClr
self.srgbClr = srgbClr
self.hslClr = hslClr
self.sysClr = sysClr
self.schemeClr = schemeClr
self.prstClr = prstClr
_COLOR_SET = ('dk1', 'lt1', 'dk2', 'lt2', 'accent1', 'accent2', 'accent3',
'accent4', 'accent5', 'accent6', 'hlink', 'folHlink')
class ColorMapping(Serialisable):
tagname = "clrMapOvr"
bg1 = Set(values=_COLOR_SET)
tx1 = Set(values=_COLOR_SET)
bg2 = Set(values=_COLOR_SET)
tx2 = Set(values=_COLOR_SET)
accent1 = Set(values=_COLOR_SET)
accent2 = Set(values=_COLOR_SET)
accent3 = Set(values=_COLOR_SET)
accent4 = Set(values=_COLOR_SET)
accent5 = Set(values=_COLOR_SET)
accent6 = Set(values=_COLOR_SET)
hlink = Set(values=_COLOR_SET)
folHlink = Set(values=_COLOR_SET)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
def __init__(self,
bg1="lt1",
tx1="dk1",
bg2="lt2",
tx2="dk2",
accent1="accent1",
accent2="accent2",
accent3="accent3",
accent4="accent4",
accent5="accent5",
accent6="accent6",
hlink="hlink",
folHlink="folHlink",
extLst=None,
):
self.bg1 = bg1
self.tx1 = tx1
self.bg2 = bg2
self.tx2 = tx2
self.accent1 = accent1
self.accent2 = accent2
self.accent3 = accent3
self.accent4 = accent4
self.accent5 = accent5
self.accent6 = accent6
self.hlink = hlink
self.folHlink = folHlink
self.extLst = extLst
class ColorChoiceDescriptor(Typed):
"""
Objects can choose from 7 different kinds of color system.
Assume RGBHex if a string is passed in.
"""
expected_type = ColorChoice
allow_none = True
def __set__(self, instance, value):
if isinstance(value, str):
value = ColorChoice(srgbClr=value)
else:
if hasattr(self, "namespace") and value is not None:
value.namespace = self.namespace
super().__set__(instance, value)

View File

@ -0,0 +1,144 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Typed,
Bool,
Integer,
String,
Alias,
)
from openpyxl.descriptors.excel import ExtensionList as OfficeArtExtensionList
from openpyxl.chart.shapes import GraphicalProperties
from openpyxl.chart.text import RichText
from .properties import (
NonVisualDrawingProps,
NonVisualDrawingShapeProps,
)
from .geometry import ShapeStyle
class Connection(Serialisable):
id = Integer()
idx = Integer()
def __init__(self,
id=None,
idx=None,
):
self.id = id
self.idx = idx
class ConnectorLocking(Serialisable):
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
def __init__(self,
extLst=None,
):
self.extLst = extLst
class NonVisualConnectorProperties(Serialisable):
cxnSpLocks = Typed(expected_type=ConnectorLocking, allow_none=True)
stCxn = Typed(expected_type=Connection, allow_none=True)
endCxn = Typed(expected_type=Connection, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
def __init__(self,
cxnSpLocks=None,
stCxn=None,
endCxn=None,
extLst=None,
):
self.cxnSpLocks = cxnSpLocks
self.stCxn = stCxn
self.endCxn = endCxn
self.extLst = extLst
class ConnectorNonVisual(Serialisable):
cNvPr = Typed(expected_type=NonVisualDrawingProps, )
cNvCxnSpPr = Typed(expected_type=NonVisualConnectorProperties, )
__elements__ = ("cNvPr", "cNvCxnSpPr",)
def __init__(self,
cNvPr=None,
cNvCxnSpPr=None,
):
self.cNvPr = cNvPr
self.cNvCxnSpPr = cNvCxnSpPr
class ConnectorShape(Serialisable):
tagname = "cxnSp"
nvCxnSpPr = Typed(expected_type=ConnectorNonVisual)
spPr = Typed(expected_type=GraphicalProperties)
style = Typed(expected_type=ShapeStyle, allow_none=True)
macro = String(allow_none=True)
fPublished = Bool(allow_none=True)
def __init__(self,
nvCxnSpPr=None,
spPr=None,
style=None,
macro=None,
fPublished=None,
):
self.nvCxnSpPr = nvCxnSpPr
self.spPr = spPr
self.style = style
self.macro = macro
self.fPublished = fPublished
class ShapeMeta(Serialisable):
tagname = "nvSpPr"
cNvPr = Typed(expected_type=NonVisualDrawingProps)
cNvSpPr = Typed(expected_type=NonVisualDrawingShapeProps)
def __init__(self, cNvPr=None, cNvSpPr=None):
self.cNvPr = cNvPr
self.cNvSpPr = cNvSpPr
class Shape(Serialisable):
macro = String(allow_none=True)
textlink = String(allow_none=True)
fPublished = Bool(allow_none=True)
fLocksText = Bool(allow_none=True)
nvSpPr = Typed(expected_type=ShapeMeta, allow_none=True)
meta = Alias("nvSpPr")
spPr = Typed(expected_type=GraphicalProperties)
graphicalProperties = Alias("spPr")
style = Typed(expected_type=ShapeStyle, allow_none=True)
txBody = Typed(expected_type=RichText, allow_none=True)
def __init__(self,
macro=None,
textlink=None,
fPublished=None,
fLocksText=None,
nvSpPr=None,
spPr=None,
style=None,
txBody=None,
):
self.macro = macro
self.textlink = textlink
self.fPublished = fPublished
self.fLocksText = fLocksText
self.nvSpPr = nvSpPr
self.spPr = spPr
self.style = style
self.txBody = txBody

View File

@ -0,0 +1,92 @@
# Copyright (c) 2010-2024 openpyxl
import math
from openpyxl.utils.units import pixels_to_EMU
class Drawing:
""" a drawing object - eg container for shapes or charts
we assume user specifies dimensions in pixels; units are
converted to EMU in the drawing part
"""
count = 0
def __init__(self):
self.name = ''
self.description = ''
self.coordinates = ((1, 2), (16, 8))
self.left = 0
self.top = 0
self._width = 21 # default in px
self._height = 192 #default in px
self.resize_proportional = False
self.rotation = 0
self.anchortype = "absolute"
self.anchorcol = 0 # left cell
self.anchorrow = 0 # top row
@property
def width(self):
return self._width
@width.setter
def width(self, w):
if self.resize_proportional and w:
ratio = self._height / self._width
self._height = round(ratio * w)
self._width = w
@property
def height(self):
return self._height
@height.setter
def height(self, h):
if self.resize_proportional and h:
ratio = self._width / self._height
self._width = round(ratio * h)
self._height = h
def set_dimension(self, w=0, h=0):
xratio = w / self._width
yratio = h / self._height
if self.resize_proportional and w and h:
if (xratio * self._height) < h:
self._height = math.ceil(xratio * self._height)
self._width = w
else:
self._width = math.ceil(yratio * self._width)
self._height = h
@property
def anchor(self):
from .spreadsheet_drawing import (
OneCellAnchor,
TwoCellAnchor,
AbsoluteAnchor)
if self.anchortype == "absolute":
anchor = AbsoluteAnchor()
anchor.pos.x = pixels_to_EMU(self.left)
anchor.pos.y = pixels_to_EMU(self.top)
elif self.anchortype == "oneCell":
anchor = OneCellAnchor()
anchor._from.col = self.anchorcol
anchor._from.row = self.anchorrow
anchor.ext.width = pixels_to_EMU(self._width)
anchor.ext.height = pixels_to_EMU(self._height)
return anchor

View File

@ -0,0 +1,407 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Typed,
String,
Set,
Bool,
Integer,
Float,
)
from .colors import ColorChoice
class TintEffect(Serialisable):
tagname = "tint"
hue = Integer()
amt = Integer()
def __init__(self,
hue=0,
amt=0,
):
self.hue = hue
self.amt = amt
class LuminanceEffect(Serialisable):
tagname = "lum"
bright = Integer() #Pct ?
contrast = Integer() #Pct#
def __init__(self,
bright=0,
contrast=0,
):
self.bright = bright
self.contrast = contrast
class HSLEffect(Serialisable):
hue = Integer()
sat = Integer()
lum = Integer()
def __init__(self,
hue=None,
sat=None,
lum=None,
):
self.hue = hue
self.sat = sat
self.lum = lum
class GrayscaleEffect(Serialisable):
tagname = "grayscl"
class FillOverlayEffect(Serialisable):
blend = Set(values=(['over', 'mult', 'screen', 'darken', 'lighten']))
def __init__(self,
blend=None,
):
self.blend = blend
class DuotoneEffect(Serialisable):
pass
class ColorReplaceEffect(Serialisable):
pass
class Color(Serialisable):
pass
class ColorChangeEffect(Serialisable):
useA = Bool(allow_none=True)
clrFrom = Typed(expected_type=Color, )
clrTo = Typed(expected_type=Color, )
def __init__(self,
useA=None,
clrFrom=None,
clrTo=None,
):
self.useA = useA
self.clrFrom = clrFrom
self.clrTo = clrTo
class BlurEffect(Serialisable):
rad = Float()
grow = Bool(allow_none=True)
def __init__(self,
rad=None,
grow=None,
):
self.rad = rad
self.grow = grow
class BiLevelEffect(Serialisable):
thresh = Integer()
def __init__(self,
thresh=None,
):
self.thresh = thresh
class AlphaReplaceEffect(Serialisable):
a = Integer()
def __init__(self,
a=None,
):
self.a = a
class AlphaModulateFixedEffect(Serialisable):
amt = Integer()
def __init__(self,
amt=None,
):
self.amt = amt
class EffectContainer(Serialisable):
type = Set(values=(['sib', 'tree']))
name = String(allow_none=True)
def __init__(self,
type=None,
name=None,
):
self.type = type
self.name = name
class AlphaModulateEffect(Serialisable):
cont = Typed(expected_type=EffectContainer, )
def __init__(self,
cont=None,
):
self.cont = cont
class AlphaInverseEffect(Serialisable):
pass
class AlphaFloorEffect(Serialisable):
pass
class AlphaCeilingEffect(Serialisable):
pass
class AlphaBiLevelEffect(Serialisable):
thresh = Integer()
def __init__(self,
thresh=None,
):
self.thresh = thresh
class GlowEffect(ColorChoice):
rad = Float()
# uses element group EG_ColorChoice
scrgbClr = ColorChoice.scrgbClr
srgbClr = ColorChoice.srgbClr
hslClr = ColorChoice.hslClr
sysClr = ColorChoice.sysClr
schemeClr = ColorChoice.schemeClr
prstClr = ColorChoice.prstClr
__elements__ = ('scrgbClr', 'srgbClr', 'hslClr', 'sysClr', 'schemeClr', 'prstClr')
def __init__(self,
rad=None,
**kw
):
self.rad = rad
super().__init__(**kw)
class InnerShadowEffect(ColorChoice):
blurRad = Float()
dist = Float()
dir = Integer()
# uses element group EG_ColorChoice
scrgbClr = ColorChoice.scrgbClr
srgbClr = ColorChoice.srgbClr
hslClr = ColorChoice.hslClr
sysClr = ColorChoice.sysClr
schemeClr = ColorChoice.schemeClr
prstClr = ColorChoice.prstClr
__elements__ = ('scrgbClr', 'srgbClr', 'hslClr', 'sysClr', 'schemeClr', 'prstClr')
def __init__(self,
blurRad=None,
dist=None,
dir=None,
**kw
):
self.blurRad = blurRad
self.dist = dist
self.dir = dir
super().__init__(**kw)
class OuterShadow(ColorChoice):
tagname = "outerShdw"
blurRad = Float(allow_none=True)
dist = Float(allow_none=True)
dir = Integer(allow_none=True)
sx = Integer(allow_none=True)
sy = Integer(allow_none=True)
kx = Integer(allow_none=True)
ky = Integer(allow_none=True)
algn = Set(values=['tl', 't', 'tr', 'l', 'ctr', 'r', 'bl', 'b', 'br'])
rotWithShape = Bool(allow_none=True)
# uses element group EG_ColorChoice
scrgbClr = ColorChoice.scrgbClr
srgbClr = ColorChoice.srgbClr
hslClr = ColorChoice.hslClr
sysClr = ColorChoice.sysClr
schemeClr = ColorChoice.schemeClr
prstClr = ColorChoice.prstClr
__elements__ = ('scrgbClr', 'srgbClr', 'hslClr', 'sysClr', 'schemeClr', 'prstClr')
def __init__(self,
blurRad=None,
dist=None,
dir=None,
sx=None,
sy=None,
kx=None,
ky=None,
algn=None,
rotWithShape=None,
**kw
):
self.blurRad = blurRad
self.dist = dist
self.dir = dir
self.sx = sx
self.sy = sy
self.kx = kx
self.ky = ky
self.algn = algn
self.rotWithShape = rotWithShape
super().__init__(**kw)
class PresetShadowEffect(ColorChoice):
prst = Set(values=(['shdw1', 'shdw2', 'shdw3', 'shdw4', 'shdw5', 'shdw6',
'shdw7', 'shdw8', 'shdw9', 'shdw10', 'shdw11', 'shdw12', 'shdw13',
'shdw14', 'shdw15', 'shdw16', 'shdw17', 'shdw18', 'shdw19', 'shdw20']))
dist = Float()
dir = Integer()
# uses element group EG_ColorChoice
scrgbClr = ColorChoice.scrgbClr
srgbClr = ColorChoice.srgbClr
hslClr = ColorChoice.hslClr
sysClr = ColorChoice.sysClr
schemeClr = ColorChoice.schemeClr
prstClr = ColorChoice.prstClr
__elements__ = ('scrgbClr', 'srgbClr', 'hslClr', 'sysClr', 'schemeClr', 'prstClr')
def __init__(self,
prst=None,
dist=None,
dir=None,
**kw
):
self.prst = prst
self.dist = dist
self.dir = dir
super().__init__(**kw)
class ReflectionEffect(Serialisable):
blurRad = Float()
stA = Integer()
stPos = Integer()
endA = Integer()
endPos = Integer()
dist = Float()
dir = Integer()
fadeDir = Integer()
sx = Integer()
sy = Integer()
kx = Integer()
ky = Integer()
algn = Set(values=(['tl', 't', 'tr', 'l', 'ctr', 'r', 'bl', 'b', 'br']))
rotWithShape = Bool(allow_none=True)
def __init__(self,
blurRad=None,
stA=None,
stPos=None,
endA=None,
endPos=None,
dist=None,
dir=None,
fadeDir=None,
sx=None,
sy=None,
kx=None,
ky=None,
algn=None,
rotWithShape=None,
):
self.blurRad = blurRad
self.stA = stA
self.stPos = stPos
self.endA = endA
self.endPos = endPos
self.dist = dist
self.dir = dir
self.fadeDir = fadeDir
self.sx = sx
self.sy = sy
self.kx = kx
self.ky = ky
self.algn = algn
self.rotWithShape = rotWithShape
class SoftEdgesEffect(Serialisable):
rad = Float()
def __init__(self,
rad=None,
):
self.rad = rad
class EffectList(Serialisable):
blur = Typed(expected_type=BlurEffect, allow_none=True)
fillOverlay = Typed(expected_type=FillOverlayEffect, allow_none=True)
glow = Typed(expected_type=GlowEffect, allow_none=True)
innerShdw = Typed(expected_type=InnerShadowEffect, allow_none=True)
outerShdw = Typed(expected_type=OuterShadow, allow_none=True)
prstShdw = Typed(expected_type=PresetShadowEffect, allow_none=True)
reflection = Typed(expected_type=ReflectionEffect, allow_none=True)
softEdge = Typed(expected_type=SoftEdgesEffect, allow_none=True)
__elements__ = ('blur', 'fillOverlay', 'glow', 'innerShdw', 'outerShdw',
'prstShdw', 'reflection', 'softEdge')
def __init__(self,
blur=None,
fillOverlay=None,
glow=None,
innerShdw=None,
outerShdw=None,
prstShdw=None,
reflection=None,
softEdge=None,
):
self.blur = blur
self.fillOverlay = fillOverlay
self.glow = glow
self.innerShdw = innerShdw
self.outerShdw = outerShdw
self.prstShdw = prstShdw
self.reflection = reflection
self.softEdge = softEdge

View File

@ -0,0 +1,425 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Alias,
Bool,
Integer,
Set,
NoneSet,
Typed,
MinMax,
)
from openpyxl.descriptors.excel import (
Relation,
Percentage,
)
from openpyxl.descriptors.nested import NestedNoneSet, NestedValue
from openpyxl.descriptors.sequence import NestedSequence
from openpyxl.descriptors.excel import ExtensionList as OfficeArtExtensionList
from openpyxl.xml.constants import DRAWING_NS
from .colors import (
ColorChoice,
HSLColor,
SystemColor,
SchemeColor,
PRESET_COLORS,
RGBPercent,
)
from .effect import (
AlphaBiLevelEffect,
AlphaCeilingEffect,
AlphaFloorEffect,
AlphaInverseEffect,
AlphaModulateEffect,
AlphaModulateFixedEffect,
AlphaReplaceEffect,
BiLevelEffect,
BlurEffect,
ColorChangeEffect,
ColorReplaceEffect,
DuotoneEffect,
FillOverlayEffect,
GrayscaleEffect,
HSLEffect,
LuminanceEffect,
TintEffect,
)
"""
Fill elements from drawing main schema
"""
class PatternFillProperties(Serialisable):
tagname = "pattFill"
namespace = DRAWING_NS
prst = NoneSet(values=(['pct5', 'pct10', 'pct20', 'pct25', 'pct30',
'pct40', 'pct50', 'pct60', 'pct70', 'pct75', 'pct80', 'pct90', 'horz',
'vert', 'ltHorz', 'ltVert', 'dkHorz', 'dkVert', 'narHorz', 'narVert',
'dashHorz', 'dashVert', 'cross', 'dnDiag', 'upDiag', 'ltDnDiag',
'ltUpDiag', 'dkDnDiag', 'dkUpDiag', 'wdDnDiag', 'wdUpDiag', 'dashDnDiag',
'dashUpDiag', 'diagCross', 'smCheck', 'lgCheck', 'smGrid', 'lgGrid',
'dotGrid', 'smConfetti', 'lgConfetti', 'horzBrick', 'diagBrick',
'solidDmnd', 'openDmnd', 'dotDmnd', 'plaid', 'sphere', 'weave', 'divot',
'shingle', 'wave', 'trellis', 'zigZag']))
preset = Alias("prst")
fgClr = Typed(expected_type=ColorChoice, allow_none=True)
foreground = Alias("fgClr")
bgClr = Typed(expected_type=ColorChoice, allow_none=True)
background = Alias("bgClr")
__elements__ = ("fgClr", "bgClr")
def __init__(self,
prst=None,
fgClr=None,
bgClr=None,
):
self.prst = prst
self.fgClr = fgClr
self.bgClr = bgClr
class RelativeRect(Serialisable):
tagname = "rect"
namespace = DRAWING_NS
l = Percentage(allow_none=True)
left = Alias('l')
t = Percentage(allow_none=True)
top = Alias('t')
r = Percentage(allow_none=True)
right = Alias('r')
b = Percentage(allow_none=True)
bottom = Alias('b')
def __init__(self,
l=None,
t=None,
r=None,
b=None,
):
self.l = l
self.t = t
self.r = r
self.b = b
class StretchInfoProperties(Serialisable):
tagname = "stretch"
namespace = DRAWING_NS
fillRect = Typed(expected_type=RelativeRect, allow_none=True)
def __init__(self,
fillRect=RelativeRect(),
):
self.fillRect = fillRect
class GradientStop(Serialisable):
tagname = "gs"
namespace = DRAWING_NS
pos = MinMax(min=0, max=100000, allow_none=True)
# Color Choice Group
scrgbClr = Typed(expected_type=RGBPercent, allow_none=True)
RGBPercent = Alias('scrgbClr')
srgbClr = NestedValue(expected_type=str, allow_none=True) # needs pattern and can have transform
RGB = Alias('srgbClr')
hslClr = Typed(expected_type=HSLColor, allow_none=True)
sysClr = Typed(expected_type=SystemColor, allow_none=True)
schemeClr = Typed(expected_type=SchemeColor, allow_none=True)
prstClr = NestedNoneSet(values=PRESET_COLORS)
__elements__ = ('scrgbClr', 'srgbClr', 'hslClr', 'sysClr', 'schemeClr', 'prstClr')
def __init__(self,
pos=None,
scrgbClr=None,
srgbClr=None,
hslClr=None,
sysClr=None,
schemeClr=None,
prstClr=None,
):
if pos is None:
pos = 0
self.pos = pos
self.scrgbClr = scrgbClr
self.srgbClr = srgbClr
self.hslClr = hslClr
self.sysClr = sysClr
self.schemeClr = schemeClr
self.prstClr = prstClr
class LinearShadeProperties(Serialisable):
tagname = "lin"
namespace = DRAWING_NS
ang = Integer()
scaled = Bool(allow_none=True)
def __init__(self,
ang=None,
scaled=None,
):
self.ang = ang
self.scaled = scaled
class PathShadeProperties(Serialisable):
tagname = "path"
namespace = DRAWING_NS
path = Set(values=(['shape', 'circle', 'rect']))
fillToRect = Typed(expected_type=RelativeRect, allow_none=True)
def __init__(self,
path=None,
fillToRect=None,
):
self.path = path
self.fillToRect = fillToRect
class GradientFillProperties(Serialisable):
tagname = "gradFill"
namespace = DRAWING_NS
flip = NoneSet(values=(['x', 'y', 'xy']))
rotWithShape = Bool(allow_none=True)
gsLst = NestedSequence(expected_type=GradientStop, count=False)
stop_list = Alias("gsLst")
lin = Typed(expected_type=LinearShadeProperties, allow_none=True)
linear = Alias("lin")
path = Typed(expected_type=PathShadeProperties, allow_none=True)
tileRect = Typed(expected_type=RelativeRect, allow_none=True)
__elements__ = ('gsLst', 'lin', 'path', 'tileRect')
def __init__(self,
flip=None,
rotWithShape=None,
gsLst=(),
lin=None,
path=None,
tileRect=None,
):
self.flip = flip
self.rotWithShape = rotWithShape
self.gsLst = gsLst
self.lin = lin
self.path = path
self.tileRect = tileRect
class SolidColorFillProperties(Serialisable):
tagname = "solidFill"
# uses element group EG_ColorChoice
scrgbClr = Typed(expected_type=RGBPercent, allow_none=True)
RGBPercent = Alias('scrgbClr')
srgbClr = NestedValue(expected_type=str, allow_none=True) # needs pattern and can have transform
RGB = Alias('srgbClr')
hslClr = Typed(expected_type=HSLColor, allow_none=True)
sysClr = Typed(expected_type=SystemColor, allow_none=True)
schemeClr = Typed(expected_type=SchemeColor, allow_none=True)
prstClr = NestedNoneSet(values=PRESET_COLORS)
__elements__ = ('scrgbClr', 'srgbClr', 'hslClr', 'sysClr', 'schemeClr', 'prstClr')
def __init__(self,
scrgbClr=None,
srgbClr=None,
hslClr=None,
sysClr=None,
schemeClr=None,
prstClr=None,
):
self.scrgbClr = scrgbClr
self.srgbClr = srgbClr
self.hslClr = hslClr
self.sysClr = sysClr
self.schemeClr = schemeClr
self.prstClr = prstClr
class Blip(Serialisable):
tagname = "blip"
namespace = DRAWING_NS
# Using attribute groupAG_Blob
cstate = NoneSet(values=(['email', 'screen', 'print', 'hqprint']))
embed = Relation() # rId
link = Relation() # hyperlink
noGrp = Bool(allow_none=True)
noSelect = Bool(allow_none=True)
noRot = Bool(allow_none=True)
noChangeAspect = Bool(allow_none=True)
noMove = Bool(allow_none=True)
noResize = Bool(allow_none=True)
noEditPoints = Bool(allow_none=True)
noAdjustHandles = Bool(allow_none=True)
noChangeArrowheads = Bool(allow_none=True)
noChangeShapeType = Bool(allow_none=True)
# some elements are choice
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
alphaBiLevel = Typed(expected_type=AlphaBiLevelEffect, allow_none=True)
alphaCeiling = Typed(expected_type=AlphaCeilingEffect, allow_none=True)
alphaFloor = Typed(expected_type=AlphaFloorEffect, allow_none=True)
alphaInv = Typed(expected_type=AlphaInverseEffect, allow_none=True)
alphaMod = Typed(expected_type=AlphaModulateEffect, allow_none=True)
alphaModFix = Typed(expected_type=AlphaModulateFixedEffect, allow_none=True)
alphaRepl = Typed(expected_type=AlphaReplaceEffect, allow_none=True)
biLevel = Typed(expected_type=BiLevelEffect, allow_none=True)
blur = Typed(expected_type=BlurEffect, allow_none=True)
clrChange = Typed(expected_type=ColorChangeEffect, allow_none=True)
clrRepl = Typed(expected_type=ColorReplaceEffect, allow_none=True)
duotone = Typed(expected_type=DuotoneEffect, allow_none=True)
fillOverlay = Typed(expected_type=FillOverlayEffect, allow_none=True)
grayscl = Typed(expected_type=GrayscaleEffect, allow_none=True)
hsl = Typed(expected_type=HSLEffect, allow_none=True)
lum = Typed(expected_type=LuminanceEffect, allow_none=True)
tint = Typed(expected_type=TintEffect, allow_none=True)
__elements__ = ('alphaBiLevel', 'alphaCeiling', 'alphaFloor', 'alphaInv',
'alphaMod', 'alphaModFix', 'alphaRepl', 'biLevel', 'blur', 'clrChange',
'clrRepl', 'duotone', 'fillOverlay', 'grayscl', 'hsl', 'lum', 'tint')
def __init__(self,
cstate=None,
embed=None,
link=None,
noGrp=None,
noSelect=None,
noRot=None,
noChangeAspect=None,
noMove=None,
noResize=None,
noEditPoints=None,
noAdjustHandles=None,
noChangeArrowheads=None,
noChangeShapeType=None,
extLst=None,
alphaBiLevel=None,
alphaCeiling=None,
alphaFloor=None,
alphaInv=None,
alphaMod=None,
alphaModFix=None,
alphaRepl=None,
biLevel=None,
blur=None,
clrChange=None,
clrRepl=None,
duotone=None,
fillOverlay=None,
grayscl=None,
hsl=None,
lum=None,
tint=None,
):
self.cstate = cstate
self.embed = embed
self.link = link
self.noGrp = noGrp
self.noSelect = noSelect
self.noRot = noRot
self.noChangeAspect = noChangeAspect
self.noMove = noMove
self.noResize = noResize
self.noEditPoints = noEditPoints
self.noAdjustHandles = noAdjustHandles
self.noChangeArrowheads = noChangeArrowheads
self.noChangeShapeType = noChangeShapeType
self.extLst = extLst
self.alphaBiLevel = alphaBiLevel
self.alphaCeiling = alphaCeiling
self.alphaFloor = alphaFloor
self.alphaInv = alphaInv
self.alphaMod = alphaMod
self.alphaModFix = alphaModFix
self.alphaRepl = alphaRepl
self.biLevel = biLevel
self.blur = blur
self.clrChange = clrChange
self.clrRepl = clrRepl
self.duotone = duotone
self.fillOverlay = fillOverlay
self.grayscl = grayscl
self.hsl = hsl
self.lum = lum
self.tint = tint
class TileInfoProperties(Serialisable):
tx = Integer(allow_none=True)
ty = Integer(allow_none=True)
sx = Integer(allow_none=True)
sy = Integer(allow_none=True)
flip = NoneSet(values=(['x', 'y', 'xy']))
algn = Set(values=(['tl', 't', 'tr', 'l', 'ctr', 'r', 'bl', 'b', 'br']))
def __init__(self,
tx=None,
ty=None,
sx=None,
sy=None,
flip=None,
algn=None,
):
self.tx = tx
self.ty = ty
self.sx = sx
self.sy = sy
self.flip = flip
self.algn = algn
class BlipFillProperties(Serialisable):
tagname = "blipFill"
dpi = Integer(allow_none=True)
rotWithShape = Bool(allow_none=True)
blip = Typed(expected_type=Blip, allow_none=True)
srcRect = Typed(expected_type=RelativeRect, allow_none=True)
tile = Typed(expected_type=TileInfoProperties, allow_none=True)
stretch = Typed(expected_type=StretchInfoProperties, allow_none=True)
__elements__ = ("blip", "srcRect", "tile", "stretch")
def __init__(self,
dpi=None,
rotWithShape=None,
blip=None,
tile=None,
stretch=StretchInfoProperties(),
srcRect=None,
):
self.dpi = dpi
self.rotWithShape = rotWithShape
self.blip = blip
self.tile = tile
self.stretch = stretch
self.srcRect = srcRect

View File

@ -0,0 +1,584 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Typed,
Float,
Integer,
Bool,
MinMax,
Set,
NoneSet,
String,
Alias,
)
from openpyxl.descriptors.excel import Coordinate, Percentage
from openpyxl.descriptors.excel import ExtensionList as OfficeArtExtensionList
from .line import LineProperties
from openpyxl.styles.colors import Color
from openpyxl.xml.constants import DRAWING_NS
class Point2D(Serialisable):
tagname = "off"
namespace = DRAWING_NS
x = Coordinate()
y = Coordinate()
def __init__(self,
x=None,
y=None,
):
self.x = x
self.y = y
class PositiveSize2D(Serialisable):
tagname = "ext"
namespace = DRAWING_NS
"""
Dimensions in EMUs
"""
cx = Integer()
width = Alias('cx')
cy = Integer()
height = Alias('cy')
def __init__(self,
cx=None,
cy=None,
):
self.cx = cx
self.cy = cy
class Transform2D(Serialisable):
tagname = "xfrm"
namespace = DRAWING_NS
rot = Integer(allow_none=True)
flipH = Bool(allow_none=True)
flipV = Bool(allow_none=True)
off = Typed(expected_type=Point2D, allow_none=True)
ext = Typed(expected_type=PositiveSize2D, allow_none=True)
chOff = Typed(expected_type=Point2D, allow_none=True)
chExt = Typed(expected_type=PositiveSize2D, allow_none=True)
__elements__ = ('off', 'ext', 'chOff', 'chExt')
def __init__(self,
rot=None,
flipH=None,
flipV=None,
off=None,
ext=None,
chOff=None,
chExt=None,
):
self.rot = rot
self.flipH = flipH
self.flipV = flipV
self.off = off
self.ext = ext
self.chOff = chOff
self.chExt = chExt
class GroupTransform2D(Serialisable):
tagname = "xfrm"
namespace = DRAWING_NS
rot = Integer(allow_none=True)
flipH = Bool(allow_none=True)
flipV = Bool(allow_none=True)
off = Typed(expected_type=Point2D, allow_none=True)
ext = Typed(expected_type=PositiveSize2D, allow_none=True)
chOff = Typed(expected_type=Point2D, allow_none=True)
chExt = Typed(expected_type=PositiveSize2D, allow_none=True)
__elements__ = ("off", "ext", "chOff", "chExt")
def __init__(self,
rot=0,
flipH=None,
flipV=None,
off=None,
ext=None,
chOff=None,
chExt=None,
):
self.rot = rot
self.flipH = flipH
self.flipV = flipV
self.off = off
self.ext = ext
self.chOff = chOff
self.chExt = chExt
class SphereCoords(Serialisable):
tagname = "sphereCoords" # usually
lat = Integer()
lon = Integer()
rev = Integer()
def __init__(self,
lat=None,
lon=None,
rev=None,
):
self.lat = lat
self.lon = lon
self.rev = rev
class Camera(Serialisable):
tagname = "camera"
prst = Set(values=[
'legacyObliqueTopLeft', 'legacyObliqueTop', 'legacyObliqueTopRight', 'legacyObliqueLeft',
'legacyObliqueFront', 'legacyObliqueRight', 'legacyObliqueBottomLeft',
'legacyObliqueBottom', 'legacyObliqueBottomRight', 'legacyPerspectiveTopLeft',
'legacyPerspectiveTop', 'legacyPerspectiveTopRight', 'legacyPerspectiveLeft',
'legacyPerspectiveFront', 'legacyPerspectiveRight', 'legacyPerspectiveBottomLeft',
'legacyPerspectiveBottom', 'legacyPerspectiveBottomRight', 'orthographicFront',
'isometricTopUp', 'isometricTopDown', 'isometricBottomUp', 'isometricBottomDown',
'isometricLeftUp', 'isometricLeftDown', 'isometricRightUp', 'isometricRightDown',
'isometricOffAxis1Left', 'isometricOffAxis1Right', 'isometricOffAxis1Top',
'isometricOffAxis2Left', 'isometricOffAxis2Right', 'isometricOffAxis2Top',
'isometricOffAxis3Left', 'isometricOffAxis3Right', 'isometricOffAxis3Bottom',
'isometricOffAxis4Left', 'isometricOffAxis4Right', 'isometricOffAxis4Bottom',
'obliqueTopLeft', 'obliqueTop', 'obliqueTopRight', 'obliqueLeft', 'obliqueRight',
'obliqueBottomLeft', 'obliqueBottom', 'obliqueBottomRight', 'perspectiveFront',
'perspectiveLeft', 'perspectiveRight', 'perspectiveAbove', 'perspectiveBelow',
'perspectiveAboveLeftFacing', 'perspectiveAboveRightFacing',
'perspectiveContrastingLeftFacing', 'perspectiveContrastingRightFacing',
'perspectiveHeroicLeftFacing', 'perspectiveHeroicRightFacing',
'perspectiveHeroicExtremeLeftFacing', 'perspectiveHeroicExtremeRightFacing',
'perspectiveRelaxed', 'perspectiveRelaxedModerately'])
fov = Integer(allow_none=True)
zoom = Typed(expected_type=Percentage, allow_none=True)
rot = Typed(expected_type=SphereCoords, allow_none=True)
def __init__(self,
prst=None,
fov=None,
zoom=None,
rot=None,
):
self.prst = prst
self.fov = fov
self.zoom = zoom
self.rot = rot
class LightRig(Serialisable):
tagname = "lightRig"
rig = Set(values=['legacyFlat1', 'legacyFlat2', 'legacyFlat3', 'legacyFlat4', 'legacyNormal1',
'legacyNormal2', 'legacyNormal3', 'legacyNormal4', 'legacyHarsh1',
'legacyHarsh2', 'legacyHarsh3', 'legacyHarsh4', 'threePt', 'balanced',
'soft', 'harsh', 'flood', 'contrasting', 'morning', 'sunrise', 'sunset',
'chilly', 'freezing', 'flat', 'twoPt', 'glow', 'brightRoom']
)
dir = Set(values=(['tl', 't', 'tr', 'l', 'r', 'bl', 'b', 'br']))
rot = Typed(expected_type=SphereCoords, allow_none=True)
def __init__(self,
rig=None,
dir=None,
rot=None,
):
self.rig = rig
self.dir = dir
self.rot = rot
class Vector3D(Serialisable):
tagname = "vector"
dx = Integer() # can be in or universl measure :-/
dy = Integer()
dz = Integer()
def __init__(self,
dx=None,
dy=None,
dz=None,
):
self.dx = dx
self.dy = dy
self.dz = dz
class Point3D(Serialisable):
tagname = "anchor"
x = Integer()
y = Integer()
z = Integer()
def __init__(self,
x=None,
y=None,
z=None,
):
self.x = x
self.y = y
self.z = z
class Backdrop(Serialisable):
anchor = Typed(expected_type=Point3D, )
norm = Typed(expected_type=Vector3D, )
up = Typed(expected_type=Vector3D, )
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
def __init__(self,
anchor=None,
norm=None,
up=None,
extLst=None,
):
self.anchor = anchor
self.norm = norm
self.up = up
self.extLst = extLst
class Scene3D(Serialisable):
camera = Typed(expected_type=Camera, )
lightRig = Typed(expected_type=LightRig, )
backdrop = Typed(expected_type=Backdrop, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
def __init__(self,
camera=None,
lightRig=None,
backdrop=None,
extLst=None,
):
self.camera = camera
self.lightRig = lightRig
self.backdrop = backdrop
self.extLst = extLst
class Bevel(Serialisable):
tagname = "bevel"
w = Integer()
h = Integer()
prst = NoneSet(values=
['relaxedInset', 'circle', 'slope', 'cross', 'angle',
'softRound', 'convex', 'coolSlant', 'divot', 'riblet',
'hardEdge', 'artDeco']
)
def __init__(self,
w=None,
h=None,
prst=None,
):
self.w = w
self.h = h
self.prst = prst
class Shape3D(Serialisable):
namespace = DRAWING_NS
z = Typed(expected_type=Coordinate, allow_none=True)
extrusionH = Integer(allow_none=True)
contourW = Integer(allow_none=True)
prstMaterial = NoneSet(values=[
'legacyMatte','legacyPlastic', 'legacyMetal', 'legacyWireframe', 'matte', 'plastic',
'metal', 'warmMatte', 'translucentPowder', 'powder', 'dkEdge',
'softEdge', 'clear', 'flat', 'softmetal']
)
bevelT = Typed(expected_type=Bevel, allow_none=True)
bevelB = Typed(expected_type=Bevel, allow_none=True)
extrusionClr = Typed(expected_type=Color, allow_none=True)
contourClr = Typed(expected_type=Color, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
def __init__(self,
z=None,
extrusionH=None,
contourW=None,
prstMaterial=None,
bevelT=None,
bevelB=None,
extrusionClr=None,
contourClr=None,
extLst=None,
):
self.z = z
self.extrusionH = extrusionH
self.contourW = contourW
self.prstMaterial = prstMaterial
self.bevelT = bevelT
self.bevelB = bevelB
self.extrusionClr = extrusionClr
self.contourClr = contourClr
self.extLst = extLst
class Path2D(Serialisable):
w = Float()
h = Float()
fill = NoneSet(values=(['norm', 'lighten', 'lightenLess', 'darken', 'darkenLess']))
stroke = Bool(allow_none=True)
extrusionOk = Bool(allow_none=True)
def __init__(self,
w=None,
h=None,
fill=None,
stroke=None,
extrusionOk=None,
):
self.w = w
self.h = h
self.fill = fill
self.stroke = stroke
self.extrusionOk = extrusionOk
class Path2DList(Serialisable):
path = Typed(expected_type=Path2D, allow_none=True)
def __init__(self,
path=None,
):
self.path = path
class GeomRect(Serialisable):
l = Coordinate()
t = Coordinate()
r = Coordinate()
b = Coordinate()
def __init__(self,
l=None,
t=None,
r=None,
b=None,
):
self.l = l
self.t = t
self.r = r
self.b = b
class AdjPoint2D(Serialisable):
x = Coordinate()
y = Coordinate()
def __init__(self,
x=None,
y=None,
):
self.x = x
self.y = y
class ConnectionSite(Serialisable):
ang = MinMax(min=0, max=360) # guess work, can also be a name
pos = Typed(expected_type=AdjPoint2D, )
def __init__(self,
ang=None,
pos=None,
):
self.ang = ang
self.pos = pos
class ConnectionSiteList(Serialisable):
cxn = Typed(expected_type=ConnectionSite, allow_none=True)
def __init__(self,
cxn=None,
):
self.cxn = cxn
class AdjustHandleList(Serialisable):
pass
class GeomGuide(Serialisable):
name = String()
fmla = String()
def __init__(self,
name=None,
fmla=None,
):
self.name = name
self.fmla = fmla
class GeomGuideList(Serialisable):
gd = Typed(expected_type=GeomGuide, allow_none=True)
def __init__(self,
gd=None,
):
self.gd = gd
class CustomGeometry2D(Serialisable):
avLst = Typed(expected_type=GeomGuideList, allow_none=True)
gdLst = Typed(expected_type=GeomGuideList, allow_none=True)
ahLst = Typed(expected_type=AdjustHandleList, allow_none=True)
cxnLst = Typed(expected_type=ConnectionSiteList, allow_none=True)
#rect = Typed(expected_type=GeomRect, allow_none=True)
pathLst = Typed(expected_type=Path2DList, )
def __init__(self,
avLst=None,
gdLst=None,
ahLst=None,
cxnLst=None,
rect=None,
pathLst=None,
):
self.avLst = avLst
self.gdLst = gdLst
self.ahLst = ahLst
self.cxnLst = cxnLst
self.rect = None
self.pathLst = pathLst
class PresetGeometry2D(Serialisable):
namespace = DRAWING_NS
prst = Set(values=(
['line', 'lineInv', 'triangle', 'rtTriangle', 'rect',
'diamond', 'parallelogram', 'trapezoid', 'nonIsoscelesTrapezoid',
'pentagon', 'hexagon', 'heptagon', 'octagon', 'decagon', 'dodecagon',
'star4', 'star5', 'star6', 'star7', 'star8', 'star10', 'star12',
'star16', 'star24', 'star32', 'roundRect', 'round1Rect',
'round2SameRect', 'round2DiagRect', 'snipRoundRect', 'snip1Rect',
'snip2SameRect', 'snip2DiagRect', 'plaque', 'ellipse', 'teardrop',
'homePlate', 'chevron', 'pieWedge', 'pie', 'blockArc', 'donut',
'noSmoking', 'rightArrow', 'leftArrow', 'upArrow', 'downArrow',
'stripedRightArrow', 'notchedRightArrow', 'bentUpArrow',
'leftRightArrow', 'upDownArrow', 'leftUpArrow', 'leftRightUpArrow',
'quadArrow', 'leftArrowCallout', 'rightArrowCallout', 'upArrowCallout',
'downArrowCallout', 'leftRightArrowCallout', 'upDownArrowCallout',
'quadArrowCallout', 'bentArrow', 'uturnArrow', 'circularArrow',
'leftCircularArrow', 'leftRightCircularArrow', 'curvedRightArrow',
'curvedLeftArrow', 'curvedUpArrow', 'curvedDownArrow', 'swooshArrow',
'cube', 'can', 'lightningBolt', 'heart', 'sun', 'moon', 'smileyFace',
'irregularSeal1', 'irregularSeal2', 'foldedCorner', 'bevel', 'frame',
'halfFrame', 'corner', 'diagStripe', 'chord', 'arc', 'leftBracket',
'rightBracket', 'leftBrace', 'rightBrace', 'bracketPair', 'bracePair',
'straightConnector1', 'bentConnector2', 'bentConnector3',
'bentConnector4', 'bentConnector5', 'curvedConnector2',
'curvedConnector3', 'curvedConnector4', 'curvedConnector5', 'callout1',
'callout2', 'callout3', 'accentCallout1', 'accentCallout2',
'accentCallout3', 'borderCallout1', 'borderCallout2', 'borderCallout3',
'accentBorderCallout1', 'accentBorderCallout2', 'accentBorderCallout3',
'wedgeRectCallout', 'wedgeRoundRectCallout', 'wedgeEllipseCallout',
'cloudCallout', 'cloud', 'ribbon', 'ribbon2', 'ellipseRibbon',
'ellipseRibbon2', 'leftRightRibbon', 'verticalScroll',
'horizontalScroll', 'wave', 'doubleWave', 'plus', 'flowChartProcess',
'flowChartDecision', 'flowChartInputOutput',
'flowChartPredefinedProcess', 'flowChartInternalStorage',
'flowChartDocument', 'flowChartMultidocument', 'flowChartTerminator',
'flowChartPreparation', 'flowChartManualInput',
'flowChartManualOperation', 'flowChartConnector', 'flowChartPunchedCard',
'flowChartPunchedTape', 'flowChartSummingJunction', 'flowChartOr',
'flowChartCollate', 'flowChartSort', 'flowChartExtract',
'flowChartMerge', 'flowChartOfflineStorage', 'flowChartOnlineStorage',
'flowChartMagneticTape', 'flowChartMagneticDisk',
'flowChartMagneticDrum', 'flowChartDisplay', 'flowChartDelay',
'flowChartAlternateProcess', 'flowChartOffpageConnector',
'actionButtonBlank', 'actionButtonHome', 'actionButtonHelp',
'actionButtonInformation', 'actionButtonForwardNext',
'actionButtonBackPrevious', 'actionButtonEnd', 'actionButtonBeginning',
'actionButtonReturn', 'actionButtonDocument', 'actionButtonSound',
'actionButtonMovie', 'gear6', 'gear9', 'funnel', 'mathPlus', 'mathMinus',
'mathMultiply', 'mathDivide', 'mathEqual', 'mathNotEqual', 'cornerTabs',
'squareTabs', 'plaqueTabs', 'chartX', 'chartStar', 'chartPlus']))
avLst = Typed(expected_type=GeomGuideList, allow_none=True)
def __init__(self,
prst=None,
avLst=None,
):
self.prst = prst
self.avLst = avLst
class FontReference(Serialisable):
idx = NoneSet(values=(['major', 'minor']))
def __init__(self,
idx=None,
):
self.idx = idx
class StyleMatrixReference(Serialisable):
idx = Integer()
def __init__(self,
idx=None,
):
self.idx = idx
class ShapeStyle(Serialisable):
lnRef = Typed(expected_type=StyleMatrixReference, )
fillRef = Typed(expected_type=StyleMatrixReference, )
effectRef = Typed(expected_type=StyleMatrixReference, )
fontRef = Typed(expected_type=FontReference, )
def __init__(self,
lnRef=None,
fillRef=None,
effectRef=None,
fontRef=None,
):
self.lnRef = lnRef
self.fillRef = fillRef
self.effectRef = effectRef
self.fontRef = fontRef

View File

@ -0,0 +1,177 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.xml.constants import CHART_NS, DRAWING_NS
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Typed,
Bool,
String,
Alias,
)
from openpyxl.descriptors.excel import ExtensionList as OfficeArtExtensionList
from .effect import (
EffectList,
EffectContainer,
)
from .fill import (
Blip,
GradientFillProperties,
BlipFillProperties,
)
from .picture import PictureFrame
from .properties import (
NonVisualDrawingProps,
NonVisualGroupShape,
GroupShapeProperties,
)
from .relation import ChartRelation
from .xdr import XDRTransform2D
class GraphicFrameLocking(Serialisable):
noGrp = Bool(allow_none=True)
noDrilldown = Bool(allow_none=True)
noSelect = Bool(allow_none=True)
noChangeAspect = Bool(allow_none=True)
noMove = Bool(allow_none=True)
noResize = Bool(allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
def __init__(self,
noGrp=None,
noDrilldown=None,
noSelect=None,
noChangeAspect=None,
noMove=None,
noResize=None,
extLst=None,
):
self.noGrp = noGrp
self.noDrilldown = noDrilldown
self.noSelect = noSelect
self.noChangeAspect = noChangeAspect
self.noMove = noMove
self.noResize = noResize
self.extLst = extLst
class NonVisualGraphicFrameProperties(Serialisable):
tagname = "cNvGraphicFramePr"
graphicFrameLocks = Typed(expected_type=GraphicFrameLocking, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
def __init__(self,
graphicFrameLocks=None,
extLst=None,
):
self.graphicFrameLocks = graphicFrameLocks
self.extLst = extLst
class NonVisualGraphicFrame(Serialisable):
tagname = "nvGraphicFramePr"
cNvPr = Typed(expected_type=NonVisualDrawingProps)
cNvGraphicFramePr = Typed(expected_type=NonVisualGraphicFrameProperties)
__elements__ = ('cNvPr', 'cNvGraphicFramePr')
def __init__(self,
cNvPr=None,
cNvGraphicFramePr=None,
):
if cNvPr is None:
cNvPr = NonVisualDrawingProps(id=0, name="Chart 0")
self.cNvPr = cNvPr
if cNvGraphicFramePr is None:
cNvGraphicFramePr = NonVisualGraphicFrameProperties()
self.cNvGraphicFramePr = cNvGraphicFramePr
class GraphicData(Serialisable):
tagname = "graphicData"
namespace = DRAWING_NS
uri = String()
chart = Typed(expected_type=ChartRelation, allow_none=True)
def __init__(self,
uri=CHART_NS,
chart=None,
):
self.uri = uri
self.chart = chart
class GraphicObject(Serialisable):
tagname = "graphic"
namespace = DRAWING_NS
graphicData = Typed(expected_type=GraphicData)
def __init__(self,
graphicData=None,
):
if graphicData is None:
graphicData = GraphicData()
self.graphicData = graphicData
class GraphicFrame(Serialisable):
tagname = "graphicFrame"
nvGraphicFramePr = Typed(expected_type=NonVisualGraphicFrame)
xfrm = Typed(expected_type=XDRTransform2D)
graphic = Typed(expected_type=GraphicObject)
macro = String(allow_none=True)
fPublished = Bool(allow_none=True)
__elements__ = ('nvGraphicFramePr', 'xfrm', 'graphic', 'macro', 'fPublished')
def __init__(self,
nvGraphicFramePr=None,
xfrm=None,
graphic=None,
macro=None,
fPublished=None,
):
if nvGraphicFramePr is None:
nvGraphicFramePr = NonVisualGraphicFrame()
self.nvGraphicFramePr = nvGraphicFramePr
if xfrm is None:
xfrm = XDRTransform2D()
self.xfrm = xfrm
if graphic is None:
graphic = GraphicObject()
self.graphic = graphic
self.macro = macro
self.fPublished = fPublished
class GroupShape(Serialisable):
nvGrpSpPr = Typed(expected_type=NonVisualGroupShape)
nonVisualProperties = Alias("nvGrpSpPr")
grpSpPr = Typed(expected_type=GroupShapeProperties)
visualProperties = Alias("grpSpPr")
pic = Typed(expected_type=PictureFrame, allow_none=True)
__elements__ = ["nvGrpSpPr", "grpSpPr", "pic"]
def __init__(self,
nvGrpSpPr=None,
grpSpPr=None,
pic=None,
):
self.nvGrpSpPr = nvGrpSpPr
self.grpSpPr = grpSpPr
self.pic = pic

View File

@ -0,0 +1,65 @@
# Copyright (c) 2010-2024 openpyxl
from io import BytesIO
try:
from PIL import Image as PILImage
except ImportError:
PILImage = False
def _import_image(img):
if not PILImage:
raise ImportError('You must install Pillow to fetch image objects')
if not isinstance(img, PILImage.Image):
img = PILImage.open(img)
return img
class Image:
"""Image in a spreadsheet"""
_id = 1
_path = "/xl/media/image{0}.{1}"
anchor = "A1"
def __init__(self, img):
self.ref = img
mark_to_close = isinstance(img, str)
image = _import_image(img)
self.width, self.height = image.size
try:
self.format = image.format.lower()
except AttributeError:
self.format = "png"
if mark_to_close:
# PIL instances created for metadata should be closed.
image.close()
def _data(self):
"""
Return image data, convert to supported types if necessary
"""
img = _import_image(self.ref)
# don't convert these file formats
if self.format in ['gif', 'jpeg', 'png']:
img.fp.seek(0)
fp = img.fp
else:
fp = BytesIO()
img.save(fp, format="png")
fp.seek(0)
data = fp.read()
fp.close()
return data
@property
def path(self):
return self._path.format(self._id, self.format)

View File

@ -0,0 +1,144 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Typed,
Integer,
MinMax,
NoneSet,
Alias,
Sequence
)
from openpyxl.descriptors.nested import (
NestedInteger,
NestedNoneSet,
EmptyTag,
)
from openpyxl.xml.constants import DRAWING_NS
from .colors import ColorChoiceDescriptor
from .fill import GradientFillProperties, PatternFillProperties
from openpyxl.descriptors.excel import ExtensionList as OfficeArtExtensionList
"""
Line elements from drawing main schema
"""
class LineEndProperties(Serialisable):
tagname = "end"
namespace = DRAWING_NS
type = NoneSet(values=(['none', 'triangle', 'stealth', 'diamond', 'oval', 'arrow']))
w = NoneSet(values=(['sm', 'med', 'lg']))
len = NoneSet(values=(['sm', 'med', 'lg']))
def __init__(self,
type=None,
w=None,
len=None,
):
self.type = type
self.w = w
self.len = len
class DashStop(Serialisable):
tagname = "ds"
namespace = DRAWING_NS
d = Integer()
length = Alias('d')
sp = Integer()
space = Alias('sp')
def __init__(self,
d=0,
sp=0,
):
self.d = d
self.sp = sp
class DashStopList(Serialisable):
ds = Sequence(expected_type=DashStop, allow_none=True)
def __init__(self,
ds=None,
):
self.ds = ds
class LineProperties(Serialisable):
tagname = "ln"
namespace = DRAWING_NS
w = MinMax(min=0, max=20116800, allow_none=True) # EMU
width = Alias('w')
cap = NoneSet(values=(['rnd', 'sq', 'flat']))
cmpd = NoneSet(values=(['sng', 'dbl', 'thickThin', 'thinThick', 'tri']))
algn = NoneSet(values=(['ctr', 'in']))
noFill = EmptyTag()
solidFill = ColorChoiceDescriptor()
gradFill = Typed(expected_type=GradientFillProperties, allow_none=True)
pattFill = Typed(expected_type=PatternFillProperties, allow_none=True)
prstDash = NestedNoneSet(values=(['solid', 'dot', 'dash', 'lgDash', 'dashDot',
'lgDashDot', 'lgDashDotDot', 'sysDash', 'sysDot', 'sysDashDot',
'sysDashDotDot']), namespace=namespace)
dashStyle = Alias('prstDash')
custDash = Typed(expected_type=DashStop, allow_none=True)
round = EmptyTag()
bevel = EmptyTag()
miter = NestedInteger(allow_none=True, attribute="lim")
headEnd = Typed(expected_type=LineEndProperties, allow_none=True)
tailEnd = Typed(expected_type=LineEndProperties, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
__elements__ = ('noFill', 'solidFill', 'gradFill', 'pattFill',
'prstDash', 'custDash', 'round', 'bevel', 'miter', 'headEnd', 'tailEnd')
def __init__(self,
w=None,
cap=None,
cmpd=None,
algn=None,
noFill=None,
solidFill=None,
gradFill=None,
pattFill=None,
prstDash=None,
custDash=None,
round=None,
bevel=None,
miter=None,
headEnd=None,
tailEnd=None,
extLst=None,
):
self.w = w
self.cap = cap
self.cmpd = cmpd
self.algn = algn
self.noFill = noFill
self.solidFill = solidFill
self.gradFill = gradFill
self.pattFill = pattFill
if prstDash is None:
prstDash = "solid"
self.prstDash = prstDash
self.custDash = custDash
self.round = round
self.bevel = bevel
self.miter = miter
self.headEnd = headEnd
self.tailEnd = tailEnd

View File

@ -0,0 +1,144 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.xml.constants import DRAWING_NS
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Typed,
Bool,
String,
Alias,
)
from openpyxl.descriptors.excel import ExtensionList as OfficeArtExtensionList
from openpyxl.chart.shapes import GraphicalProperties
from .fill import BlipFillProperties
from .properties import NonVisualDrawingProps
from .geometry import ShapeStyle
class PictureLocking(Serialisable):
tagname = "picLocks"
namespace = DRAWING_NS
# Using attribute group AG_Locking
noCrop = Bool(allow_none=True)
noGrp = Bool(allow_none=True)
noSelect = Bool(allow_none=True)
noRot = Bool(allow_none=True)
noChangeAspect = Bool(allow_none=True)
noMove = Bool(allow_none=True)
noResize = Bool(allow_none=True)
noEditPoints = Bool(allow_none=True)
noAdjustHandles = Bool(allow_none=True)
noChangeArrowheads = Bool(allow_none=True)
noChangeShapeType = Bool(allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
__elements__ = ()
def __init__(self,
noCrop=None,
noGrp=None,
noSelect=None,
noRot=None,
noChangeAspect=None,
noMove=None,
noResize=None,
noEditPoints=None,
noAdjustHandles=None,
noChangeArrowheads=None,
noChangeShapeType=None,
extLst=None,
):
self.noCrop = noCrop
self.noGrp = noGrp
self.noSelect = noSelect
self.noRot = noRot
self.noChangeAspect = noChangeAspect
self.noMove = noMove
self.noResize = noResize
self.noEditPoints = noEditPoints
self.noAdjustHandles = noAdjustHandles
self.noChangeArrowheads = noChangeArrowheads
self.noChangeShapeType = noChangeShapeType
class NonVisualPictureProperties(Serialisable):
tagname = "cNvPicPr"
preferRelativeResize = Bool(allow_none=True)
picLocks = Typed(expected_type=PictureLocking, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
__elements__ = ("picLocks",)
def __init__(self,
preferRelativeResize=None,
picLocks=None,
extLst=None,
):
self.preferRelativeResize = preferRelativeResize
self.picLocks = picLocks
class PictureNonVisual(Serialisable):
tagname = "nvPicPr"
cNvPr = Typed(expected_type=NonVisualDrawingProps, )
cNvPicPr = Typed(expected_type=NonVisualPictureProperties, )
__elements__ = ("cNvPr", "cNvPicPr")
def __init__(self,
cNvPr=None,
cNvPicPr=None,
):
if cNvPr is None:
cNvPr = NonVisualDrawingProps(id=0, name="Image 1", descr="Name of file")
self.cNvPr = cNvPr
if cNvPicPr is None:
cNvPicPr = NonVisualPictureProperties()
self.cNvPicPr = cNvPicPr
class PictureFrame(Serialisable):
tagname = "pic"
macro = String(allow_none=True)
fPublished = Bool(allow_none=True)
nvPicPr = Typed(expected_type=PictureNonVisual, )
blipFill = Typed(expected_type=BlipFillProperties, )
spPr = Typed(expected_type=GraphicalProperties, )
graphicalProperties = Alias('spPr')
style = Typed(expected_type=ShapeStyle, allow_none=True)
__elements__ = ("nvPicPr", "blipFill", "spPr", "style")
def __init__(self,
macro=None,
fPublished=None,
nvPicPr=None,
blipFill=None,
spPr=None,
style=None,
):
self.macro = macro
self.fPublished = fPublished
if nvPicPr is None:
nvPicPr = PictureNonVisual()
self.nvPicPr = nvPicPr
if blipFill is None:
blipFill = BlipFillProperties()
self.blipFill = blipFill
if spPr is None:
spPr = GraphicalProperties()
self.spPr = spPr
self.style = style

View File

@ -0,0 +1,174 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.xml.constants import DRAWING_NS
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Typed,
Bool,
Integer,
Set,
String,
Alias,
NoneSet,
)
from openpyxl.descriptors.excel import ExtensionList as OfficeArtExtensionList
from .geometry import GroupTransform2D, Scene3D
from .text import Hyperlink
class GroupShapeProperties(Serialisable):
tagname = "grpSpPr"
bwMode = NoneSet(values=(['clr', 'auto', 'gray', 'ltGray', 'invGray',
'grayWhite', 'blackGray', 'blackWhite', 'black', 'white', 'hidden']))
xfrm = Typed(expected_type=GroupTransform2D, allow_none=True)
scene3d = Typed(expected_type=Scene3D, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
def __init__(self,
bwMode=None,
xfrm=None,
scene3d=None,
extLst=None,
):
self.bwMode = bwMode
self.xfrm = xfrm
self.scene3d = scene3d
self.extLst = extLst
class GroupLocking(Serialisable):
tagname = "grpSpLocks"
namespace = DRAWING_NS
noGrp = Bool(allow_none=True)
noUngrp = Bool(allow_none=True)
noSelect = Bool(allow_none=True)
noRot = Bool(allow_none=True)
noChangeAspect = Bool(allow_none=True)
noMove = Bool(allow_none=True)
noResize = Bool(allow_none=True)
noChangeArrowheads = Bool(allow_none=True)
noEditPoints = Bool(allow_none=True)
noAdjustHandles = Bool(allow_none=True)
noChangeArrowheads = Bool(allow_none=True)
noChangeShapeType = Bool(allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
__elements__ = ()
def __init__(self,
noGrp=None,
noUngrp=None,
noSelect=None,
noRot=None,
noChangeAspect=None,
noChangeArrowheads=None,
noMove=None,
noResize=None,
noEditPoints=None,
noAdjustHandles=None,
noChangeShapeType=None,
extLst=None,
):
self.noGrp = noGrp
self.noUngrp = noUngrp
self.noSelect = noSelect
self.noRot = noRot
self.noChangeAspect = noChangeAspect
self.noChangeArrowheads = noChangeArrowheads
self.noMove = noMove
self.noResize = noResize
self.noEditPoints = noEditPoints
self.noAdjustHandles = noAdjustHandles
self.noChangeShapeType = noChangeShapeType
class NonVisualGroupDrawingShapeProps(Serialisable):
tagname = "cNvGrpSpPr"
grpSpLocks = Typed(expected_type=GroupLocking, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
__elements__ = ("grpSpLocks",)
def __init__(self,
grpSpLocks=None,
extLst=None,
):
self.grpSpLocks = grpSpLocks
class NonVisualDrawingShapeProps(Serialisable):
tagname = "cNvSpPr"
spLocks = Typed(expected_type=GroupLocking, allow_none=True)
txBax = Bool(allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
__elements__ = ("spLocks", "txBax")
def __init__(self,
spLocks=None,
txBox=None,
extLst=None,
):
self.spLocks = spLocks
self.txBox = txBox
class NonVisualDrawingProps(Serialisable):
tagname = "cNvPr"
id = Integer()
name = String()
descr = String(allow_none=True)
hidden = Bool(allow_none=True)
title = String(allow_none=True)
hlinkClick = Typed(expected_type=Hyperlink, allow_none=True)
hlinkHover = Typed(expected_type=Hyperlink, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
__elements__ = ["hlinkClick", "hlinkHover"]
def __init__(self,
id=None,
name=None,
descr=None,
hidden=None,
title=None,
hlinkClick=None,
hlinkHover=None,
extLst=None,
):
self.id = id
self.name = name
self.descr = descr
self.hidden = hidden
self.title = title
self.hlinkClick = hlinkClick
self.hlinkHover = hlinkHover
self.extLst = extLst
class NonVisualGroupShape(Serialisable):
tagname = "nvGrpSpPr"
cNvPr = Typed(expected_type=NonVisualDrawingProps)
cNvGrpSpPr = Typed(expected_type=NonVisualGroupDrawingShapeProps)
__elements__ = ("cNvPr", "cNvGrpSpPr")
def __init__(self,
cNvPr=None,
cNvGrpSpPr=None,
):
self.cNvPr = cNvPr
self.cNvGrpSpPr = cNvGrpSpPr

View File

@ -0,0 +1,17 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.xml.constants import CHART_NS
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors.excel import Relation
class ChartRelation(Serialisable):
tagname = "chart"
namespace = CHART_NS
id = Relation()
def __init__(self, id):
self.id = id

View File

@ -0,0 +1,382 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Typed,
Bool,
NoneSet,
Integer,
Sequence,
Alias,
)
from openpyxl.descriptors.nested import (
NestedText,
NestedNoneSet,
)
from openpyxl.descriptors.excel import Relation
from openpyxl.packaging.relationship import (
Relationship,
RelationshipList,
)
from openpyxl.utils import coordinate_to_tuple
from openpyxl.utils.units import (
cm_to_EMU,
pixels_to_EMU,
)
from openpyxl.drawing.image import Image
from openpyxl.xml.constants import SHEET_DRAWING_NS
from openpyxl.chart._chart import ChartBase
from .xdr import (
XDRPoint2D,
XDRPositiveSize2D,
)
from .fill import Blip
from .connector import Shape
from .graphic import (
GroupShape,
GraphicFrame,
)
from .geometry import PresetGeometry2D
from .picture import PictureFrame
from .relation import ChartRelation
class AnchorClientData(Serialisable):
fLocksWithSheet = Bool(allow_none=True)
fPrintsWithSheet = Bool(allow_none=True)
def __init__(self,
fLocksWithSheet=None,
fPrintsWithSheet=None,
):
self.fLocksWithSheet = fLocksWithSheet
self.fPrintsWithSheet = fPrintsWithSheet
class AnchorMarker(Serialisable):
tagname = "marker"
col = NestedText(expected_type=int)
colOff = NestedText(expected_type=int)
row = NestedText(expected_type=int)
rowOff = NestedText(expected_type=int)
def __init__(self,
col=0,
colOff=0,
row=0,
rowOff=0,
):
self.col = col
self.colOff = colOff
self.row = row
self.rowOff = rowOff
class _AnchorBase(Serialisable):
#one of
sp = Typed(expected_type=Shape, allow_none=True)
shape = Alias("sp")
grpSp = Typed(expected_type=GroupShape, allow_none=True)
groupShape = Alias("grpSp")
graphicFrame = Typed(expected_type=GraphicFrame, allow_none=True)
cxnSp = Typed(expected_type=Shape, allow_none=True)
connectionShape = Alias("cxnSp")
pic = Typed(expected_type=PictureFrame, allow_none=True)
contentPart = Relation()
clientData = Typed(expected_type=AnchorClientData)
__elements__ = ('sp', 'grpSp', 'graphicFrame',
'cxnSp', 'pic', 'contentPart', 'clientData')
def __init__(self,
clientData=None,
sp=None,
grpSp=None,
graphicFrame=None,
cxnSp=None,
pic=None,
contentPart=None
):
if clientData is None:
clientData = AnchorClientData()
self.clientData = clientData
self.sp = sp
self.grpSp = grpSp
self.graphicFrame = graphicFrame
self.cxnSp = cxnSp
self.pic = pic
self.contentPart = contentPart
class AbsoluteAnchor(_AnchorBase):
tagname = "absoluteAnchor"
pos = Typed(expected_type=XDRPoint2D)
ext = Typed(expected_type=XDRPositiveSize2D)
sp = _AnchorBase.sp
grpSp = _AnchorBase.grpSp
graphicFrame = _AnchorBase.graphicFrame
cxnSp = _AnchorBase.cxnSp
pic = _AnchorBase.pic
contentPart = _AnchorBase.contentPart
clientData = _AnchorBase.clientData
__elements__ = ('pos', 'ext') + _AnchorBase.__elements__
def __init__(self,
pos=None,
ext=None,
**kw
):
if pos is None:
pos = XDRPoint2D(0, 0)
self.pos = pos
if ext is None:
ext = XDRPositiveSize2D(0, 0)
self.ext = ext
super().__init__(**kw)
class OneCellAnchor(_AnchorBase):
tagname = "oneCellAnchor"
_from = Typed(expected_type=AnchorMarker)
ext = Typed(expected_type=XDRPositiveSize2D)
sp = _AnchorBase.sp
grpSp = _AnchorBase.grpSp
graphicFrame = _AnchorBase.graphicFrame
cxnSp = _AnchorBase.cxnSp
pic = _AnchorBase.pic
contentPart = _AnchorBase.contentPart
clientData = _AnchorBase.clientData
__elements__ = ('_from', 'ext') + _AnchorBase.__elements__
def __init__(self,
_from=None,
ext=None,
**kw
):
if _from is None:
_from = AnchorMarker()
self._from = _from
if ext is None:
ext = XDRPositiveSize2D(0, 0)
self.ext = ext
super().__init__(**kw)
class TwoCellAnchor(_AnchorBase):
tagname = "twoCellAnchor"
editAs = NoneSet(values=(['twoCell', 'oneCell', 'absolute']))
_from = Typed(expected_type=AnchorMarker)
to = Typed(expected_type=AnchorMarker)
sp = _AnchorBase.sp
grpSp = _AnchorBase.grpSp
graphicFrame = _AnchorBase.graphicFrame
cxnSp = _AnchorBase.cxnSp
pic = _AnchorBase.pic
contentPart = _AnchorBase.contentPart
clientData = _AnchorBase.clientData
__elements__ = ('_from', 'to') + _AnchorBase.__elements__
def __init__(self,
editAs=None,
_from=None,
to=None,
**kw
):
self.editAs = editAs
if _from is None:
_from = AnchorMarker()
self._from = _from
if to is None:
to = AnchorMarker()
self.to = to
super().__init__(**kw)
def _check_anchor(obj):
"""
Check whether an object has an existing Anchor object
If not create a OneCellAnchor using the provided coordinate
"""
anchor = obj.anchor
if not isinstance(anchor, _AnchorBase):
row, col = coordinate_to_tuple(anchor.upper())
anchor = OneCellAnchor()
anchor._from.row = row -1
anchor._from.col = col -1
if isinstance(obj, ChartBase):
anchor.ext.width = cm_to_EMU(obj.width)
anchor.ext.height = cm_to_EMU(obj.height)
elif isinstance(obj, Image):
anchor.ext.width = pixels_to_EMU(obj.width)
anchor.ext.height = pixels_to_EMU(obj.height)
return anchor
class SpreadsheetDrawing(Serialisable):
tagname = "wsDr"
mime_type = "application/vnd.openxmlformats-officedocument.drawing+xml"
_rel_type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
_path = PartName="/xl/drawings/drawing{0}.xml"
_id = None
twoCellAnchor = Sequence(expected_type=TwoCellAnchor, allow_none=True)
oneCellAnchor = Sequence(expected_type=OneCellAnchor, allow_none=True)
absoluteAnchor = Sequence(expected_type=AbsoluteAnchor, allow_none=True)
__elements__ = ("twoCellAnchor", "oneCellAnchor", "absoluteAnchor")
def __init__(self,
twoCellAnchor=(),
oneCellAnchor=(),
absoluteAnchor=(),
):
self.twoCellAnchor = twoCellAnchor
self.oneCellAnchor = oneCellAnchor
self.absoluteAnchor = absoluteAnchor
self.charts = []
self.images = []
self._rels = []
def __hash__(self):
"""
Just need to check for identity
"""
return id(self)
def __bool__(self):
return bool(self.charts) or bool(self.images)
def _write(self):
"""
create required structure and the serialise
"""
anchors = []
for idx, obj in enumerate(self.charts + self.images, 1):
anchor = _check_anchor(obj)
if isinstance(obj, ChartBase):
rel = Relationship(type="chart", Target=obj.path)
anchor.graphicFrame = self._chart_frame(idx)
elif isinstance(obj, Image):
rel = Relationship(type="image", Target=obj.path)
child = anchor.pic or anchor.groupShape and anchor.groupShape.pic
if not child:
anchor.pic = self._picture_frame(idx)
else:
child.blipFill.blip.embed = "rId{0}".format(idx)
anchors.append(anchor)
self._rels.append(rel)
for a in anchors:
if isinstance(a, OneCellAnchor):
self.oneCellAnchor.append(a)
elif isinstance(a, TwoCellAnchor):
self.twoCellAnchor.append(a)
else:
self.absoluteAnchor.append(a)
tree = self.to_tree()
tree.set('xmlns', SHEET_DRAWING_NS)
return tree
def _chart_frame(self, idx):
chart_rel = ChartRelation(f"rId{idx}")
frame = GraphicFrame()
nv = frame.nvGraphicFramePr.cNvPr
nv.id = idx
nv.name = "Chart {0}".format(idx)
frame.graphic.graphicData.chart = chart_rel
return frame
def _picture_frame(self, idx):
pic = PictureFrame()
pic.nvPicPr.cNvPr.descr = "Picture"
pic.nvPicPr.cNvPr.id = idx
pic.nvPicPr.cNvPr.name = "Image {0}".format(idx)
pic.blipFill.blip = Blip()
pic.blipFill.blip.embed = "rId{0}".format(idx)
pic.blipFill.blip.cstate = "print"
pic.spPr.prstGeom = PresetGeometry2D(prst="rect")
pic.spPr.ln = None
return pic
def _write_rels(self):
rels = RelationshipList()
for r in self._rels:
rels.append(r)
return rels.to_tree()
@property
def path(self):
return self._path.format(self._id)
@property
def _chart_rels(self):
"""
Get relationship information for each chart and bind anchor to it
"""
rels = []
anchors = self.absoluteAnchor + self.oneCellAnchor + self.twoCellAnchor
for anchor in anchors:
if anchor.graphicFrame is not None:
graphic = anchor.graphicFrame.graphic
rel = graphic.graphicData.chart
if rel is not None:
rel.anchor = anchor
rel.anchor.graphicFrame = None
rels.append(rel)
return rels
@property
def _blip_rels(self):
"""
Get relationship information for each blip and bind anchor to it
Images that are not part of the XLSX package will be ignored.
"""
rels = []
anchors = self.absoluteAnchor + self.oneCellAnchor + self.twoCellAnchor
for anchor in anchors:
child = anchor.pic or anchor.groupShape and anchor.groupShape.pic
if child and child.blipFill:
rel = child.blipFill.blip
if rel is not None and rel.embed:
rel.anchor = anchor
rels.append(rel)
return rels

View File

@ -0,0 +1,717 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Alias,
Typed,
Set,
NoneSet,
Sequence,
String,
Bool,
MinMax,
Integer
)
from openpyxl.descriptors.excel import (
HexBinary,
Coordinate,
Relation,
)
from openpyxl.descriptors.nested import (
NestedInteger,
NestedText,
NestedValue,
EmptyTag
)
from openpyxl.xml.constants import DRAWING_NS
from .colors import ColorChoiceDescriptor
from .effect import (
EffectList,
EffectContainer,
)
from .fill import(
GradientFillProperties,
BlipFillProperties,
PatternFillProperties,
Blip
)
from .geometry import (
LineProperties,
Color,
Scene3D
)
from openpyxl.descriptors.excel import ExtensionList as OfficeArtExtensionList
from openpyxl.descriptors.nested import NestedBool
class EmbeddedWAVAudioFile(Serialisable):
name = String(allow_none=True)
def __init__(self,
name=None,
):
self.name = name
class Hyperlink(Serialisable):
tagname = "hlinkClick"
namespace = DRAWING_NS
invalidUrl = String(allow_none=True)
action = String(allow_none=True)
tgtFrame = String(allow_none=True)
tooltip = String(allow_none=True)
history = Bool(allow_none=True)
highlightClick = Bool(allow_none=True)
endSnd = Bool(allow_none=True)
snd = Typed(expected_type=EmbeddedWAVAudioFile, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
id = Relation(allow_none=True)
__elements__ = ('snd',)
def __init__(self,
invalidUrl=None,
action=None,
tgtFrame=None,
tooltip=None,
history=None,
highlightClick=None,
endSnd=None,
snd=None,
extLst=None,
id=None,
):
self.invalidUrl = invalidUrl
self.action = action
self.tgtFrame = tgtFrame
self.tooltip = tooltip
self.history = history
self.highlightClick = highlightClick
self.endSnd = endSnd
self.snd = snd
self.id = id
class Font(Serialisable):
tagname = "latin"
namespace = DRAWING_NS
typeface = String()
panose = HexBinary(allow_none=True)
pitchFamily = MinMax(min=0, max=52, allow_none=True)
charset = Integer(allow_none=True)
def __init__(self,
typeface=None,
panose=None,
pitchFamily=None,
charset=None,
):
self.typeface = typeface
self.panose = panose
self.pitchFamily = pitchFamily
self.charset = charset
class CharacterProperties(Serialisable):
tagname = "defRPr"
namespace = DRAWING_NS
kumimoji = Bool(allow_none=True)
lang = String(allow_none=True)
altLang = String(allow_none=True)
sz = MinMax(allow_none=True, min=100, max=400000) # 100ths of a point
b = Bool(allow_none=True)
i = Bool(allow_none=True)
u = NoneSet(values=(['words', 'sng', 'dbl', 'heavy', 'dotted',
'dottedHeavy', 'dash', 'dashHeavy', 'dashLong', 'dashLongHeavy',
'dotDash', 'dotDashHeavy', 'dotDotDash', 'dotDotDashHeavy', 'wavy',
'wavyHeavy', 'wavyDbl']))
strike = NoneSet(values=(['noStrike', 'sngStrike', 'dblStrike']))
kern = Integer(allow_none=True)
cap = NoneSet(values=(['small', 'all']))
spc = Integer(allow_none=True)
normalizeH = Bool(allow_none=True)
baseline = Integer(allow_none=True)
noProof = Bool(allow_none=True)
dirty = Bool(allow_none=True)
err = Bool(allow_none=True)
smtClean = Bool(allow_none=True)
smtId = Integer(allow_none=True)
bmk = String(allow_none=True)
ln = Typed(expected_type=LineProperties, allow_none=True)
highlight = Typed(expected_type=Color, allow_none=True)
latin = Typed(expected_type=Font, allow_none=True)
ea = Typed(expected_type=Font, allow_none=True)
cs = Typed(expected_type=Font, allow_none=True)
sym = Typed(expected_type=Font, allow_none=True)
hlinkClick = Typed(expected_type=Hyperlink, allow_none=True)
hlinkMouseOver = Typed(expected_type=Hyperlink, allow_none=True)
rtl = NestedBool(allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
# uses element group EG_FillProperties
noFill = EmptyTag(namespace=DRAWING_NS)
solidFill = ColorChoiceDescriptor()
gradFill = Typed(expected_type=GradientFillProperties, allow_none=True)
blipFill = Typed(expected_type=BlipFillProperties, allow_none=True)
pattFill = Typed(expected_type=PatternFillProperties, allow_none=True)
grpFill = EmptyTag(namespace=DRAWING_NS)
# uses element group EG_EffectProperties
effectLst = Typed(expected_type=EffectList, allow_none=True)
effectDag = Typed(expected_type=EffectContainer, allow_none=True)
# uses element group EG_TextUnderlineLine
uLnTx = EmptyTag()
uLn = Typed(expected_type=LineProperties, allow_none=True)
# uses element group EG_TextUnderlineFill
uFillTx = EmptyTag()
uFill = EmptyTag()
__elements__ = ('ln', 'noFill', 'solidFill', 'gradFill', 'blipFill',
'pattFill', 'grpFill', 'effectLst', 'effectDag', 'highlight','uLnTx',
'uLn', 'uFillTx', 'uFill', 'latin', 'ea', 'cs', 'sym', 'hlinkClick',
'hlinkMouseOver', 'rtl', )
def __init__(self,
kumimoji=None,
lang=None,
altLang=None,
sz=None,
b=None,
i=None,
u=None,
strike=None,
kern=None,
cap=None,
spc=None,
normalizeH=None,
baseline=None,
noProof=None,
dirty=None,
err=None,
smtClean=None,
smtId=None,
bmk=None,
ln=None,
highlight=None,
latin=None,
ea=None,
cs=None,
sym=None,
hlinkClick=None,
hlinkMouseOver=None,
rtl=None,
extLst=None,
noFill=None,
solidFill=None,
gradFill=None,
blipFill=None,
pattFill=None,
grpFill=None,
effectLst=None,
effectDag=None,
uLnTx=None,
uLn=None,
uFillTx=None,
uFill=None,
):
self.kumimoji = kumimoji
self.lang = lang
self.altLang = altLang
self.sz = sz
self.b = b
self.i = i
self.u = u
self.strike = strike
self.kern = kern
self.cap = cap
self.spc = spc
self.normalizeH = normalizeH
self.baseline = baseline
self.noProof = noProof
self.dirty = dirty
self.err = err
self.smtClean = smtClean
self.smtId = smtId
self.bmk = bmk
self.ln = ln
self.highlight = highlight
self.latin = latin
self.ea = ea
self.cs = cs
self.sym = sym
self.hlinkClick = hlinkClick
self.hlinkMouseOver = hlinkMouseOver
self.rtl = rtl
self.noFill = noFill
self.solidFill = solidFill
self.gradFill = gradFill
self.blipFill = blipFill
self.pattFill = pattFill
self.grpFill = grpFill
self.effectLst = effectLst
self.effectDag = effectDag
self.uLnTx = uLnTx
self.uLn = uLn
self.uFillTx = uFillTx
self.uFill = uFill
class TabStop(Serialisable):
pos = Typed(expected_type=Coordinate, allow_none=True)
algn = Typed(expected_type=Set(values=(['l', 'ctr', 'r', 'dec'])))
def __init__(self,
pos=None,
algn=None,
):
self.pos = pos
self.algn = algn
class TabStopList(Serialisable):
tab = Typed(expected_type=TabStop, allow_none=True)
def __init__(self,
tab=None,
):
self.tab = tab
class Spacing(Serialisable):
spcPct = NestedInteger(allow_none=True)
spcPts = NestedInteger(allow_none=True)
__elements__ = ('spcPct', 'spcPts')
def __init__(self,
spcPct=None,
spcPts=None,
):
self.spcPct = spcPct
self.spcPts = spcPts
class AutonumberBullet(Serialisable):
type = Set(values=(['alphaLcParenBoth', 'alphaUcParenBoth',
'alphaLcParenR', 'alphaUcParenR', 'alphaLcPeriod', 'alphaUcPeriod',
'arabicParenBoth', 'arabicParenR', 'arabicPeriod', 'arabicPlain',
'romanLcParenBoth', 'romanUcParenBoth', 'romanLcParenR', 'romanUcParenR',
'romanLcPeriod', 'romanUcPeriod', 'circleNumDbPlain',
'circleNumWdBlackPlain', 'circleNumWdWhitePlain', 'arabicDbPeriod',
'arabicDbPlain', 'ea1ChsPeriod', 'ea1ChsPlain', 'ea1ChtPeriod',
'ea1ChtPlain', 'ea1JpnChsDbPeriod', 'ea1JpnKorPlain', 'ea1JpnKorPeriod',
'arabic1Minus', 'arabic2Minus', 'hebrew2Minus', 'thaiAlphaPeriod',
'thaiAlphaParenR', 'thaiAlphaParenBoth', 'thaiNumPeriod',
'thaiNumParenR', 'thaiNumParenBoth', 'hindiAlphaPeriod',
'hindiNumPeriod', 'hindiNumParenR', 'hindiAlpha1Period']))
startAt = Integer()
def __init__(self,
type=None,
startAt=None,
):
self.type = type
self.startAt = startAt
class ParagraphProperties(Serialisable):
tagname = "pPr"
namespace = DRAWING_NS
marL = Integer(allow_none=True)
marR = Integer(allow_none=True)
lvl = Integer(allow_none=True)
indent = Integer(allow_none=True)
algn = NoneSet(values=(['l', 'ctr', 'r', 'just', 'justLow', 'dist', 'thaiDist']))
defTabSz = Integer(allow_none=True)
rtl = Bool(allow_none=True)
eaLnBrk = Bool(allow_none=True)
fontAlgn = NoneSet(values=(['auto', 't', 'ctr', 'base', 'b']))
latinLnBrk = Bool(allow_none=True)
hangingPunct = Bool(allow_none=True)
# uses element group EG_TextBulletColor
# uses element group EG_TextBulletSize
# uses element group EG_TextBulletTypeface
# uses element group EG_TextBullet
lnSpc = Typed(expected_type=Spacing, allow_none=True)
spcBef = Typed(expected_type=Spacing, allow_none=True)
spcAft = Typed(expected_type=Spacing, allow_none=True)
tabLst = Typed(expected_type=TabStopList, allow_none=True)
defRPr = Typed(expected_type=CharacterProperties, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
buClrTx = EmptyTag()
buClr = Typed(expected_type=Color, allow_none=True)
buSzTx = EmptyTag()
buSzPct = NestedInteger(allow_none=True)
buSzPts = NestedInteger(allow_none=True)
buFontTx = EmptyTag()
buFont = Typed(expected_type=Font, allow_none=True)
buNone = EmptyTag()
buAutoNum = EmptyTag()
buChar = NestedValue(expected_type=str, attribute="char", allow_none=True)
buBlip = NestedValue(expected_type=Blip, attribute="blip", allow_none=True)
__elements__ = ('lnSpc', 'spcBef', 'spcAft', 'tabLst', 'defRPr',
'buClrTx', 'buClr', 'buSzTx', 'buSzPct', 'buSzPts', 'buFontTx', 'buFont',
'buNone', 'buAutoNum', 'buChar', 'buBlip')
def __init__(self,
marL=None,
marR=None,
lvl=None,
indent=None,
algn=None,
defTabSz=None,
rtl=None,
eaLnBrk=None,
fontAlgn=None,
latinLnBrk=None,
hangingPunct=None,
lnSpc=None,
spcBef=None,
spcAft=None,
tabLst=None,
defRPr=None,
extLst=None,
buClrTx=None,
buClr=None,
buSzTx=None,
buSzPct=None,
buSzPts=None,
buFontTx=None,
buFont=None,
buNone=None,
buAutoNum=None,
buChar=None,
buBlip=None,
):
self.marL = marL
self.marR = marR
self.lvl = lvl
self.indent = indent
self.algn = algn
self.defTabSz = defTabSz
self.rtl = rtl
self.eaLnBrk = eaLnBrk
self.fontAlgn = fontAlgn
self.latinLnBrk = latinLnBrk
self.hangingPunct = hangingPunct
self.lnSpc = lnSpc
self.spcBef = spcBef
self.spcAft = spcAft
self.tabLst = tabLst
self.defRPr = defRPr
self.buClrTx = buClrTx
self.buClr = buClr
self.buSzTx = buSzTx
self.buSzPct = buSzPct
self.buSzPts = buSzPts
self.buFontTx = buFontTx
self.buFont = buFont
self.buNone = buNone
self.buAutoNum = buAutoNum
self.buChar = buChar
self.buBlip = buBlip
self.defRPr = defRPr
class ListStyle(Serialisable):
tagname = "lstStyle"
namespace = DRAWING_NS
defPPr = Typed(expected_type=ParagraphProperties, allow_none=True)
lvl1pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
lvl2pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
lvl3pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
lvl4pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
lvl5pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
lvl6pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
lvl7pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
lvl8pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
lvl9pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
__elements__ = ("defPPr", "lvl1pPr", "lvl2pPr", "lvl3pPr", "lvl4pPr",
"lvl5pPr", "lvl6pPr", "lvl7pPr", "lvl8pPr", "lvl9pPr")
def __init__(self,
defPPr=None,
lvl1pPr=None,
lvl2pPr=None,
lvl3pPr=None,
lvl4pPr=None,
lvl5pPr=None,
lvl6pPr=None,
lvl7pPr=None,
lvl8pPr=None,
lvl9pPr=None,
extLst=None,
):
self.defPPr = defPPr
self.lvl1pPr = lvl1pPr
self.lvl2pPr = lvl2pPr
self.lvl3pPr = lvl3pPr
self.lvl4pPr = lvl4pPr
self.lvl5pPr = lvl5pPr
self.lvl6pPr = lvl6pPr
self.lvl7pPr = lvl7pPr
self.lvl8pPr = lvl8pPr
self.lvl9pPr = lvl9pPr
class RegularTextRun(Serialisable):
tagname = "r"
namespace = DRAWING_NS
rPr = Typed(expected_type=CharacterProperties, allow_none=True)
properties = Alias("rPr")
t = NestedText(expected_type=str)
value = Alias("t")
__elements__ = ('rPr', 't')
def __init__(self,
rPr=None,
t="",
):
self.rPr = rPr
self.t = t
class LineBreak(Serialisable):
tagname = "br"
namespace = DRAWING_NS
rPr = Typed(expected_type=CharacterProperties, allow_none=True)
__elements__ = ('rPr',)
def __init__(self,
rPr=None,
):
self.rPr = rPr
class TextField(Serialisable):
id = String()
type = String(allow_none=True)
rPr = Typed(expected_type=CharacterProperties, allow_none=True)
pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
t = String(allow_none=True)
__elements__ = ('rPr', 'pPr')
def __init__(self,
id=None,
type=None,
rPr=None,
pPr=None,
t=None,
):
self.id = id
self.type = type
self.rPr = rPr
self.pPr = pPr
self.t = t
class Paragraph(Serialisable):
tagname = "p"
namespace = DRAWING_NS
# uses element group EG_TextRun
pPr = Typed(expected_type=ParagraphProperties, allow_none=True)
properties = Alias("pPr")
endParaRPr = Typed(expected_type=CharacterProperties, allow_none=True)
r = Sequence(expected_type=RegularTextRun)
text = Alias('r')
br = Typed(expected_type=LineBreak, allow_none=True)
fld = Typed(expected_type=TextField, allow_none=True)
__elements__ = ('pPr', 'r', 'br', 'fld', 'endParaRPr')
def __init__(self,
pPr=None,
endParaRPr=None,
r=None,
br=None,
fld=None,
):
self.pPr = pPr
self.endParaRPr = endParaRPr
if r is None:
r = [RegularTextRun()]
self.r = r
self.br = br
self.fld = fld
class GeomGuide(Serialisable):
name = String(())
fmla = String(())
def __init__(self,
name=None,
fmla=None,
):
self.name = name
self.fmla = fmla
class GeomGuideList(Serialisable):
gd = Sequence(expected_type=GeomGuide, allow_none=True)
def __init__(self,
gd=None,
):
self.gd = gd
class PresetTextShape(Serialisable):
prst = Typed(expected_type=Set(values=(
['textNoShape', 'textPlain','textStop', 'textTriangle', 'textTriangleInverted', 'textChevron',
'textChevronInverted', 'textRingInside', 'textRingOutside', 'textArchUp',
'textArchDown', 'textCircle', 'textButton', 'textArchUpPour',
'textArchDownPour', 'textCirclePour', 'textButtonPour', 'textCurveUp',
'textCurveDown', 'textCanUp', 'textCanDown', 'textWave1', 'textWave2',
'textDoubleWave1', 'textWave4', 'textInflate', 'textDeflate',
'textInflateBottom', 'textDeflateBottom', 'textInflateTop',
'textDeflateTop', 'textDeflateInflate', 'textDeflateInflateDeflate',
'textFadeRight', 'textFadeLeft', 'textFadeUp', 'textFadeDown',
'textSlantUp', 'textSlantDown', 'textCascadeUp', 'textCascadeDown'
]
)))
avLst = Typed(expected_type=GeomGuideList, allow_none=True)
def __init__(self,
prst=None,
avLst=None,
):
self.prst = prst
self.avLst = avLst
class TextNormalAutofit(Serialisable):
fontScale = Integer()
lnSpcReduction = Integer()
def __init__(self,
fontScale=None,
lnSpcReduction=None,
):
self.fontScale = fontScale
self.lnSpcReduction = lnSpcReduction
class RichTextProperties(Serialisable):
tagname = "bodyPr"
namespace = DRAWING_NS
rot = Integer(allow_none=True)
spcFirstLastPara = Bool(allow_none=True)
vertOverflow = NoneSet(values=(['overflow', 'ellipsis', 'clip']))
horzOverflow = NoneSet(values=(['overflow', 'clip']))
vert = NoneSet(values=(['horz', 'vert', 'vert270', 'wordArtVert',
'eaVert', 'mongolianVert', 'wordArtVertRtl']))
wrap = NoneSet(values=(['none', 'square']))
lIns = Integer(allow_none=True)
tIns = Integer(allow_none=True)
rIns = Integer(allow_none=True)
bIns = Integer(allow_none=True)
numCol = Integer(allow_none=True)
spcCol = Integer(allow_none=True)
rtlCol = Bool(allow_none=True)
fromWordArt = Bool(allow_none=True)
anchor = NoneSet(values=(['t', 'ctr', 'b', 'just', 'dist']))
anchorCtr = Bool(allow_none=True)
forceAA = Bool(allow_none=True)
upright = Bool(allow_none=True)
compatLnSpc = Bool(allow_none=True)
prstTxWarp = Typed(expected_type=PresetTextShape, allow_none=True)
scene3d = Typed(expected_type=Scene3D, allow_none=True)
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
noAutofit = EmptyTag()
normAutofit = EmptyTag()
spAutoFit = EmptyTag()
flatTx = NestedInteger(attribute="z", allow_none=True)
__elements__ = ('prstTxWarp', 'scene3d', 'noAutofit', 'normAutofit', 'spAutoFit')
def __init__(self,
rot=None,
spcFirstLastPara=None,
vertOverflow=None,
horzOverflow=None,
vert=None,
wrap=None,
lIns=None,
tIns=None,
rIns=None,
bIns=None,
numCol=None,
spcCol=None,
rtlCol=None,
fromWordArt=None,
anchor=None,
anchorCtr=None,
forceAA=None,
upright=None,
compatLnSpc=None,
prstTxWarp=None,
scene3d=None,
extLst=None,
noAutofit=None,
normAutofit=None,
spAutoFit=None,
flatTx=None,
):
self.rot = rot
self.spcFirstLastPara = spcFirstLastPara
self.vertOverflow = vertOverflow
self.horzOverflow = horzOverflow
self.vert = vert
self.wrap = wrap
self.lIns = lIns
self.tIns = tIns
self.rIns = rIns
self.bIns = bIns
self.numCol = numCol
self.spcCol = spcCol
self.rtlCol = rtlCol
self.fromWordArt = fromWordArt
self.anchor = anchor
self.anchorCtr = anchorCtr
self.forceAA = forceAA
self.upright = upright
self.compatLnSpc = compatLnSpc
self.prstTxWarp = prstTxWarp
self.scene3d = scene3d
self.noAutofit = noAutofit
self.normAutofit = normAutofit
self.spAutoFit = spAutoFit
self.flatTx = flatTx

View File

@ -0,0 +1,33 @@
# Copyright (c) 2010-2024 openpyxl
"""
Spreadsheet Drawing has some copies of Drawing ML elements
"""
from .geometry import Point2D, PositiveSize2D, Transform2D
class XDRPoint2D(Point2D):
namespace = None
x = Point2D.x
y = Point2D.y
class XDRPositiveSize2D(PositiveSize2D):
namespace = None
cx = PositiveSize2D.cx
cy = PositiveSize2D.cy
class XDRTransform2D(Transform2D):
namespace = None
rot = Transform2D.rot
flipH = Transform2D.flipH
flipV = Transform2D.flipV
off = Transform2D.off
ext = Transform2D.ext
chOff = Transform2D.chOff
chExt = Transform2D.chExt