/usr/lib/python2.7/dist-packages/openpyxl/styles/named_styles.py is in python-openpyxl 2.4.9-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | from __future__ import absolute_import
# Copyright (c) 2010-2017 openpyxl
from openpyxl.compat import safe_string
from openpyxl.compat import OrderedDict
from openpyxl.descriptors import (
Typed,
Integer,
Bool,
String,
Sequence,
)
from openpyxl.descriptors.excel import ExtensionList
from openpyxl.descriptors.serialisable import Serialisable
from .fills import PatternFill, Fill
from .fonts import Font
from .borders import Border
from .alignment import Alignment
from .protection import Protection
from .numbers import (
NumberFormatDescriptor,
BUILTIN_FORMATS,
BUILTIN_FORMATS_REVERSE,
)
from .cell_style import (
StyleArray,
CellStyle,
)
class NamedStyle(Serialisable):
"""
Named and editable styles
"""
font = Typed(expected_type=Font)
fill = Typed(expected_type=Fill)
border = Typed(expected_type=Border)
alignment = Typed(expected_type=Alignment)
number_format = NumberFormatDescriptor()
protection = Typed(expected_type=Protection)
builtinId = Integer(allow_none=True)
hidden = Bool(allow_none=True)
xfId = Integer(allow_none=True)
name = String()
def __init__(self,
name="Normal",
font=Font(),
fill=PatternFill(),
border=Border(),
alignment=Alignment(),
number_format=None,
protection=Protection(),
builtinId=None,
hidden=False,
xfId=None,
):
self.name = name
self.font = font
self.fill = fill
self.border = border
self.alignment = alignment
self.number_format = number_format
self.protection = protection
self.builtinId = builtinId
self.hidden = hidden
self._wb = None
self._style = StyleArray()
def __setattr__(self, attr, value):
super(NamedStyle, self).__setattr__(attr, value)
if getattr(self, '_wb', None) and attr in (
'font', 'fill', 'border', 'alignment', 'number_format', 'protection',
):
self._recalculate()
def __iter__(self):
for key in ('name', 'builtinId', 'hidden', 'xfId'):
value = getattr(self, key, None)
if value is not None:
yield key, safe_string(value)
@property
def xfId(self):
"""
Index of the style in the list of named styles
"""
return self._style.xfId
def _set_index(self, idx):
"""
Allow the containing list to set the index
"""
self._style.xfId = idx
def bind(self, wb):
"""
Bind a named style to a workbook
"""
self._wb = wb
self._recalculate()
def _recalculate(self):
self._style.fontId = self._wb._fonts.add(self.font)
self._style.borderId = self._wb._borders.add(self.border)
self._style.fillId = self._wb._fills.add(self.fill)
self._style.protectionId = self._wb._protections.add(self.protection)
self._style.alignmentId = self._wb._alignments.add(self.alignment)
fmt = self.number_format
if fmt in BUILTIN_FORMATS_REVERSE:
fmt = BUILTIN_FORMATS_REVERSE[fmt]
else:
fmt = self._wb._number_formats.add(self.number_format) + 164
self._style.numFmtId = fmt
def as_tuple(self):
"""Return a style array representing the current style"""
return self._style
def as_xf(self):
"""
Return equivalent XfStyle
"""
xf = CellStyle.from_array(self._style)
xf.xfId = None
xf.pivotButton = None
xf.quotePrefix = None
return xf
def as_name(self):
"""
Return relevant named style
"""
named = _NamedCellStyle(
name=self.name,
builtinId=self.builtinId,
hidden=self.hidden,
xfId=self.xfId
)
return named
class NamedStyleList(list):
"""
Named styles are editable and can be applied to multiple objects
As only the index is stored in referencing objects the order mus
be preserved.
"""
@property
def names(self):
return [s.name for s in self]
def __getitem__(self, key):
if isinstance(key, int):
return super(NamedStyleList, self).__getitem__(key)
names = self.names
if key not in names:
raise KeyError("No named style with the name{0} exists".format(key))
for idx, name in enumerate(names):
if name == key:
return self[idx]
def append(self, style):
if not isinstance(style, NamedStyle):
raise TypeError("""Only NamedStyle instances can be added""")
elif style.name in self.names:
raise ValueError("""Style {0} exists already""".format(style.name))
style._set_index(len(self))
super(NamedStyleList, self).append(style)
class _NamedCellStyle(Serialisable):
"""
Pointer-based representation of named styles in XML
xfId refers to the corresponding CellStyleXfs
Not used in client code.
"""
tagname = "cellStyle"
name = String()
xfId = Integer()
builtinId = Integer(allow_none=True)
iLevel = Integer(allow_none=True)
hidden = Bool(allow_none=True)
customBuiltin = Bool(allow_none=True)
extLst = Typed(expected_type=ExtensionList, allow_none=True)
__elements__ = ()
def __init__(self,
name=None,
xfId=None,
builtinId=None,
iLevel=None,
hidden=None,
customBuiltin=None,
extLst=None,
):
self.name = name
self.xfId = xfId
self.builtinId = builtinId
self.iLevel = iLevel
self.hidden = hidden
self.customBuiltin = customBuiltin
class _NamedCellStyleList(Serialisable):
"""
Container for named cell style objects
Not used in client code
"""
tagname = "cellStyles"
count = Integer(allow_none=True)
cellStyle = Sequence(expected_type=_NamedCellStyle)
__attrs__ = ("count",)
def __init__(self,
count=None,
cellStyle=(),
):
self.cellStyle = cellStyle
@property
def count(self):
return len(self.cellStyle)
@property
def names(self):
"""
Convert to NamedStyle objects and remove duplicates.
In theory the highest xfId wins but in practice they are duplicates
so it doesn't matter.
"""
def sort_fn(v):
return v.xfId
styles = []
names = set()
for ns in sorted(self.cellStyle, key=sort_fn):
if ns.name in names:
continue
style = NamedStyle(
name=ns.name,
hidden=ns.hidden,
builtinId = ns.builtinId
)
names.add(ns.name)
style._set_index(len(styles)) # assign xfId
styles.append(style)
return NamedStyleList(styles)
|