Updated script that can be controled by Nodejs web app
This commit is contained in:
19
lib/python3.13/site-packages/openpyxl/__init__.py
Normal file
19
lib/python3.13/site-packages/openpyxl/__init__.py
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
DEBUG = False
|
||||
|
||||
from openpyxl.compat.numbers import NUMPY
|
||||
from openpyxl.xml import DEFUSEDXML, LXML
|
||||
from openpyxl.workbook import Workbook
|
||||
from openpyxl.reader.excel import load_workbook as open
|
||||
from openpyxl.reader.excel import load_workbook
|
||||
import openpyxl._constants as constants
|
||||
|
||||
# Expose constants especially the version number
|
||||
|
||||
__author__ = constants.__author__
|
||||
__author_email__ = constants.__author_email__
|
||||
__license__ = constants.__license__
|
||||
__maintainer_email__ = constants.__maintainer_email__
|
||||
__url__ = constants.__url__
|
||||
__version__ = constants.__version__
|
Binary file not shown.
Binary file not shown.
13
lib/python3.13/site-packages/openpyxl/_constants.py
Normal file
13
lib/python3.13/site-packages/openpyxl/_constants.py
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
"""
|
||||
Package metadata
|
||||
"""
|
||||
|
||||
__author__ = "See AUTHORS"
|
||||
__author_email__ = "charlie.clark@clark-consulting.eu"
|
||||
__license__ = "MIT"
|
||||
__maintainer_email__ = "openpyxl-users@googlegroups.com"
|
||||
__url__ = "https://openpyxl.readthedocs.io"
|
||||
__version__ = "3.1.5"
|
||||
__python__ = "3.8"
|
4
lib/python3.13/site-packages/openpyxl/cell/__init__.py
Normal file
4
lib/python3.13/site-packages/openpyxl/cell/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from .cell import Cell, WriteOnlyCell, MergedCell
|
||||
from .read_only import ReadOnlyCell
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
136
lib/python3.13/site-packages/openpyxl/cell/_writer.py
Normal file
136
lib/python3.13/site-packages/openpyxl/cell/_writer.py
Normal file
@ -0,0 +1,136 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.compat import safe_string
|
||||
from openpyxl.xml.functions import Element, SubElement, whitespace, XML_NS
|
||||
from openpyxl import LXML
|
||||
from openpyxl.utils.datetime import to_excel, to_ISO8601
|
||||
from datetime import timedelta
|
||||
|
||||
from openpyxl.worksheet.formula import DataTableFormula, ArrayFormula
|
||||
from openpyxl.cell.rich_text import CellRichText
|
||||
|
||||
def _set_attributes(cell, styled=None):
|
||||
"""
|
||||
Set coordinate and datatype
|
||||
"""
|
||||
coordinate = cell.coordinate
|
||||
attrs = {'r': coordinate}
|
||||
if styled:
|
||||
attrs['s'] = f"{cell.style_id}"
|
||||
|
||||
if cell.data_type == "s":
|
||||
attrs['t'] = "inlineStr"
|
||||
elif cell.data_type != 'f':
|
||||
attrs['t'] = cell.data_type
|
||||
|
||||
value = cell._value
|
||||
|
||||
if cell.data_type == "d":
|
||||
if hasattr(value, "tzinfo") and value.tzinfo is not None:
|
||||
raise TypeError("Excel does not support timezones in datetimes. "
|
||||
"The tzinfo in the datetime/time object must be set to None.")
|
||||
|
||||
if cell.parent.parent.iso_dates and not isinstance(value, timedelta):
|
||||
value = to_ISO8601(value)
|
||||
else:
|
||||
attrs['t'] = "n"
|
||||
value = to_excel(value, cell.parent.parent.epoch)
|
||||
|
||||
if cell.hyperlink:
|
||||
cell.parent._hyperlinks.append(cell.hyperlink)
|
||||
|
||||
return value, attrs
|
||||
|
||||
|
||||
def etree_write_cell(xf, worksheet, cell, styled=None):
|
||||
|
||||
value, attributes = _set_attributes(cell, styled)
|
||||
|
||||
el = Element("c", attributes)
|
||||
if value is None or value == "":
|
||||
xf.write(el)
|
||||
return
|
||||
|
||||
if cell.data_type == 'f':
|
||||
attrib = {}
|
||||
|
||||
if isinstance(value, ArrayFormula):
|
||||
attrib = dict(value)
|
||||
value = value.text
|
||||
|
||||
elif isinstance(value, DataTableFormula):
|
||||
attrib = dict(value)
|
||||
value = None
|
||||
|
||||
formula = SubElement(el, 'f', attrib)
|
||||
if value is not None and not attrib.get('t') == "dataTable":
|
||||
formula.text = value[1:]
|
||||
value = None
|
||||
|
||||
if cell.data_type == 's':
|
||||
if isinstance(value, CellRichText):
|
||||
el.append(value.to_tree())
|
||||
else:
|
||||
inline_string = Element("is")
|
||||
text = Element('t')
|
||||
text.text = value
|
||||
whitespace(text)
|
||||
inline_string.append(text)
|
||||
el.append(inline_string)
|
||||
|
||||
else:
|
||||
cell_content = SubElement(el, 'v')
|
||||
if value is not None:
|
||||
cell_content.text = safe_string(value)
|
||||
|
||||
xf.write(el)
|
||||
|
||||
|
||||
def lxml_write_cell(xf, worksheet, cell, styled=False):
|
||||
value, attributes = _set_attributes(cell, styled)
|
||||
|
||||
if value == '' or value is None:
|
||||
with xf.element("c", attributes):
|
||||
return
|
||||
|
||||
with xf.element('c', attributes):
|
||||
if cell.data_type == 'f':
|
||||
attrib = {}
|
||||
|
||||
if isinstance(value, ArrayFormula):
|
||||
attrib = dict(value)
|
||||
value = value.text
|
||||
|
||||
elif isinstance(value, DataTableFormula):
|
||||
attrib = dict(value)
|
||||
value = None
|
||||
|
||||
with xf.element('f', attrib):
|
||||
if value is not None and not attrib.get('t') == "dataTable":
|
||||
xf.write(value[1:])
|
||||
value = None
|
||||
|
||||
if cell.data_type == 's':
|
||||
if isinstance(value, CellRichText):
|
||||
el = value.to_tree()
|
||||
xf.write(el)
|
||||
else:
|
||||
with xf.element("is"):
|
||||
if isinstance(value, str):
|
||||
attrs = {}
|
||||
if value != value.strip():
|
||||
attrs["{%s}space" % XML_NS] = "preserve"
|
||||
el = Element("t", attrs) # lxml can't handle xml-ns
|
||||
el.text = value
|
||||
xf.write(el)
|
||||
|
||||
else:
|
||||
with xf.element("v"):
|
||||
if value is not None:
|
||||
xf.write(safe_string(value))
|
||||
|
||||
|
||||
if LXML:
|
||||
write_cell = lxml_write_cell
|
||||
else:
|
||||
write_cell = etree_write_cell
|
332
lib/python3.13/site-packages/openpyxl/cell/cell.py
Normal file
332
lib/python3.13/site-packages/openpyxl/cell/cell.py
Normal file
@ -0,0 +1,332 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
"""Manage individual cells in a spreadsheet.
|
||||
|
||||
The Cell class is required to know its value and type, display options,
|
||||
and any other features of an Excel cell. Utilities for referencing
|
||||
cells using Excel's 'A1' column/row nomenclature are also provided.
|
||||
|
||||
"""
|
||||
|
||||
__docformat__ = "restructuredtext en"
|
||||
|
||||
# Python stdlib imports
|
||||
from copy import copy
|
||||
import datetime
|
||||
import re
|
||||
|
||||
|
||||
from openpyxl.compat import (
|
||||
NUMERIC_TYPES,
|
||||
)
|
||||
|
||||
from openpyxl.utils.exceptions import IllegalCharacterError
|
||||
|
||||
from openpyxl.utils import get_column_letter
|
||||
from openpyxl.styles import numbers, is_date_format
|
||||
from openpyxl.styles.styleable import StyleableObject
|
||||
from openpyxl.worksheet.hyperlink import Hyperlink
|
||||
from openpyxl.worksheet.formula import DataTableFormula, ArrayFormula
|
||||
from openpyxl.cell.rich_text import CellRichText
|
||||
|
||||
# constants
|
||||
|
||||
TIME_TYPES = (datetime.datetime, datetime.date, datetime.time, datetime.timedelta)
|
||||
TIME_FORMATS = {
|
||||
datetime.datetime:numbers.FORMAT_DATE_DATETIME,
|
||||
datetime.date:numbers.FORMAT_DATE_YYYYMMDD2,
|
||||
datetime.time:numbers.FORMAT_DATE_TIME6,
|
||||
datetime.timedelta:numbers.FORMAT_DATE_TIMEDELTA,
|
||||
}
|
||||
|
||||
STRING_TYPES = (str, bytes, CellRichText)
|
||||
KNOWN_TYPES = NUMERIC_TYPES + TIME_TYPES + STRING_TYPES + (bool, type(None))
|
||||
|
||||
ILLEGAL_CHARACTERS_RE = re.compile(r'[\000-\010]|[\013-\014]|[\016-\037]')
|
||||
ERROR_CODES = ('#NULL!', '#DIV/0!', '#VALUE!', '#REF!', '#NAME?', '#NUM!',
|
||||
'#N/A')
|
||||
|
||||
TYPE_STRING = 's'
|
||||
TYPE_FORMULA = 'f'
|
||||
TYPE_NUMERIC = 'n'
|
||||
TYPE_BOOL = 'b'
|
||||
TYPE_NULL = 'n'
|
||||
TYPE_INLINE = 'inlineStr'
|
||||
TYPE_ERROR = 'e'
|
||||
TYPE_FORMULA_CACHE_STRING = 'str'
|
||||
|
||||
VALID_TYPES = (TYPE_STRING, TYPE_FORMULA, TYPE_NUMERIC, TYPE_BOOL,
|
||||
TYPE_NULL, TYPE_INLINE, TYPE_ERROR, TYPE_FORMULA_CACHE_STRING)
|
||||
|
||||
|
||||
_TYPES = {int:'n', float:'n', str:'s', bool:'b'}
|
||||
|
||||
|
||||
def get_type(t, value):
|
||||
if isinstance(value, NUMERIC_TYPES):
|
||||
dt = 'n'
|
||||
elif isinstance(value, STRING_TYPES):
|
||||
dt = 's'
|
||||
elif isinstance(value, TIME_TYPES):
|
||||
dt = 'd'
|
||||
elif isinstance(value, (DataTableFormula, ArrayFormula)):
|
||||
dt = 'f'
|
||||
else:
|
||||
return
|
||||
_TYPES[t] = dt
|
||||
return dt
|
||||
|
||||
|
||||
def get_time_format(t):
|
||||
value = TIME_FORMATS.get(t)
|
||||
if value:
|
||||
return value
|
||||
for base in t.mro()[1:]:
|
||||
value = TIME_FORMATS.get(base)
|
||||
if value:
|
||||
TIME_FORMATS[t] = value
|
||||
return value
|
||||
raise ValueError("Could not get time format for {0!r}".format(value))
|
||||
|
||||
|
||||
class Cell(StyleableObject):
|
||||
"""Describes cell associated properties.
|
||||
|
||||
Properties of interest include style, type, value, and address.
|
||||
|
||||
"""
|
||||
__slots__ = (
|
||||
'row',
|
||||
'column',
|
||||
'_value',
|
||||
'data_type',
|
||||
'parent',
|
||||
'_hyperlink',
|
||||
'_comment',
|
||||
)
|
||||
|
||||
def __init__(self, worksheet, row=None, column=None, value=None, style_array=None):
|
||||
super().__init__(worksheet, style_array)
|
||||
self.row = row
|
||||
"""Row number of this cell (1-based)"""
|
||||
self.column = column
|
||||
"""Column number of this cell (1-based)"""
|
||||
# _value is the stored value, while value is the displayed value
|
||||
self._value = None
|
||||
self._hyperlink = None
|
||||
self.data_type = 'n'
|
||||
if value is not None:
|
||||
self.value = value
|
||||
self._comment = None
|
||||
|
||||
|
||||
@property
|
||||
def coordinate(self):
|
||||
"""This cell's coordinate (ex. 'A5')"""
|
||||
col = get_column_letter(self.column)
|
||||
return f"{col}{self.row}"
|
||||
|
||||
|
||||
@property
|
||||
def col_idx(self):
|
||||
"""The numerical index of the column"""
|
||||
return self.column
|
||||
|
||||
|
||||
@property
|
||||
def column_letter(self):
|
||||
return get_column_letter(self.column)
|
||||
|
||||
|
||||
@property
|
||||
def encoding(self):
|
||||
return self.parent.encoding
|
||||
|
||||
@property
|
||||
def base_date(self):
|
||||
return self.parent.parent.epoch
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "<Cell {0!r}.{1}>".format(self.parent.title, self.coordinate)
|
||||
|
||||
def check_string(self, value):
|
||||
"""Check string coding, length, and line break character"""
|
||||
if value is None:
|
||||
return
|
||||
# convert to str string
|
||||
if not isinstance(value, str):
|
||||
value = str(value, self.encoding)
|
||||
value = str(value)
|
||||
# string must never be longer than 32,767 characters
|
||||
# truncate if necessary
|
||||
value = value[:32767]
|
||||
if next(ILLEGAL_CHARACTERS_RE.finditer(value), None):
|
||||
raise IllegalCharacterError(f"{value} cannot be used in worksheets.")
|
||||
return value
|
||||
|
||||
def check_error(self, value):
|
||||
"""Tries to convert Error" else N/A"""
|
||||
try:
|
||||
return str(value)
|
||||
except UnicodeDecodeError:
|
||||
return u'#N/A'
|
||||
|
||||
|
||||
def _bind_value(self, value):
|
||||
"""Given a value, infer the correct data type"""
|
||||
|
||||
self.data_type = "n"
|
||||
t = type(value)
|
||||
try:
|
||||
dt = _TYPES[t]
|
||||
except KeyError:
|
||||
dt = get_type(t, value)
|
||||
|
||||
if dt is None and value is not None:
|
||||
raise ValueError("Cannot convert {0!r} to Excel".format(value))
|
||||
|
||||
if dt:
|
||||
self.data_type = dt
|
||||
|
||||
if dt == 'd':
|
||||
if not is_date_format(self.number_format):
|
||||
self.number_format = get_time_format(t)
|
||||
|
||||
elif dt == "s" and not isinstance(value, CellRichText):
|
||||
value = self.check_string(value)
|
||||
if len(value) > 1 and value.startswith("="):
|
||||
self.data_type = 'f'
|
||||
elif value in ERROR_CODES:
|
||||
self.data_type = 'e'
|
||||
|
||||
self._value = value
|
||||
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
"""Get or set the value held in the cell.
|
||||
|
||||
:type: depends on the value (string, float, int or
|
||||
:class:`datetime.datetime`)
|
||||
"""
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
"""Set the value and infer type and display options."""
|
||||
self._bind_value(value)
|
||||
|
||||
@property
|
||||
def internal_value(self):
|
||||
"""Always returns the value for excel."""
|
||||
return self._value
|
||||
|
||||
@property
|
||||
def hyperlink(self):
|
||||
"""Return the hyperlink target or an empty string"""
|
||||
return self._hyperlink
|
||||
|
||||
|
||||
@hyperlink.setter
|
||||
def hyperlink(self, val):
|
||||
"""Set value and display for hyperlinks in a cell.
|
||||
Automatically sets the `value` of the cell with link text,
|
||||
but you can modify it afterwards by setting the `value`
|
||||
property, and the hyperlink will remain.
|
||||
Hyperlink is removed if set to ``None``."""
|
||||
if val is None:
|
||||
self._hyperlink = None
|
||||
else:
|
||||
if not isinstance(val, Hyperlink):
|
||||
val = Hyperlink(ref="", target=val)
|
||||
val.ref = self.coordinate
|
||||
self._hyperlink = val
|
||||
if self._value is None:
|
||||
self.value = val.target or val.location
|
||||
|
||||
|
||||
@property
|
||||
def is_date(self):
|
||||
"""True if the value is formatted as a date
|
||||
|
||||
:type: bool
|
||||
"""
|
||||
return self.data_type == 'd' or (
|
||||
self.data_type == 'n' and is_date_format(self.number_format)
|
||||
)
|
||||
|
||||
|
||||
def offset(self, row=0, column=0):
|
||||
"""Returns a cell location relative to this cell.
|
||||
|
||||
:param row: number of rows to offset
|
||||
:type row: int
|
||||
|
||||
:param column: number of columns to offset
|
||||
:type column: int
|
||||
|
||||
:rtype: :class:`openpyxl.cell.Cell`
|
||||
"""
|
||||
offset_column = self.col_idx + column
|
||||
offset_row = self.row + row
|
||||
return self.parent.cell(column=offset_column, row=offset_row)
|
||||
|
||||
|
||||
@property
|
||||
def comment(self):
|
||||
""" Returns the comment associated with this cell
|
||||
|
||||
:type: :class:`openpyxl.comments.Comment`
|
||||
"""
|
||||
return self._comment
|
||||
|
||||
|
||||
@comment.setter
|
||||
def comment(self, value):
|
||||
"""
|
||||
Assign a comment to a cell
|
||||
"""
|
||||
|
||||
if value is not None:
|
||||
if value.parent:
|
||||
value = copy(value)
|
||||
value.bind(self)
|
||||
elif value is None and self._comment:
|
||||
self._comment.unbind()
|
||||
self._comment = value
|
||||
|
||||
|
||||
class MergedCell(StyleableObject):
|
||||
|
||||
"""
|
||||
Describes the properties of a cell in a merged cell and helps to
|
||||
display the borders of the merged cell.
|
||||
|
||||
The value of a MergedCell is always None.
|
||||
"""
|
||||
|
||||
__slots__ = ('row', 'column')
|
||||
|
||||
_value = None
|
||||
data_type = "n"
|
||||
comment = None
|
||||
hyperlink = None
|
||||
|
||||
|
||||
def __init__(self, worksheet, row=None, column=None):
|
||||
super().__init__(worksheet)
|
||||
self.row = row
|
||||
self.column = column
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "<MergedCell {0!r}.{1}>".format(self.parent.title, self.coordinate)
|
||||
|
||||
coordinate = Cell.coordinate
|
||||
_comment = comment
|
||||
value = _value
|
||||
|
||||
|
||||
def WriteOnlyCell(ws=None, value=None):
|
||||
return Cell(worksheet=ws, column=1, row=1, value=value)
|
136
lib/python3.13/site-packages/openpyxl/cell/read_only.py
Normal file
136
lib/python3.13/site-packages/openpyxl/cell/read_only.py
Normal file
@ -0,0 +1,136 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.cell import Cell
|
||||
from openpyxl.utils import get_column_letter
|
||||
from openpyxl.utils.datetime import from_excel
|
||||
from openpyxl.styles import is_date_format
|
||||
from openpyxl.styles.numbers import BUILTIN_FORMATS, BUILTIN_FORMATS_MAX_SIZE
|
||||
|
||||
|
||||
class ReadOnlyCell:
|
||||
|
||||
__slots__ = ('parent', 'row', 'column', '_value', 'data_type', '_style_id')
|
||||
|
||||
def __init__(self, sheet, row, column, value, data_type='n', style_id=0):
|
||||
self.parent = sheet
|
||||
self._value = None
|
||||
self.row = row
|
||||
self.column = column
|
||||
self.data_type = data_type
|
||||
self.value = value
|
||||
self._style_id = style_id
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
for a in self.__slots__:
|
||||
if getattr(self, a) != getattr(other, a):
|
||||
return
|
||||
return True
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "<ReadOnlyCell {0!r}.{1}>".format(self.parent.title, self.coordinate)
|
||||
|
||||
|
||||
@property
|
||||
def coordinate(self):
|
||||
column = get_column_letter(self.column)
|
||||
return "{1}{0}".format(self.row, column)
|
||||
|
||||
|
||||
@property
|
||||
def coordinate(self):
|
||||
return Cell.coordinate.__get__(self)
|
||||
|
||||
|
||||
@property
|
||||
def column_letter(self):
|
||||
return Cell.column_letter.__get__(self)
|
||||
|
||||
|
||||
@property
|
||||
def style_array(self):
|
||||
return self.parent.parent._cell_styles[self._style_id]
|
||||
|
||||
|
||||
@property
|
||||
def has_style(self):
|
||||
return self._style_id != 0
|
||||
|
||||
|
||||
@property
|
||||
def number_format(self):
|
||||
_id = self.style_array.numFmtId
|
||||
if _id < BUILTIN_FORMATS_MAX_SIZE:
|
||||
return BUILTIN_FORMATS.get(_id, "General")
|
||||
else:
|
||||
return self.parent.parent._number_formats[
|
||||
_id - BUILTIN_FORMATS_MAX_SIZE]
|
||||
|
||||
@property
|
||||
def font(self):
|
||||
_id = self.style_array.fontId
|
||||
return self.parent.parent._fonts[_id]
|
||||
|
||||
@property
|
||||
def fill(self):
|
||||
_id = self.style_array.fillId
|
||||
return self.parent.parent._fills[_id]
|
||||
|
||||
@property
|
||||
def border(self):
|
||||
_id = self.style_array.borderId
|
||||
return self.parent.parent._borders[_id]
|
||||
|
||||
@property
|
||||
def alignment(self):
|
||||
_id = self.style_array.alignmentId
|
||||
return self.parent.parent._alignments[_id]
|
||||
|
||||
@property
|
||||
def protection(self):
|
||||
_id = self.style_array.protectionId
|
||||
return self.parent.parent._protections[_id]
|
||||
|
||||
|
||||
@property
|
||||
def is_date(self):
|
||||
return Cell.is_date.__get__(self)
|
||||
|
||||
|
||||
@property
|
||||
def internal_value(self):
|
||||
return self._value
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
if self._value is not None:
|
||||
raise AttributeError("Cell is read only")
|
||||
self._value = value
|
||||
|
||||
|
||||
class EmptyCell:
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
value = None
|
||||
is_date = False
|
||||
font = None
|
||||
border = None
|
||||
fill = None
|
||||
number_format = None
|
||||
alignment = None
|
||||
data_type = 'n'
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "<EmptyCell>"
|
||||
|
||||
EMPTY_CELL = EmptyCell()
|
202
lib/python3.13/site-packages/openpyxl/cell/rich_text.py
Normal file
202
lib/python3.13/site-packages/openpyxl/cell/rich_text.py
Normal file
@ -0,0 +1,202 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
"""
|
||||
RichText definition
|
||||
"""
|
||||
from copy import copy
|
||||
from openpyxl.compat import NUMERIC_TYPES
|
||||
from openpyxl.cell.text import InlineFont, Text
|
||||
from openpyxl.descriptors import (
|
||||
Strict,
|
||||
String,
|
||||
Typed
|
||||
)
|
||||
|
||||
from openpyxl.xml.functions import Element, whitespace
|
||||
|
||||
class TextBlock(Strict):
|
||||
""" Represents text string in a specific format
|
||||
|
||||
This class is used as part of constructing a rich text strings.
|
||||
"""
|
||||
font = Typed(expected_type=InlineFont)
|
||||
text = String()
|
||||
|
||||
def __init__(self, font, text):
|
||||
self.font = font
|
||||
self.text = text
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.text == other.text and self.font == other.font
|
||||
|
||||
|
||||
def __str__(self):
|
||||
"""Just retun the text"""
|
||||
return self.text
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
font = self.font != InlineFont() and self.font or "default"
|
||||
return f"{self.__class__.__name__} text={self.text}, font={font}"
|
||||
|
||||
|
||||
def to_tree(self):
|
||||
el = Element("r")
|
||||
el.append(self.font.to_tree(tagname="rPr"))
|
||||
t = Element("t")
|
||||
t.text = self.text
|
||||
whitespace(t)
|
||||
el.append(t)
|
||||
return el
|
||||
|
||||
#
|
||||
# Rich Text class.
|
||||
# This class behaves just like a list whose members are either simple strings, or TextBlock() instances.
|
||||
# In addition, it can be initialized in several ways:
|
||||
# t = CellRFichText([...]) # initialize with a list.
|
||||
# t = CellRFichText((...)) # initialize with a tuple.
|
||||
# t = CellRichText(node) # where node is an Element() from either lxml or xml.etree (has a 'tag' element)
|
||||
class CellRichText(list):
|
||||
"""Represents a rich text string.
|
||||
|
||||
Initialize with a list made of pure strings or :class:`TextBlock` elements
|
||||
Can index object to access or modify individual rich text elements
|
||||
it also supports the + and += operators between rich text strings
|
||||
There are no user methods for this class
|
||||
|
||||
operations which modify the string will generally call an optimization pass afterwards,
|
||||
that merges text blocks with identical formats, consecutive pure text strings,
|
||||
and remove empty strings and empty text blocks
|
||||
"""
|
||||
|
||||
def __init__(self, *args):
|
||||
if len(args) == 1:
|
||||
args = args[0]
|
||||
if isinstance(args, (list, tuple)):
|
||||
CellRichText._check_rich_text(args)
|
||||
else:
|
||||
CellRichText._check_element(args)
|
||||
args = [args]
|
||||
else:
|
||||
CellRichText._check_rich_text(args)
|
||||
super().__init__(args)
|
||||
|
||||
|
||||
@classmethod
|
||||
def _check_element(cls, value):
|
||||
if not isinstance(value, (str, TextBlock, NUMERIC_TYPES)):
|
||||
raise TypeError(f"Illegal CellRichText element {value}")
|
||||
|
||||
|
||||
@classmethod
|
||||
def _check_rich_text(cls, rich_text):
|
||||
for t in rich_text:
|
||||
CellRichText._check_element(t)
|
||||
|
||||
@classmethod
|
||||
def from_tree(cls, node):
|
||||
text = Text.from_tree(node)
|
||||
if text.t:
|
||||
return (text.t.replace('x005F_', ''),)
|
||||
s = []
|
||||
for r in text.r:
|
||||
t = ""
|
||||
if r.t:
|
||||
t = r.t.replace('x005F_', '')
|
||||
if r.rPr:
|
||||
s.append(TextBlock(r.rPr, t))
|
||||
else:
|
||||
s.append(t)
|
||||
return cls(s)
|
||||
|
||||
# Merge TextBlocks with identical formatting
|
||||
# remove empty elements
|
||||
def _opt(self):
|
||||
last_t = None
|
||||
l = CellRichText(tuple())
|
||||
for t in self:
|
||||
if isinstance(t, str):
|
||||
if not t:
|
||||
continue
|
||||
elif not t.text:
|
||||
continue
|
||||
if type(last_t) == type(t):
|
||||
if isinstance(t, str):
|
||||
last_t += t
|
||||
continue
|
||||
elif last_t.font == t.font:
|
||||
last_t.text += t.text
|
||||
continue
|
||||
if last_t:
|
||||
l.append(last_t)
|
||||
last_t = t
|
||||
if last_t:
|
||||
# Add remaining TextBlock at end of rich text
|
||||
l.append(last_t)
|
||||
super().__setitem__(slice(None), l)
|
||||
return self
|
||||
|
||||
|
||||
def __iadd__(self, arg):
|
||||
# copy used here to create new TextBlock() so we don't modify the right hand side in _opt()
|
||||
CellRichText._check_rich_text(arg)
|
||||
super().__iadd__([copy(e) for e in list(arg)])
|
||||
return self._opt()
|
||||
|
||||
|
||||
def __add__(self, arg):
|
||||
return CellRichText([copy(e) for e in list(self) + list(arg)])._opt()
|
||||
|
||||
|
||||
def __setitem__(self, indx, val):
|
||||
CellRichText._check_element(val)
|
||||
super().__setitem__(indx, val)
|
||||
self._opt()
|
||||
|
||||
|
||||
def append(self, arg):
|
||||
CellRichText._check_element(arg)
|
||||
super().append(arg)
|
||||
|
||||
|
||||
def extend(self, arg):
|
||||
CellRichText._check_rich_text(arg)
|
||||
super().extend(arg)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "CellRichText([{}])".format(', '.join((repr(s) for s in self)))
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return ''.join([str(s) for s in self])
|
||||
|
||||
|
||||
def as_list(self):
|
||||
"""
|
||||
Returns a list of the strings contained.
|
||||
The main reason for this is to make editing easier.
|
||||
"""
|
||||
return [str(s) for s in self]
|
||||
|
||||
|
||||
def to_tree(self):
|
||||
"""
|
||||
Return the full XML representation
|
||||
"""
|
||||
container = Element("is")
|
||||
for obj in self:
|
||||
if isinstance(obj, TextBlock):
|
||||
container.append(obj.to_tree())
|
||||
|
||||
else:
|
||||
el = Element("r")
|
||||
t = Element("t")
|
||||
t.text = obj
|
||||
whitespace(t)
|
||||
el.append(t)
|
||||
container.append(el)
|
||||
|
||||
return container
|
||||
|
184
lib/python3.13/site-packages/openpyxl/cell/text.py
Normal file
184
lib/python3.13/site-packages/openpyxl/cell/text.py
Normal file
@ -0,0 +1,184 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
"""
|
||||
Richtext definition
|
||||
"""
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Alias,
|
||||
Typed,
|
||||
Integer,
|
||||
Set,
|
||||
NoneSet,
|
||||
Bool,
|
||||
String,
|
||||
Sequence,
|
||||
)
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedBool,
|
||||
NestedInteger,
|
||||
NestedString,
|
||||
NestedText,
|
||||
)
|
||||
from openpyxl.styles.fonts import Font
|
||||
|
||||
|
||||
class PhoneticProperties(Serialisable):
|
||||
|
||||
tagname = "phoneticPr"
|
||||
|
||||
fontId = Integer()
|
||||
type = NoneSet(values=(['halfwidthKatakana', 'fullwidthKatakana',
|
||||
'Hiragana', 'noConversion']))
|
||||
alignment = NoneSet(values=(['noControl', 'left', 'center', 'distributed']))
|
||||
|
||||
def __init__(self,
|
||||
fontId=None,
|
||||
type=None,
|
||||
alignment=None,
|
||||
):
|
||||
self.fontId = fontId
|
||||
self.type = type
|
||||
self.alignment = alignment
|
||||
|
||||
|
||||
class PhoneticText(Serialisable):
|
||||
|
||||
tagname = "rPh"
|
||||
|
||||
sb = Integer()
|
||||
eb = Integer()
|
||||
t = NestedText(expected_type=str)
|
||||
text = Alias('t')
|
||||
|
||||
def __init__(self,
|
||||
sb=None,
|
||||
eb=None,
|
||||
t=None,
|
||||
):
|
||||
self.sb = sb
|
||||
self.eb = eb
|
||||
self.t = t
|
||||
|
||||
|
||||
class InlineFont(Font):
|
||||
|
||||
"""
|
||||
Font for inline text because, yes what you need are different objects with the same elements but different constraints.
|
||||
"""
|
||||
|
||||
tagname = "RPrElt"
|
||||
|
||||
rFont = NestedString(allow_none=True)
|
||||
charset = Font.charset
|
||||
family = Font.family
|
||||
b =Font.b
|
||||
i = Font.i
|
||||
strike = Font.strike
|
||||
outline = Font.outline
|
||||
shadow = Font.shadow
|
||||
condense = Font.condense
|
||||
extend = Font.extend
|
||||
color = Font.color
|
||||
sz = Font.sz
|
||||
u = Font.u
|
||||
vertAlign = Font.vertAlign
|
||||
scheme = Font.scheme
|
||||
|
||||
__elements__ = ('rFont', 'charset', 'family', 'b', 'i', 'strike',
|
||||
'outline', 'shadow', 'condense', 'extend', 'color', 'sz', 'u',
|
||||
'vertAlign', 'scheme')
|
||||
|
||||
def __init__(self,
|
||||
rFont=None,
|
||||
charset=None,
|
||||
family=None,
|
||||
b=None,
|
||||
i=None,
|
||||
strike=None,
|
||||
outline=None,
|
||||
shadow=None,
|
||||
condense=None,
|
||||
extend=None,
|
||||
color=None,
|
||||
sz=None,
|
||||
u=None,
|
||||
vertAlign=None,
|
||||
scheme=None,
|
||||
):
|
||||
self.rFont = rFont
|
||||
self.charset = charset
|
||||
self.family = family
|
||||
self.b = b
|
||||
self.i = i
|
||||
self.strike = strike
|
||||
self.outline = outline
|
||||
self.shadow = shadow
|
||||
self.condense = condense
|
||||
self.extend = extend
|
||||
self.color = color
|
||||
self.sz = sz
|
||||
self.u = u
|
||||
self.vertAlign = vertAlign
|
||||
self.scheme = scheme
|
||||
|
||||
|
||||
class RichText(Serialisable):
|
||||
|
||||
tagname = "RElt"
|
||||
|
||||
rPr = Typed(expected_type=InlineFont, allow_none=True)
|
||||
font = Alias("rPr")
|
||||
t = NestedText(expected_type=str, allow_none=True)
|
||||
text = Alias("t")
|
||||
|
||||
__elements__ = ('rPr', 't')
|
||||
|
||||
def __init__(self,
|
||||
rPr=None,
|
||||
t=None,
|
||||
):
|
||||
self.rPr = rPr
|
||||
self.t = t
|
||||
|
||||
|
||||
class Text(Serialisable):
|
||||
|
||||
tagname = "text"
|
||||
|
||||
t = NestedText(allow_none=True, expected_type=str)
|
||||
plain = Alias("t")
|
||||
r = Sequence(expected_type=RichText, allow_none=True)
|
||||
formatted = Alias("r")
|
||||
rPh = Sequence(expected_type=PhoneticText, allow_none=True)
|
||||
phonetic = Alias("rPh")
|
||||
phoneticPr = Typed(expected_type=PhoneticProperties, allow_none=True)
|
||||
PhoneticProperties = Alias("phoneticPr")
|
||||
|
||||
__elements__ = ('t', 'r', 'rPh', 'phoneticPr')
|
||||
|
||||
def __init__(self,
|
||||
t=None,
|
||||
r=(),
|
||||
rPh=(),
|
||||
phoneticPr=None,
|
||||
):
|
||||
self.t = t
|
||||
self.r = r
|
||||
self.rPh = rPh
|
||||
self.phoneticPr = phoneticPr
|
||||
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
"""
|
||||
Text stripped of all formatting
|
||||
"""
|
||||
snippets = []
|
||||
if self.plain is not None:
|
||||
snippets.append(self.plain)
|
||||
for block in self.formatted:
|
||||
if block.t is not None:
|
||||
snippets.append(block.t)
|
||||
return u"".join(snippets)
|
105
lib/python3.13/site-packages/openpyxl/chart/_3d.py
Normal file
105
lib/python3.13/site-packages/openpyxl/chart/_3d.py
Normal file
@ -0,0 +1,105 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors import Typed, Alias
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedBool,
|
||||
NestedInteger,
|
||||
NestedMinMax,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from .marker import PictureOptions
|
||||
from .shapes import GraphicalProperties
|
||||
|
||||
|
||||
class View3D(Serialisable):
|
||||
|
||||
tagname = "view3D"
|
||||
|
||||
rotX = NestedMinMax(min=-90, max=90, allow_none=True)
|
||||
x_rotation = Alias('rotX')
|
||||
hPercent = NestedMinMax(min=5, max=500, allow_none=True)
|
||||
height_percent = Alias('hPercent')
|
||||
rotY = NestedInteger(min=-90, max=90, allow_none=True)
|
||||
y_rotation = Alias('rotY')
|
||||
depthPercent = NestedInteger(allow_none=True)
|
||||
rAngAx = NestedBool(allow_none=True)
|
||||
right_angle_axes = Alias('rAngAx')
|
||||
perspective = NestedInteger(allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('rotX', 'hPercent', 'rotY', 'depthPercent', 'rAngAx',
|
||||
'perspective',)
|
||||
|
||||
def __init__(self,
|
||||
rotX=15,
|
||||
hPercent=None,
|
||||
rotY=20,
|
||||
depthPercent=None,
|
||||
rAngAx=True,
|
||||
perspective=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.rotX = rotX
|
||||
self.hPercent = hPercent
|
||||
self.rotY = rotY
|
||||
self.depthPercent = depthPercent
|
||||
self.rAngAx = rAngAx
|
||||
self.perspective = perspective
|
||||
|
||||
|
||||
class Surface(Serialisable):
|
||||
|
||||
tagname = "surface"
|
||||
|
||||
thickness = NestedInteger(allow_none=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
pictureOptions = Typed(expected_type=PictureOptions, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('thickness', 'spPr', 'pictureOptions',)
|
||||
|
||||
def __init__(self,
|
||||
thickness=None,
|
||||
spPr=None,
|
||||
pictureOptions=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.thickness = thickness
|
||||
self.spPr = spPr
|
||||
self.pictureOptions = pictureOptions
|
||||
|
||||
|
||||
class _3DBase(Serialisable):
|
||||
|
||||
"""
|
||||
Base class for 3D charts
|
||||
"""
|
||||
|
||||
tagname = "ChartBase"
|
||||
|
||||
view3D = Typed(expected_type=View3D, allow_none=True)
|
||||
floor = Typed(expected_type=Surface, allow_none=True)
|
||||
sideWall = Typed(expected_type=Surface, allow_none=True)
|
||||
backWall = Typed(expected_type=Surface, allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
view3D=None,
|
||||
floor=None,
|
||||
sideWall=None,
|
||||
backWall=None,
|
||||
):
|
||||
if view3D is None:
|
||||
view3D = View3D()
|
||||
self.view3D = view3D
|
||||
if floor is None:
|
||||
floor = Surface()
|
||||
self.floor = floor
|
||||
if sideWall is None:
|
||||
sideWall = Surface()
|
||||
self.sideWall = sideWall
|
||||
if backWall is None:
|
||||
backWall = Surface()
|
||||
self.backWall = backWall
|
||||
super(_3DBase, self).__init__()
|
19
lib/python3.13/site-packages/openpyxl/chart/__init__.py
Normal file
19
lib/python3.13/site-packages/openpyxl/chart/__init__.py
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from .area_chart import AreaChart, AreaChart3D
|
||||
from .bar_chart import BarChart, BarChart3D
|
||||
from .bubble_chart import BubbleChart
|
||||
from .line_chart import LineChart, LineChart3D
|
||||
from .pie_chart import (
|
||||
PieChart,
|
||||
PieChart3D,
|
||||
DoughnutChart,
|
||||
ProjectedPieChart
|
||||
)
|
||||
from .radar_chart import RadarChart
|
||||
from .scatter_chart import ScatterChart
|
||||
from .stock_chart import StockChart
|
||||
from .surface_chart import SurfaceChart, SurfaceChart3D
|
||||
|
||||
from .series_factory import SeriesFactory as Series
|
||||
from .reference import Reference
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
199
lib/python3.13/site-packages/openpyxl/chart/_chart.py
Normal file
199
lib/python3.13/site-packages/openpyxl/chart/_chart.py
Normal file
@ -0,0 +1,199 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from collections import OrderedDict
|
||||
from operator import attrgetter
|
||||
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Integer,
|
||||
Alias,
|
||||
MinMax,
|
||||
Bool,
|
||||
Set,
|
||||
)
|
||||
from openpyxl.descriptors.sequence import ValueSequence
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
|
||||
from ._3d import _3DBase
|
||||
from .data_source import AxDataSource, NumRef
|
||||
from .layout import Layout
|
||||
from .legend import Legend
|
||||
from .reference import Reference
|
||||
from .series_factory import SeriesFactory
|
||||
from .series import attribute_mapping
|
||||
from .shapes import GraphicalProperties
|
||||
from .title import TitleDescriptor
|
||||
|
||||
class AxId(Serialisable):
|
||||
|
||||
val = Integer()
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
|
||||
def PlotArea():
|
||||
from .chartspace import PlotArea
|
||||
return PlotArea()
|
||||
|
||||
|
||||
class ChartBase(Serialisable):
|
||||
|
||||
"""
|
||||
Base class for all charts
|
||||
"""
|
||||
|
||||
legend = Typed(expected_type=Legend, allow_none=True)
|
||||
layout = Typed(expected_type=Layout, allow_none=True)
|
||||
roundedCorners = Bool(allow_none=True)
|
||||
axId = ValueSequence(expected_type=int)
|
||||
visible_cells_only = Bool(allow_none=True)
|
||||
display_blanks = Set(values=['span', 'gap', 'zero'])
|
||||
graphical_properties = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
|
||||
_series_type = ""
|
||||
ser = ()
|
||||
series = Alias('ser')
|
||||
title = TitleDescriptor()
|
||||
anchor = "E15" # default anchor position
|
||||
width = 15 # in cm, approx 5 rows
|
||||
height = 7.5 # in cm, approx 14 rows
|
||||
_id = 1
|
||||
_path = "/xl/charts/chart{0}.xml"
|
||||
style = MinMax(allow_none=True, min=1, max=48)
|
||||
mime_type = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"
|
||||
graphical_properties = Typed(expected_type=GraphicalProperties, allow_none=True) # mapped to chartspace
|
||||
|
||||
__elements__ = ()
|
||||
|
||||
|
||||
def __init__(self, axId=(), **kw):
|
||||
self._charts = [self]
|
||||
self.title = None
|
||||
self.layout = None
|
||||
self.roundedCorners = None
|
||||
self.legend = Legend()
|
||||
self.graphical_properties = None
|
||||
self.style = None
|
||||
self.plot_area = PlotArea()
|
||||
self.axId = axId
|
||||
self.display_blanks = 'gap'
|
||||
self.pivotSource = None
|
||||
self.pivotFormats = ()
|
||||
self.visible_cells_only = True
|
||||
self.idx_base = 0
|
||||
self.graphical_properties = None
|
||||
super().__init__()
|
||||
|
||||
|
||||
def __hash__(self):
|
||||
"""
|
||||
Just need to check for identity
|
||||
"""
|
||||
return id(self)
|
||||
|
||||
def __iadd__(self, other):
|
||||
"""
|
||||
Combine the chart with another one
|
||||
"""
|
||||
if not isinstance(other, ChartBase):
|
||||
raise TypeError("Only other charts can be added")
|
||||
self._charts.append(other)
|
||||
return self
|
||||
|
||||
|
||||
def to_tree(self, namespace=None, tagname=None, idx=None):
|
||||
self.axId = [id for id in self._axes]
|
||||
if self.ser is not None:
|
||||
for s in self.ser:
|
||||
s.__elements__ = attribute_mapping[self._series_type]
|
||||
return super().to_tree(tagname, idx)
|
||||
|
||||
|
||||
def _reindex(self):
|
||||
"""
|
||||
Normalise and rebase series: sort by order and then rebase order
|
||||
|
||||
"""
|
||||
# sort data series in order and rebase
|
||||
ds = sorted(self.series, key=attrgetter("order"))
|
||||
for idx, s in enumerate(ds):
|
||||
s.order = idx
|
||||
self.series = ds
|
||||
|
||||
|
||||
def _write(self):
|
||||
from .chartspace import ChartSpace, ChartContainer
|
||||
self.plot_area.layout = self.layout
|
||||
|
||||
idx_base = self.idx_base
|
||||
for chart in self._charts:
|
||||
if chart not in self.plot_area._charts:
|
||||
chart.idx_base = idx_base
|
||||
idx_base += len(chart.series)
|
||||
self.plot_area._charts = self._charts
|
||||
|
||||
container = ChartContainer(plotArea=self.plot_area, legend=self.legend, title=self.title)
|
||||
if isinstance(chart, _3DBase):
|
||||
container.view3D = chart.view3D
|
||||
container.floor = chart.floor
|
||||
container.sideWall = chart.sideWall
|
||||
container.backWall = chart.backWall
|
||||
container.plotVisOnly = self.visible_cells_only
|
||||
container.dispBlanksAs = self.display_blanks
|
||||
container.pivotFmts = self.pivotFormats
|
||||
cs = ChartSpace(chart=container)
|
||||
cs.style = self.style
|
||||
cs.roundedCorners = self.roundedCorners
|
||||
cs.pivotSource = self.pivotSource
|
||||
cs.spPr = self.graphical_properties
|
||||
return cs.to_tree()
|
||||
|
||||
|
||||
@property
|
||||
def _axes(self):
|
||||
x = getattr(self, "x_axis", None)
|
||||
y = getattr(self, "y_axis", None)
|
||||
z = getattr(self, "z_axis", None)
|
||||
return OrderedDict([(axis.axId, axis) for axis in (x, y, z) if axis])
|
||||
|
||||
|
||||
def set_categories(self, labels):
|
||||
"""
|
||||
Set the categories / x-axis values
|
||||
"""
|
||||
if not isinstance(labels, Reference):
|
||||
labels = Reference(range_string=labels)
|
||||
for s in self.ser:
|
||||
s.cat = AxDataSource(numRef=NumRef(f=labels))
|
||||
|
||||
|
||||
def add_data(self, data, from_rows=False, titles_from_data=False):
|
||||
"""
|
||||
Add a range of data in a single pass.
|
||||
The default is to treat each column as a data series.
|
||||
"""
|
||||
if not isinstance(data, Reference):
|
||||
data = Reference(range_string=data)
|
||||
|
||||
if from_rows:
|
||||
values = data.rows
|
||||
|
||||
else:
|
||||
values = data.cols
|
||||
|
||||
for ref in values:
|
||||
series = SeriesFactory(ref, title_from_data=titles_from_data)
|
||||
self.series.append(series)
|
||||
|
||||
|
||||
def append(self, value):
|
||||
"""Append a data series to the chart"""
|
||||
l = self.series[:]
|
||||
l.append(value)
|
||||
self.series = l
|
||||
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return self._path.format(self._id)
|
106
lib/python3.13/site-packages/openpyxl/chart/area_chart.py
Normal file
106
lib/python3.13/site-packages/openpyxl/chart/area_chart.py
Normal file
@ -0,0 +1,106 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Set,
|
||||
Bool,
|
||||
Integer,
|
||||
Sequence,
|
||||
Alias,
|
||||
)
|
||||
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedMinMax,
|
||||
NestedSet,
|
||||
NestedBool,
|
||||
)
|
||||
|
||||
from ._chart import ChartBase
|
||||
from .descriptors import NestedGapAmount
|
||||
from .axis import TextAxis, NumericAxis, SeriesAxis, ChartLines
|
||||
from .label import DataLabelList
|
||||
from .series import Series
|
||||
|
||||
|
||||
class _AreaChartBase(ChartBase):
|
||||
|
||||
grouping = NestedSet(values=(['percentStacked', 'standard', 'stacked']))
|
||||
varyColors = NestedBool(nested=True, allow_none=True)
|
||||
ser = Sequence(expected_type=Series, allow_none=True)
|
||||
dLbls = Typed(expected_type=DataLabelList, allow_none=True)
|
||||
dataLabels = Alias("dLbls")
|
||||
dropLines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
|
||||
_series_type = "area"
|
||||
|
||||
__elements__ = ('grouping', 'varyColors', 'ser', 'dLbls', 'dropLines')
|
||||
|
||||
def __init__(self,
|
||||
grouping="standard",
|
||||
varyColors=None,
|
||||
ser=(),
|
||||
dLbls=None,
|
||||
dropLines=None,
|
||||
):
|
||||
self.grouping = grouping
|
||||
self.varyColors = varyColors
|
||||
self.ser = ser
|
||||
self.dLbls = dLbls
|
||||
self.dropLines = dropLines
|
||||
super().__init__()
|
||||
|
||||
|
||||
class AreaChart(_AreaChartBase):
|
||||
|
||||
tagname = "areaChart"
|
||||
|
||||
grouping = _AreaChartBase.grouping
|
||||
varyColors = _AreaChartBase.varyColors
|
||||
ser = _AreaChartBase.ser
|
||||
dLbls = _AreaChartBase.dLbls
|
||||
dropLines = _AreaChartBase.dropLines
|
||||
|
||||
# chart properties actually used by containing classes
|
||||
x_axis = Typed(expected_type=TextAxis)
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = _AreaChartBase.__elements__ + ('axId',)
|
||||
|
||||
def __init__(self,
|
||||
axId=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.x_axis = TextAxis()
|
||||
self.y_axis = NumericAxis()
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class AreaChart3D(AreaChart):
|
||||
|
||||
tagname = "area3DChart"
|
||||
|
||||
grouping = _AreaChartBase.grouping
|
||||
varyColors = _AreaChartBase.varyColors
|
||||
ser = _AreaChartBase.ser
|
||||
dLbls = _AreaChartBase.dLbls
|
||||
dropLines = _AreaChartBase.dropLines
|
||||
|
||||
gapDepth = NestedGapAmount()
|
||||
|
||||
x_axis = Typed(expected_type=TextAxis)
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
z_axis = Typed(expected_type=SeriesAxis, allow_none=True)
|
||||
|
||||
__elements__ = AreaChart.__elements__ + ('gapDepth', )
|
||||
|
||||
def __init__(self, gapDepth=None, **kw):
|
||||
self.gapDepth = gapDepth
|
||||
super(AreaChart3D, self).__init__(**kw)
|
||||
self.x_axis = TextAxis()
|
||||
self.y_axis = NumericAxis()
|
||||
self.z_axis = SeriesAxis()
|
401
lib/python3.13/site-packages/openpyxl/chart/axis.py
Normal file
401
lib/python3.13/site-packages/openpyxl/chart/axis.py
Normal file
@ -0,0 +1,401 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Float,
|
||||
NoneSet,
|
||||
Bool,
|
||||
Integer,
|
||||
MinMax,
|
||||
NoneSet,
|
||||
Set,
|
||||
String,
|
||||
Alias,
|
||||
)
|
||||
|
||||
from openpyxl.descriptors.excel import (
|
||||
ExtensionList,
|
||||
Percentage,
|
||||
_explicit_none,
|
||||
)
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedValue,
|
||||
NestedSet,
|
||||
NestedBool,
|
||||
NestedNoneSet,
|
||||
NestedFloat,
|
||||
NestedInteger,
|
||||
NestedMinMax,
|
||||
)
|
||||
from openpyxl.xml.constants import CHART_NS
|
||||
|
||||
from .descriptors import NumberFormatDescriptor
|
||||
from .layout import Layout
|
||||
from .text import Text, RichText
|
||||
from .shapes import GraphicalProperties
|
||||
from .title import Title, TitleDescriptor
|
||||
|
||||
|
||||
class ChartLines(Serialisable):
|
||||
|
||||
tagname = "chartLines"
|
||||
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
|
||||
def __init__(self, spPr=None):
|
||||
self.spPr = spPr
|
||||
|
||||
|
||||
class Scaling(Serialisable):
|
||||
|
||||
tagname = "scaling"
|
||||
|
||||
logBase = NestedFloat(allow_none=True)
|
||||
orientation = NestedSet(values=(['maxMin', 'minMax']))
|
||||
max = NestedFloat(allow_none=True)
|
||||
min = NestedFloat(allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('logBase', 'orientation', 'max', 'min',)
|
||||
|
||||
def __init__(self,
|
||||
logBase=None,
|
||||
orientation="minMax",
|
||||
max=None,
|
||||
min=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.logBase = logBase
|
||||
self.orientation = orientation
|
||||
self.max = max
|
||||
self.min = min
|
||||
|
||||
|
||||
class _BaseAxis(Serialisable):
|
||||
|
||||
axId = NestedInteger(expected_type=int)
|
||||
scaling = Typed(expected_type=Scaling)
|
||||
delete = NestedBool(allow_none=True)
|
||||
axPos = NestedSet(values=(['b', 'l', 'r', 't']))
|
||||
majorGridlines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
minorGridlines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
title = TitleDescriptor()
|
||||
numFmt = NumberFormatDescriptor()
|
||||
number_format = Alias("numFmt")
|
||||
majorTickMark = NestedNoneSet(values=(['cross', 'in', 'out']), to_tree=_explicit_none)
|
||||
minorTickMark = NestedNoneSet(values=(['cross', 'in', 'out']), to_tree=_explicit_none)
|
||||
tickLblPos = NestedNoneSet(values=(['high', 'low', 'nextTo']))
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
txPr = Typed(expected_type=RichText, allow_none=True)
|
||||
textProperties = Alias('txPr')
|
||||
crossAx = NestedInteger(expected_type=int) # references other axis
|
||||
crosses = NestedNoneSet(values=(['autoZero', 'max', 'min']))
|
||||
crossesAt = NestedFloat(allow_none=True)
|
||||
|
||||
# crosses & crossesAt are mutually exclusive
|
||||
|
||||
__elements__ = ('axId', 'scaling', 'delete', 'axPos', 'majorGridlines',
|
||||
'minorGridlines', 'title', 'numFmt', 'majorTickMark', 'minorTickMark',
|
||||
'tickLblPos', 'spPr', 'txPr', 'crossAx', 'crosses', 'crossesAt')
|
||||
|
||||
def __init__(self,
|
||||
axId=None,
|
||||
scaling=None,
|
||||
delete=None,
|
||||
axPos='l',
|
||||
majorGridlines=None,
|
||||
minorGridlines=None,
|
||||
title=None,
|
||||
numFmt=None,
|
||||
majorTickMark=None,
|
||||
minorTickMark=None,
|
||||
tickLblPos=None,
|
||||
spPr=None,
|
||||
txPr= None,
|
||||
crossAx=None,
|
||||
crosses=None,
|
||||
crossesAt=None,
|
||||
):
|
||||
self.axId = axId
|
||||
if scaling is None:
|
||||
scaling = Scaling()
|
||||
self.scaling = scaling
|
||||
self.delete = delete
|
||||
self.axPos = axPos
|
||||
self.majorGridlines = majorGridlines
|
||||
self.minorGridlines = minorGridlines
|
||||
self.title = title
|
||||
self.numFmt = numFmt
|
||||
self.majorTickMark = majorTickMark
|
||||
self.minorTickMark = minorTickMark
|
||||
self.tickLblPos = tickLblPos
|
||||
self.spPr = spPr
|
||||
self.txPr = txPr
|
||||
self.crossAx = crossAx
|
||||
self.crosses = crosses
|
||||
self.crossesAt = crossesAt
|
||||
|
||||
|
||||
class DisplayUnitsLabel(Serialisable):
|
||||
|
||||
tagname = "dispUnitsLbl"
|
||||
|
||||
layout = Typed(expected_type=Layout, allow_none=True)
|
||||
tx = Typed(expected_type=Text, allow_none=True)
|
||||
text = Alias("tx")
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias("spPr")
|
||||
txPr = Typed(expected_type=RichText, allow_none=True)
|
||||
textPropertes = Alias("txPr")
|
||||
|
||||
__elements__ = ('layout', 'tx', 'spPr', 'txPr')
|
||||
|
||||
def __init__(self,
|
||||
layout=None,
|
||||
tx=None,
|
||||
spPr=None,
|
||||
txPr=None,
|
||||
):
|
||||
self.layout = layout
|
||||
self.tx = tx
|
||||
self.spPr = spPr
|
||||
self.txPr = txPr
|
||||
|
||||
|
||||
class DisplayUnitsLabelList(Serialisable):
|
||||
|
||||
tagname = "dispUnits"
|
||||
|
||||
custUnit = NestedFloat(allow_none=True)
|
||||
builtInUnit = NestedNoneSet(values=(['hundreds', 'thousands',
|
||||
'tenThousands', 'hundredThousands', 'millions', 'tenMillions',
|
||||
'hundredMillions', 'billions', 'trillions']))
|
||||
dispUnitsLbl = Typed(expected_type=DisplayUnitsLabel, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('custUnit', 'builtInUnit', 'dispUnitsLbl',)
|
||||
|
||||
def __init__(self,
|
||||
custUnit=None,
|
||||
builtInUnit=None,
|
||||
dispUnitsLbl=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.custUnit = custUnit
|
||||
self.builtInUnit = builtInUnit
|
||||
self.dispUnitsLbl = dispUnitsLbl
|
||||
|
||||
|
||||
class NumericAxis(_BaseAxis):
|
||||
|
||||
tagname = "valAx"
|
||||
|
||||
axId = _BaseAxis.axId
|
||||
scaling = _BaseAxis.scaling
|
||||
delete = _BaseAxis.delete
|
||||
axPos = _BaseAxis.axPos
|
||||
majorGridlines = _BaseAxis.majorGridlines
|
||||
minorGridlines = _BaseAxis.minorGridlines
|
||||
title = _BaseAxis.title
|
||||
numFmt = _BaseAxis.numFmt
|
||||
majorTickMark = _BaseAxis.majorTickMark
|
||||
minorTickMark = _BaseAxis.minorTickMark
|
||||
tickLblPos = _BaseAxis.tickLblPos
|
||||
spPr = _BaseAxis.spPr
|
||||
txPr = _BaseAxis.txPr
|
||||
crossAx = _BaseAxis.crossAx
|
||||
crosses = _BaseAxis.crosses
|
||||
crossesAt = _BaseAxis.crossesAt
|
||||
|
||||
crossBetween = NestedNoneSet(values=(['between', 'midCat']))
|
||||
majorUnit = NestedFloat(allow_none=True)
|
||||
minorUnit = NestedFloat(allow_none=True)
|
||||
dispUnits = Typed(expected_type=DisplayUnitsLabelList, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = _BaseAxis.__elements__ + ('crossBetween', 'majorUnit',
|
||||
'minorUnit', 'dispUnits',)
|
||||
|
||||
|
||||
def __init__(self,
|
||||
crossBetween=None,
|
||||
majorUnit=None,
|
||||
minorUnit=None,
|
||||
dispUnits=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.crossBetween = crossBetween
|
||||
self.majorUnit = majorUnit
|
||||
self.minorUnit = minorUnit
|
||||
self.dispUnits = dispUnits
|
||||
kw.setdefault('majorGridlines', ChartLines())
|
||||
kw.setdefault('axId', 100)
|
||||
kw.setdefault('crossAx', 10)
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
@classmethod
|
||||
def from_tree(cls, node):
|
||||
"""
|
||||
Special case value axes with no gridlines
|
||||
"""
|
||||
self = super().from_tree(node)
|
||||
gridlines = node.find("{%s}majorGridlines" % CHART_NS)
|
||||
if gridlines is None:
|
||||
self.majorGridlines = None
|
||||
return self
|
||||
|
||||
|
||||
|
||||
class TextAxis(_BaseAxis):
|
||||
|
||||
tagname = "catAx"
|
||||
|
||||
axId = _BaseAxis.axId
|
||||
scaling = _BaseAxis.scaling
|
||||
delete = _BaseAxis.delete
|
||||
axPos = _BaseAxis.axPos
|
||||
majorGridlines = _BaseAxis.majorGridlines
|
||||
minorGridlines = _BaseAxis.minorGridlines
|
||||
title = _BaseAxis.title
|
||||
numFmt = _BaseAxis.numFmt
|
||||
majorTickMark = _BaseAxis.majorTickMark
|
||||
minorTickMark = _BaseAxis.minorTickMark
|
||||
tickLblPos = _BaseAxis.tickLblPos
|
||||
spPr = _BaseAxis.spPr
|
||||
txPr = _BaseAxis.txPr
|
||||
crossAx = _BaseAxis.crossAx
|
||||
crosses = _BaseAxis.crosses
|
||||
crossesAt = _BaseAxis.crossesAt
|
||||
|
||||
auto = NestedBool(allow_none=True)
|
||||
lblAlgn = NestedNoneSet(values=(['ctr', 'l', 'r']))
|
||||
lblOffset = NestedMinMax(min=0, max=1000)
|
||||
tickLblSkip = NestedInteger(allow_none=True)
|
||||
tickMarkSkip = NestedInteger(allow_none=True)
|
||||
noMultiLvlLbl = NestedBool(allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = _BaseAxis.__elements__ + ('auto', 'lblAlgn', 'lblOffset',
|
||||
'tickLblSkip', 'tickMarkSkip', 'noMultiLvlLbl')
|
||||
|
||||
def __init__(self,
|
||||
auto=None,
|
||||
lblAlgn=None,
|
||||
lblOffset=100,
|
||||
tickLblSkip=None,
|
||||
tickMarkSkip=None,
|
||||
noMultiLvlLbl=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.auto = auto
|
||||
self.lblAlgn = lblAlgn
|
||||
self.lblOffset = lblOffset
|
||||
self.tickLblSkip = tickLblSkip
|
||||
self.tickMarkSkip = tickMarkSkip
|
||||
self.noMultiLvlLbl = noMultiLvlLbl
|
||||
kw.setdefault('axId', 10)
|
||||
kw.setdefault('crossAx', 100)
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class DateAxis(TextAxis):
|
||||
|
||||
tagname = "dateAx"
|
||||
|
||||
axId = _BaseAxis.axId
|
||||
scaling = _BaseAxis.scaling
|
||||
delete = _BaseAxis.delete
|
||||
axPos = _BaseAxis.axPos
|
||||
majorGridlines = _BaseAxis.majorGridlines
|
||||
minorGridlines = _BaseAxis.minorGridlines
|
||||
title = _BaseAxis.title
|
||||
numFmt = _BaseAxis.numFmt
|
||||
majorTickMark = _BaseAxis.majorTickMark
|
||||
minorTickMark = _BaseAxis.minorTickMark
|
||||
tickLblPos = _BaseAxis.tickLblPos
|
||||
spPr = _BaseAxis.spPr
|
||||
txPr = _BaseAxis.txPr
|
||||
crossAx = _BaseAxis.crossAx
|
||||
crosses = _BaseAxis.crosses
|
||||
crossesAt = _BaseAxis.crossesAt
|
||||
|
||||
auto = NestedBool(allow_none=True)
|
||||
lblOffset = NestedInteger(allow_none=True)
|
||||
baseTimeUnit = NestedNoneSet(values=(['days', 'months', 'years']))
|
||||
majorUnit = NestedFloat(allow_none=True)
|
||||
majorTimeUnit = NestedNoneSet(values=(['days', 'months', 'years']))
|
||||
minorUnit = NestedFloat(allow_none=True)
|
||||
minorTimeUnit = NestedNoneSet(values=(['days', 'months', 'years']))
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = _BaseAxis.__elements__ + ('auto', 'lblOffset',
|
||||
'baseTimeUnit', 'majorUnit', 'majorTimeUnit', 'minorUnit',
|
||||
'minorTimeUnit')
|
||||
|
||||
def __init__(self,
|
||||
auto=None,
|
||||
lblOffset=None,
|
||||
baseTimeUnit=None,
|
||||
majorUnit=None,
|
||||
majorTimeUnit=None,
|
||||
minorUnit=None,
|
||||
minorTimeUnit=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.auto = auto
|
||||
self.lblOffset = lblOffset
|
||||
self.baseTimeUnit = baseTimeUnit
|
||||
self.majorUnit = majorUnit
|
||||
self.majorTimeUnit = majorTimeUnit
|
||||
self.minorUnit = minorUnit
|
||||
self.minorTimeUnit = minorTimeUnit
|
||||
kw.setdefault('axId', 500)
|
||||
kw.setdefault('lblOffset', lblOffset)
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class SeriesAxis(_BaseAxis):
|
||||
|
||||
tagname = "serAx"
|
||||
|
||||
axId = _BaseAxis.axId
|
||||
scaling = _BaseAxis.scaling
|
||||
delete = _BaseAxis.delete
|
||||
axPos = _BaseAxis.axPos
|
||||
majorGridlines = _BaseAxis.majorGridlines
|
||||
minorGridlines = _BaseAxis.minorGridlines
|
||||
title = _BaseAxis.title
|
||||
numFmt = _BaseAxis.numFmt
|
||||
majorTickMark = _BaseAxis.majorTickMark
|
||||
minorTickMark = _BaseAxis.minorTickMark
|
||||
tickLblPos = _BaseAxis.tickLblPos
|
||||
spPr = _BaseAxis.spPr
|
||||
txPr = _BaseAxis.txPr
|
||||
crossAx = _BaseAxis.crossAx
|
||||
crosses = _BaseAxis.crosses
|
||||
crossesAt = _BaseAxis.crossesAt
|
||||
|
||||
tickLblSkip = NestedInteger(allow_none=True)
|
||||
tickMarkSkip = NestedInteger(allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = _BaseAxis.__elements__ + ('tickLblSkip', 'tickMarkSkip')
|
||||
|
||||
def __init__(self,
|
||||
tickLblSkip=None,
|
||||
tickMarkSkip=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.tickLblSkip = tickLblSkip
|
||||
self.tickMarkSkip = tickMarkSkip
|
||||
kw.setdefault('axId', 1000)
|
||||
kw.setdefault('crossAx', 10)
|
||||
super().__init__(**kw)
|
144
lib/python3.13/site-packages/openpyxl/chart/bar_chart.py
Normal file
144
lib/python3.13/site-packages/openpyxl/chart/bar_chart.py
Normal file
@ -0,0 +1,144 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Bool,
|
||||
Integer,
|
||||
Sequence,
|
||||
Alias,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedNoneSet,
|
||||
NestedSet,
|
||||
NestedBool,
|
||||
NestedInteger,
|
||||
NestedMinMax,
|
||||
)
|
||||
|
||||
from .descriptors import (
|
||||
NestedGapAmount,
|
||||
NestedOverlap,
|
||||
)
|
||||
from ._chart import ChartBase
|
||||
from ._3d import _3DBase
|
||||
from .axis import TextAxis, NumericAxis, SeriesAxis, ChartLines
|
||||
from .shapes import GraphicalProperties
|
||||
from .series import Series
|
||||
from .legend import Legend
|
||||
from .label import DataLabelList
|
||||
|
||||
|
||||
class _BarChartBase(ChartBase):
|
||||
|
||||
barDir = NestedSet(values=(['bar', 'col']))
|
||||
type = Alias("barDir")
|
||||
grouping = NestedSet(values=(['percentStacked', 'clustered', 'standard',
|
||||
'stacked']))
|
||||
varyColors = NestedBool(nested=True, allow_none=True)
|
||||
ser = Sequence(expected_type=Series, allow_none=True)
|
||||
dLbls = Typed(expected_type=DataLabelList, allow_none=True)
|
||||
dataLabels = Alias("dLbls")
|
||||
|
||||
__elements__ = ('barDir', 'grouping', 'varyColors', 'ser', 'dLbls')
|
||||
|
||||
_series_type = "bar"
|
||||
|
||||
def __init__(self,
|
||||
barDir="col",
|
||||
grouping="clustered",
|
||||
varyColors=None,
|
||||
ser=(),
|
||||
dLbls=None,
|
||||
**kw
|
||||
):
|
||||
self.barDir = barDir
|
||||
self.grouping = grouping
|
||||
self.varyColors = varyColors
|
||||
self.ser = ser
|
||||
self.dLbls = dLbls
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class BarChart(_BarChartBase):
|
||||
|
||||
tagname = "barChart"
|
||||
|
||||
barDir = _BarChartBase.barDir
|
||||
grouping = _BarChartBase.grouping
|
||||
varyColors = _BarChartBase.varyColors
|
||||
ser = _BarChartBase.ser
|
||||
dLbls = _BarChartBase.dLbls
|
||||
|
||||
gapWidth = NestedGapAmount()
|
||||
overlap = NestedOverlap()
|
||||
serLines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
# chart properties actually used by containing classes
|
||||
x_axis = Typed(expected_type=TextAxis)
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
|
||||
__elements__ = _BarChartBase.__elements__ + ('gapWidth', 'overlap', 'serLines', 'axId')
|
||||
|
||||
def __init__(self,
|
||||
gapWidth=150,
|
||||
overlap=None,
|
||||
serLines=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.gapWidth = gapWidth
|
||||
self.overlap = overlap
|
||||
self.serLines = serLines
|
||||
self.x_axis = TextAxis()
|
||||
self.y_axis = NumericAxis()
|
||||
self.legend = Legend()
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class BarChart3D(_BarChartBase, _3DBase):
|
||||
|
||||
tagname = "bar3DChart"
|
||||
|
||||
barDir = _BarChartBase.barDir
|
||||
grouping = _BarChartBase.grouping
|
||||
varyColors = _BarChartBase.varyColors
|
||||
ser = _BarChartBase.ser
|
||||
dLbls = _BarChartBase.dLbls
|
||||
|
||||
view3D = _3DBase.view3D
|
||||
floor = _3DBase.floor
|
||||
sideWall = _3DBase.sideWall
|
||||
backWall = _3DBase.backWall
|
||||
|
||||
gapWidth = NestedGapAmount()
|
||||
gapDepth = NestedGapAmount()
|
||||
shape = NestedNoneSet(values=(['cone', 'coneToMax', 'box', 'cylinder', 'pyramid', 'pyramidToMax']))
|
||||
serLines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
x_axis = Typed(expected_type=TextAxis)
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
z_axis = Typed(expected_type=SeriesAxis, allow_none=True)
|
||||
|
||||
__elements__ = _BarChartBase.__elements__ + ('gapWidth', 'gapDepth', 'shape', 'serLines', 'axId')
|
||||
|
||||
def __init__(self,
|
||||
gapWidth=150,
|
||||
gapDepth=150,
|
||||
shape=None,
|
||||
serLines=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.gapWidth = gapWidth
|
||||
self.gapDepth = gapDepth
|
||||
self.shape = shape
|
||||
self.serLines = serLines
|
||||
self.x_axis = TextAxis()
|
||||
self.y_axis = NumericAxis()
|
||||
self.z_axis = SeriesAxis()
|
||||
|
||||
super(BarChart3D, self).__init__(**kw)
|
67
lib/python3.13/site-packages/openpyxl/chart/bubble_chart.py
Normal file
67
lib/python3.13/site-packages/openpyxl/chart/bubble_chart.py
Normal file
@ -0,0 +1,67 @@
|
||||
#Autogenerated schema
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Set,
|
||||
MinMax,
|
||||
Bool,
|
||||
Integer,
|
||||
Alias,
|
||||
Sequence,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedNoneSet,
|
||||
NestedMinMax,
|
||||
NestedBool,
|
||||
)
|
||||
|
||||
from ._chart import ChartBase
|
||||
from .axis import TextAxis, NumericAxis
|
||||
from .series import XYSeries
|
||||
from .label import DataLabelList
|
||||
|
||||
|
||||
class BubbleChart(ChartBase):
|
||||
|
||||
tagname = "bubbleChart"
|
||||
|
||||
varyColors = NestedBool(allow_none=True)
|
||||
ser = Sequence(expected_type=XYSeries, allow_none=True)
|
||||
dLbls = Typed(expected_type=DataLabelList, allow_none=True)
|
||||
dataLabels = Alias("dLbls")
|
||||
bubble3D = NestedBool(allow_none=True)
|
||||
bubbleScale = NestedMinMax(min=0, max=300, allow_none=True)
|
||||
showNegBubbles = NestedBool(allow_none=True)
|
||||
sizeRepresents = NestedNoneSet(values=(['area', 'w']))
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
x_axis = Typed(expected_type=NumericAxis)
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
|
||||
_series_type = "bubble"
|
||||
|
||||
__elements__ = ('varyColors', 'ser', 'dLbls', 'bubble3D', 'bubbleScale',
|
||||
'showNegBubbles', 'sizeRepresents', 'axId')
|
||||
|
||||
def __init__(self,
|
||||
varyColors=None,
|
||||
ser=(),
|
||||
dLbls=None,
|
||||
bubble3D=None,
|
||||
bubbleScale=None,
|
||||
showNegBubbles=None,
|
||||
sizeRepresents=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.varyColors = varyColors
|
||||
self.ser = ser
|
||||
self.dLbls = dLbls
|
||||
self.bubble3D = bubble3D
|
||||
self.bubbleScale = bubbleScale
|
||||
self.showNegBubbles = showNegBubbles
|
||||
self.sizeRepresents = sizeRepresents
|
||||
self.x_axis = NumericAxis(axId=10, crossAx=20)
|
||||
self.y_axis = NumericAxis(axId=20, crossAx=10)
|
||||
super().__init__(**kw)
|
195
lib/python3.13/site-packages/openpyxl/chart/chartspace.py
Normal file
195
lib/python3.13/site-packages/openpyxl/chart/chartspace.py
Normal file
@ -0,0 +1,195 @@
|
||||
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
"""
|
||||
Enclosing chart object. The various chart types are actually child objects.
|
||||
Will probably need to call this indirectly
|
||||
"""
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
String,
|
||||
Alias,
|
||||
)
|
||||
from openpyxl.descriptors.excel import (
|
||||
ExtensionList,
|
||||
Relation
|
||||
)
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedBool,
|
||||
NestedNoneSet,
|
||||
NestedString,
|
||||
NestedMinMax,
|
||||
)
|
||||
from openpyxl.descriptors.sequence import NestedSequence
|
||||
from openpyxl.xml.constants import CHART_NS
|
||||
|
||||
from openpyxl.drawing.colors import ColorMapping
|
||||
from .text import RichText
|
||||
from .shapes import GraphicalProperties
|
||||
from .legend import Legend
|
||||
from ._3d import _3DBase
|
||||
from .plotarea import PlotArea
|
||||
from .title import Title
|
||||
from .pivot import (
|
||||
PivotFormat,
|
||||
PivotSource,
|
||||
)
|
||||
from .print_settings import PrintSettings
|
||||
|
||||
|
||||
class ChartContainer(Serialisable):
|
||||
|
||||
tagname = "chart"
|
||||
|
||||
title = Typed(expected_type=Title, allow_none=True)
|
||||
autoTitleDeleted = NestedBool(allow_none=True)
|
||||
pivotFmts = NestedSequence(expected_type=PivotFormat)
|
||||
view3D = _3DBase.view3D
|
||||
floor = _3DBase.floor
|
||||
sideWall = _3DBase.sideWall
|
||||
backWall = _3DBase.backWall
|
||||
plotArea = Typed(expected_type=PlotArea, )
|
||||
legend = Typed(expected_type=Legend, allow_none=True)
|
||||
plotVisOnly = NestedBool()
|
||||
dispBlanksAs = NestedNoneSet(values=(['span', 'gap', 'zero']))
|
||||
showDLblsOverMax = NestedBool(allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('title', 'autoTitleDeleted', 'pivotFmts', 'view3D',
|
||||
'floor', 'sideWall', 'backWall', 'plotArea', 'legend', 'plotVisOnly',
|
||||
'dispBlanksAs', 'showDLblsOverMax')
|
||||
|
||||
def __init__(self,
|
||||
title=None,
|
||||
autoTitleDeleted=None,
|
||||
pivotFmts=(),
|
||||
view3D=None,
|
||||
floor=None,
|
||||
sideWall=None,
|
||||
backWall=None,
|
||||
plotArea=None,
|
||||
legend=None,
|
||||
plotVisOnly=True,
|
||||
dispBlanksAs="gap",
|
||||
showDLblsOverMax=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.title = title
|
||||
self.autoTitleDeleted = autoTitleDeleted
|
||||
self.pivotFmts = pivotFmts
|
||||
self.view3D = view3D
|
||||
self.floor = floor
|
||||
self.sideWall = sideWall
|
||||
self.backWall = backWall
|
||||
if plotArea is None:
|
||||
plotArea = PlotArea()
|
||||
self.plotArea = plotArea
|
||||
self.legend = legend
|
||||
self.plotVisOnly = plotVisOnly
|
||||
self.dispBlanksAs = dispBlanksAs
|
||||
self.showDLblsOverMax = showDLblsOverMax
|
||||
|
||||
|
||||
class Protection(Serialisable):
|
||||
|
||||
tagname = "protection"
|
||||
|
||||
chartObject = NestedBool(allow_none=True)
|
||||
data = NestedBool(allow_none=True)
|
||||
formatting = NestedBool(allow_none=True)
|
||||
selection = NestedBool(allow_none=True)
|
||||
userInterface = NestedBool(allow_none=True)
|
||||
|
||||
__elements__ = ("chartObject", "data", "formatting", "selection", "userInterface")
|
||||
|
||||
def __init__(self,
|
||||
chartObject=None,
|
||||
data=None,
|
||||
formatting=None,
|
||||
selection=None,
|
||||
userInterface=None,
|
||||
):
|
||||
self.chartObject = chartObject
|
||||
self.data = data
|
||||
self.formatting = formatting
|
||||
self.selection = selection
|
||||
self.userInterface = userInterface
|
||||
|
||||
|
||||
class ExternalData(Serialisable):
|
||||
|
||||
tagname = "externalData"
|
||||
|
||||
autoUpdate = NestedBool(allow_none=True)
|
||||
id = String() # Needs namespace
|
||||
|
||||
def __init__(self,
|
||||
autoUpdate=None,
|
||||
id=None
|
||||
):
|
||||
self.autoUpdate = autoUpdate
|
||||
self.id = id
|
||||
|
||||
|
||||
class ChartSpace(Serialisable):
|
||||
|
||||
tagname = "chartSpace"
|
||||
|
||||
date1904 = NestedBool(allow_none=True)
|
||||
lang = NestedString(allow_none=True)
|
||||
roundedCorners = NestedBool(allow_none=True)
|
||||
style = NestedMinMax(allow_none=True, min=1, max=48)
|
||||
clrMapOvr = Typed(expected_type=ColorMapping, allow_none=True)
|
||||
pivotSource = Typed(expected_type=PivotSource, allow_none=True)
|
||||
protection = Typed(expected_type=Protection, allow_none=True)
|
||||
chart = Typed(expected_type=ChartContainer)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphical_properties = Alias("spPr")
|
||||
txPr = Typed(expected_type=RichText, allow_none=True)
|
||||
textProperties = Alias("txPr")
|
||||
externalData = Typed(expected_type=ExternalData, allow_none=True)
|
||||
printSettings = Typed(expected_type=PrintSettings, allow_none=True)
|
||||
userShapes = Relation()
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('date1904', 'lang', 'roundedCorners', 'style',
|
||||
'clrMapOvr', 'pivotSource', 'protection', 'chart', 'spPr', 'txPr',
|
||||
'externalData', 'printSettings', 'userShapes')
|
||||
|
||||
def __init__(self,
|
||||
date1904=None,
|
||||
lang=None,
|
||||
roundedCorners=None,
|
||||
style=None,
|
||||
clrMapOvr=None,
|
||||
pivotSource=None,
|
||||
protection=None,
|
||||
chart=None,
|
||||
spPr=None,
|
||||
txPr=None,
|
||||
externalData=None,
|
||||
printSettings=None,
|
||||
userShapes=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.date1904 = date1904
|
||||
self.lang = lang
|
||||
self.roundedCorners = roundedCorners
|
||||
self.style = style
|
||||
self.clrMapOvr = clrMapOvr
|
||||
self.pivotSource = pivotSource
|
||||
self.protection = protection
|
||||
self.chart = chart
|
||||
self.spPr = spPr
|
||||
self.txPr = txPr
|
||||
self.externalData = externalData
|
||||
self.printSettings = printSettings
|
||||
self.userShapes = userShapes
|
||||
|
||||
|
||||
def to_tree(self, tagname=None, idx=None, namespace=None):
|
||||
tree = super().to_tree()
|
||||
tree.set("xmlns", CHART_NS)
|
||||
return tree
|
246
lib/python3.13/site-packages/openpyxl/chart/data_source.py
Normal file
246
lib/python3.13/site-packages/openpyxl/chart/data_source.py
Normal file
@ -0,0 +1,246 @@
|
||||
"""
|
||||
Collection of utility primitives for charts.
|
||||
"""
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Bool,
|
||||
Typed,
|
||||
Alias,
|
||||
String,
|
||||
Integer,
|
||||
Sequence,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedString,
|
||||
NestedText,
|
||||
NestedInteger,
|
||||
)
|
||||
|
||||
|
||||
class NumFmt(Serialisable):
|
||||
|
||||
formatCode = String()
|
||||
sourceLinked = Bool()
|
||||
|
||||
def __init__(self,
|
||||
formatCode=None,
|
||||
sourceLinked=False
|
||||
):
|
||||
self.formatCode = formatCode
|
||||
self.sourceLinked = sourceLinked
|
||||
|
||||
|
||||
class NumberValueDescriptor(NestedText):
|
||||
"""
|
||||
Data should be numerical but isn't always :-/
|
||||
"""
|
||||
|
||||
allow_none = True
|
||||
|
||||
def __set__(self, instance, value):
|
||||
if value == "#N/A":
|
||||
self.expected_type = str
|
||||
else:
|
||||
self.expected_type = float
|
||||
super().__set__(instance, value)
|
||||
|
||||
|
||||
class NumVal(Serialisable):
|
||||
|
||||
idx = Integer()
|
||||
formatCode = NestedText(allow_none=True, expected_type=str)
|
||||
v = NumberValueDescriptor()
|
||||
|
||||
def __init__(self,
|
||||
idx=None,
|
||||
formatCode=None,
|
||||
v=None,
|
||||
):
|
||||
self.idx = idx
|
||||
self.formatCode = formatCode
|
||||
self.v = v
|
||||
|
||||
|
||||
class NumData(Serialisable):
|
||||
|
||||
formatCode = NestedText(expected_type=str, allow_none=True)
|
||||
ptCount = NestedInteger(allow_none=True)
|
||||
pt = Sequence(expected_type=NumVal)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('formatCode', 'ptCount', 'pt')
|
||||
|
||||
def __init__(self,
|
||||
formatCode=None,
|
||||
ptCount=None,
|
||||
pt=(),
|
||||
extLst=None,
|
||||
):
|
||||
self.formatCode = formatCode
|
||||
self.ptCount = ptCount
|
||||
self.pt = pt
|
||||
|
||||
|
||||
class NumRef(Serialisable):
|
||||
|
||||
f = NestedText(expected_type=str)
|
||||
ref = Alias('f')
|
||||
numCache = Typed(expected_type=NumData, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('f', 'numCache')
|
||||
|
||||
def __init__(self,
|
||||
f=None,
|
||||
numCache=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.f = f
|
||||
self.numCache = numCache
|
||||
|
||||
|
||||
class StrVal(Serialisable):
|
||||
|
||||
tagname = "strVal"
|
||||
|
||||
idx = Integer()
|
||||
v = NestedText(expected_type=str)
|
||||
|
||||
def __init__(self,
|
||||
idx=0,
|
||||
v=None,
|
||||
):
|
||||
self.idx = idx
|
||||
self.v = v
|
||||
|
||||
|
||||
class StrData(Serialisable):
|
||||
|
||||
tagname = "strData"
|
||||
|
||||
ptCount = NestedInteger(allow_none=True)
|
||||
pt = Sequence(expected_type=StrVal)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('ptCount', 'pt')
|
||||
|
||||
def __init__(self,
|
||||
ptCount=None,
|
||||
pt=(),
|
||||
extLst=None,
|
||||
):
|
||||
self.ptCount = ptCount
|
||||
self.pt = pt
|
||||
|
||||
|
||||
class StrRef(Serialisable):
|
||||
|
||||
tagname = "strRef"
|
||||
|
||||
f = NestedText(expected_type=str, allow_none=True)
|
||||
strCache = Typed(expected_type=StrData, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('f', 'strCache')
|
||||
|
||||
def __init__(self,
|
||||
f=None,
|
||||
strCache=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.f = f
|
||||
self.strCache = strCache
|
||||
|
||||
|
||||
class NumDataSource(Serialisable):
|
||||
|
||||
numRef = Typed(expected_type=NumRef, allow_none=True)
|
||||
numLit = Typed(expected_type=NumData, allow_none=True)
|
||||
|
||||
|
||||
def __init__(self,
|
||||
numRef=None,
|
||||
numLit=None,
|
||||
):
|
||||
self.numRef = numRef
|
||||
self.numLit = numLit
|
||||
|
||||
|
||||
class Level(Serialisable):
|
||||
|
||||
tagname = "lvl"
|
||||
|
||||
pt = Sequence(expected_type=StrVal)
|
||||
|
||||
__elements__ = ('pt',)
|
||||
|
||||
def __init__(self,
|
||||
pt=(),
|
||||
):
|
||||
self.pt = pt
|
||||
|
||||
|
||||
class MultiLevelStrData(Serialisable):
|
||||
|
||||
tagname = "multiLvlStrData"
|
||||
|
||||
ptCount = Integer(allow_none=True)
|
||||
lvl = Sequence(expected_type=Level)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('ptCount', 'lvl',)
|
||||
|
||||
def __init__(self,
|
||||
ptCount=None,
|
||||
lvl=(),
|
||||
extLst=None,
|
||||
):
|
||||
self.ptCount = ptCount
|
||||
self.lvl = lvl
|
||||
|
||||
|
||||
class MultiLevelStrRef(Serialisable):
|
||||
|
||||
tagname = "multiLvlStrRef"
|
||||
|
||||
f = NestedText(expected_type=str)
|
||||
multiLvlStrCache = Typed(expected_type=MultiLevelStrData, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('multiLvlStrCache', 'f')
|
||||
|
||||
def __init__(self,
|
||||
f=None,
|
||||
multiLvlStrCache=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.f = f
|
||||
self.multiLvlStrCache = multiLvlStrCache
|
||||
|
||||
|
||||
class AxDataSource(Serialisable):
|
||||
|
||||
tagname = "cat"
|
||||
|
||||
numRef = Typed(expected_type=NumRef, allow_none=True)
|
||||
numLit = Typed(expected_type=NumData, allow_none=True)
|
||||
strRef = Typed(expected_type=StrRef, allow_none=True)
|
||||
strLit = Typed(expected_type=StrData, allow_none=True)
|
||||
multiLvlStrRef = Typed(expected_type=MultiLevelStrRef, allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
numRef=None,
|
||||
numLit=None,
|
||||
strRef=None,
|
||||
strLit=None,
|
||||
multiLvlStrRef=None,
|
||||
):
|
||||
if not any([numLit, numRef, strRef, strLit, multiLvlStrRef]):
|
||||
raise TypeError("A data source must be provided")
|
||||
self.numRef = numRef
|
||||
self.numLit = numLit
|
||||
self.strRef = strRef
|
||||
self.strLit = strLit
|
||||
self.multiLvlStrRef = multiLvlStrRef
|
43
lib/python3.13/site-packages/openpyxl/chart/descriptors.py
Normal file
43
lib/python3.13/site-packages/openpyxl/chart/descriptors.py
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
|
||||
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedMinMax
|
||||
)
|
||||
|
||||
from openpyxl.descriptors import Typed
|
||||
|
||||
from .data_source import NumFmt
|
||||
|
||||
"""
|
||||
Utility descriptors for the chart module.
|
||||
For convenience but also clarity.
|
||||
"""
|
||||
|
||||
class NestedGapAmount(NestedMinMax):
|
||||
|
||||
allow_none = True
|
||||
min = 0
|
||||
max = 500
|
||||
|
||||
|
||||
class NestedOverlap(NestedMinMax):
|
||||
|
||||
allow_none = True
|
||||
min = -100
|
||||
max = 100
|
||||
|
||||
|
||||
class NumberFormatDescriptor(Typed):
|
||||
"""
|
||||
Allow direct assignment of format code
|
||||
"""
|
||||
|
||||
expected_type = NumFmt
|
||||
allow_none = True
|
||||
|
||||
def __set__(self, instance, value):
|
||||
if isinstance(value, str):
|
||||
value = NumFmt(value)
|
||||
super().__set__(instance, value)
|
62
lib/python3.13/site-packages/openpyxl/chart/error_bar.py
Normal file
62
lib/python3.13/site-packages/openpyxl/chart/error_bar.py
Normal file
@ -0,0 +1,62 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Float,
|
||||
Set,
|
||||
Alias
|
||||
)
|
||||
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedNoneSet,
|
||||
NestedSet,
|
||||
NestedBool,
|
||||
NestedFloat,
|
||||
)
|
||||
|
||||
from .data_source import NumDataSource
|
||||
from .shapes import GraphicalProperties
|
||||
|
||||
|
||||
class ErrorBars(Serialisable):
|
||||
|
||||
tagname = "errBars"
|
||||
|
||||
errDir = NestedNoneSet(values=(['x', 'y']))
|
||||
direction = Alias("errDir")
|
||||
errBarType = NestedSet(values=(['both', 'minus', 'plus']))
|
||||
style = Alias("errBarType")
|
||||
errValType = NestedSet(values=(['cust', 'fixedVal', 'percentage', 'stdDev', 'stdErr']))
|
||||
size = Alias("errValType")
|
||||
noEndCap = NestedBool(nested=True, allow_none=True)
|
||||
plus = Typed(expected_type=NumDataSource, allow_none=True)
|
||||
minus = Typed(expected_type=NumDataSource, allow_none=True)
|
||||
val = NestedFloat(allow_none=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias("spPr")
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('errDir','errBarType', 'errValType', 'noEndCap','minus', 'plus', 'val', 'spPr')
|
||||
|
||||
|
||||
def __init__(self,
|
||||
errDir=None,
|
||||
errBarType="both",
|
||||
errValType="fixedVal",
|
||||
noEndCap=None,
|
||||
plus=None,
|
||||
minus=None,
|
||||
val=None,
|
||||
spPr=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.errDir = errDir
|
||||
self.errBarType = errBarType
|
||||
self.errValType = errValType
|
||||
self.noEndCap = noEndCap
|
||||
self.plus = plus
|
||||
self.minus = minus
|
||||
self.val = val
|
||||
self.spPr = spPr
|
127
lib/python3.13/site-packages/openpyxl/chart/label.py
Normal file
127
lib/python3.13/site-packages/openpyxl/chart/label.py
Normal file
@ -0,0 +1,127 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Sequence,
|
||||
Alias,
|
||||
Typed
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedNoneSet,
|
||||
NestedBool,
|
||||
NestedString,
|
||||
NestedInteger,
|
||||
)
|
||||
|
||||
from .shapes import GraphicalProperties
|
||||
from .text import RichText
|
||||
|
||||
|
||||
class _DataLabelBase(Serialisable):
|
||||
|
||||
numFmt = NestedString(allow_none=True, attribute="formatCode")
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
txPr = Typed(expected_type=RichText, allow_none=True)
|
||||
textProperties = Alias('txPr')
|
||||
dLblPos = NestedNoneSet(values=['bestFit', 'b', 'ctr', 'inBase', 'inEnd',
|
||||
'l', 'outEnd', 'r', 't'])
|
||||
position = Alias('dLblPos')
|
||||
showLegendKey = NestedBool(allow_none=True)
|
||||
showVal = NestedBool(allow_none=True)
|
||||
showCatName = NestedBool(allow_none=True)
|
||||
showSerName = NestedBool(allow_none=True)
|
||||
showPercent = NestedBool(allow_none=True)
|
||||
showBubbleSize = NestedBool(allow_none=True)
|
||||
showLeaderLines = NestedBool(allow_none=True)
|
||||
separator = NestedString(allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ("numFmt", "spPr", "txPr", "dLblPos", "showLegendKey",
|
||||
"showVal", "showCatName", "showSerName", "showPercent", "showBubbleSize",
|
||||
"showLeaderLines", "separator")
|
||||
|
||||
def __init__(self,
|
||||
numFmt=None,
|
||||
spPr=None,
|
||||
txPr=None,
|
||||
dLblPos=None,
|
||||
showLegendKey=None,
|
||||
showVal=None,
|
||||
showCatName=None,
|
||||
showSerName=None,
|
||||
showPercent=None,
|
||||
showBubbleSize=None,
|
||||
showLeaderLines=None,
|
||||
separator=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.numFmt = numFmt
|
||||
self.spPr = spPr
|
||||
self.txPr = txPr
|
||||
self.dLblPos = dLblPos
|
||||
self.showLegendKey = showLegendKey
|
||||
self.showVal = showVal
|
||||
self.showCatName = showCatName
|
||||
self.showSerName = showSerName
|
||||
self.showPercent = showPercent
|
||||
self.showBubbleSize = showBubbleSize
|
||||
self.showLeaderLines = showLeaderLines
|
||||
self.separator = separator
|
||||
|
||||
|
||||
class DataLabel(_DataLabelBase):
|
||||
|
||||
tagname = "dLbl"
|
||||
|
||||
idx = NestedInteger()
|
||||
|
||||
numFmt = _DataLabelBase.numFmt
|
||||
spPr = _DataLabelBase.spPr
|
||||
txPr = _DataLabelBase.txPr
|
||||
dLblPos = _DataLabelBase.dLblPos
|
||||
showLegendKey = _DataLabelBase.showLegendKey
|
||||
showVal = _DataLabelBase.showVal
|
||||
showCatName = _DataLabelBase.showCatName
|
||||
showSerName = _DataLabelBase.showSerName
|
||||
showPercent = _DataLabelBase.showPercent
|
||||
showBubbleSize = _DataLabelBase.showBubbleSize
|
||||
showLeaderLines = _DataLabelBase.showLeaderLines
|
||||
separator = _DataLabelBase.separator
|
||||
extLst = _DataLabelBase.extLst
|
||||
|
||||
__elements__ = ("idx",) + _DataLabelBase.__elements__
|
||||
|
||||
def __init__(self, idx=0, **kw ):
|
||||
self.idx = idx
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class DataLabelList(_DataLabelBase):
|
||||
|
||||
tagname = "dLbls"
|
||||
|
||||
dLbl = Sequence(expected_type=DataLabel, allow_none=True)
|
||||
|
||||
delete = NestedBool(allow_none=True)
|
||||
numFmt = _DataLabelBase.numFmt
|
||||
spPr = _DataLabelBase.spPr
|
||||
txPr = _DataLabelBase.txPr
|
||||
dLblPos = _DataLabelBase.dLblPos
|
||||
showLegendKey = _DataLabelBase.showLegendKey
|
||||
showVal = _DataLabelBase.showVal
|
||||
showCatName = _DataLabelBase.showCatName
|
||||
showSerName = _DataLabelBase.showSerName
|
||||
showPercent = _DataLabelBase.showPercent
|
||||
showBubbleSize = _DataLabelBase.showBubbleSize
|
||||
showLeaderLines = _DataLabelBase.showLeaderLines
|
||||
separator = _DataLabelBase.separator
|
||||
extLst = _DataLabelBase.extLst
|
||||
|
||||
__elements__ = ("delete", "dLbl",) + _DataLabelBase.__elements__
|
||||
|
||||
def __init__(self, dLbl=(), delete=None, **kw):
|
||||
self.dLbl = dLbl
|
||||
self.delete = delete
|
||||
super().__init__(**kw)
|
74
lib/python3.13/site-packages/openpyxl/chart/layout.py
Normal file
74
lib/python3.13/site-packages/openpyxl/chart/layout.py
Normal file
@ -0,0 +1,74 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
NoneSet,
|
||||
Float,
|
||||
Typed,
|
||||
Alias,
|
||||
)
|
||||
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedNoneSet,
|
||||
NestedSet,
|
||||
NestedMinMax,
|
||||
)
|
||||
|
||||
class ManualLayout(Serialisable):
|
||||
|
||||
tagname = "manualLayout"
|
||||
|
||||
layoutTarget = NestedNoneSet(values=(['inner', 'outer']))
|
||||
xMode = NestedNoneSet(values=(['edge', 'factor']))
|
||||
yMode = NestedNoneSet(values=(['edge', 'factor']))
|
||||
wMode = NestedSet(values=(['edge', 'factor']))
|
||||
hMode = NestedSet(values=(['edge', 'factor']))
|
||||
x = NestedMinMax(min=-1, max=1, allow_none=True)
|
||||
y = NestedMinMax(min=-1, max=1, allow_none=True)
|
||||
w = NestedMinMax(min=0, max=1, allow_none=True)
|
||||
width = Alias('w')
|
||||
h = NestedMinMax(min=0, max=1, allow_none=True)
|
||||
height = Alias('h')
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('layoutTarget', 'xMode', 'yMode', 'wMode', 'hMode', 'x',
|
||||
'y', 'w', 'h')
|
||||
|
||||
def __init__(self,
|
||||
layoutTarget=None,
|
||||
xMode=None,
|
||||
yMode=None,
|
||||
wMode="factor",
|
||||
hMode="factor",
|
||||
x=None,
|
||||
y=None,
|
||||
w=None,
|
||||
h=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.layoutTarget = layoutTarget
|
||||
self.xMode = xMode
|
||||
self.yMode = yMode
|
||||
self.wMode = wMode
|
||||
self.hMode = hMode
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.w = w
|
||||
self.h = h
|
||||
|
||||
|
||||
class Layout(Serialisable):
|
||||
|
||||
tagname = "layout"
|
||||
|
||||
manualLayout = Typed(expected_type=ManualLayout, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('manualLayout',)
|
||||
|
||||
def __init__(self,
|
||||
manualLayout=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.manualLayout = manualLayout
|
75
lib/python3.13/site-packages/openpyxl/chart/legend.py
Normal file
75
lib/python3.13/site-packages/openpyxl/chart/legend.py
Normal file
@ -0,0 +1,75 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Integer,
|
||||
Alias,
|
||||
Sequence,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedBool,
|
||||
NestedSet,
|
||||
NestedInteger
|
||||
)
|
||||
|
||||
from .layout import Layout
|
||||
from .shapes import GraphicalProperties
|
||||
from .text import RichText
|
||||
|
||||
|
||||
class LegendEntry(Serialisable):
|
||||
|
||||
tagname = "legendEntry"
|
||||
|
||||
idx = NestedInteger()
|
||||
delete = NestedBool()
|
||||
txPr = Typed(expected_type=RichText, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('idx', 'delete', 'txPr')
|
||||
|
||||
def __init__(self,
|
||||
idx=0,
|
||||
delete=False,
|
||||
txPr=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.idx = idx
|
||||
self.delete = delete
|
||||
self.txPr = txPr
|
||||
|
||||
|
||||
class Legend(Serialisable):
|
||||
|
||||
tagname = "legend"
|
||||
|
||||
legendPos = NestedSet(values=(['b', 'tr', 'l', 'r', 't']))
|
||||
position = Alias('legendPos')
|
||||
legendEntry = Sequence(expected_type=LegendEntry)
|
||||
layout = Typed(expected_type=Layout, allow_none=True)
|
||||
overlay = NestedBool(allow_none=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
txPr = Typed(expected_type=RichText, allow_none=True)
|
||||
textProperties = Alias('txPr')
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('legendPos', 'legendEntry', 'layout', 'overlay', 'spPr', 'txPr',)
|
||||
|
||||
def __init__(self,
|
||||
legendPos="r",
|
||||
legendEntry=(),
|
||||
layout=None,
|
||||
overlay=None,
|
||||
spPr=None,
|
||||
txPr=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.legendPos = legendPos
|
||||
self.legendEntry = legendEntry
|
||||
self.layout = layout
|
||||
self.overlay = overlay
|
||||
self.spPr = spPr
|
||||
self.txPr = txPr
|
129
lib/python3.13/site-packages/openpyxl/chart/line_chart.py
Normal file
129
lib/python3.13/site-packages/openpyxl/chart/line_chart.py
Normal file
@ -0,0 +1,129 @@
|
||||
#Autogenerated schema
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Sequence,
|
||||
Alias,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedSet,
|
||||
NestedBool,
|
||||
)
|
||||
|
||||
from ._chart import ChartBase
|
||||
from .updown_bars import UpDownBars
|
||||
from .descriptors import NestedGapAmount
|
||||
from .axis import TextAxis, NumericAxis, SeriesAxis, ChartLines, _BaseAxis
|
||||
from .label import DataLabelList
|
||||
from .series import Series
|
||||
|
||||
|
||||
class _LineChartBase(ChartBase):
|
||||
|
||||
grouping = NestedSet(values=(['percentStacked', 'standard', 'stacked']))
|
||||
varyColors = NestedBool(allow_none=True)
|
||||
ser = Sequence(expected_type=Series, allow_none=True)
|
||||
dLbls = Typed(expected_type=DataLabelList, allow_none=True)
|
||||
dataLabels = Alias("dLbls")
|
||||
dropLines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
|
||||
_series_type = "line"
|
||||
|
||||
__elements__ = ('grouping', 'varyColors', 'ser', 'dLbls', 'dropLines')
|
||||
|
||||
def __init__(self,
|
||||
grouping="standard",
|
||||
varyColors=None,
|
||||
ser=(),
|
||||
dLbls=None,
|
||||
dropLines=None,
|
||||
**kw
|
||||
):
|
||||
self.grouping = grouping
|
||||
self.varyColors = varyColors
|
||||
self.ser = ser
|
||||
self.dLbls = dLbls
|
||||
self.dropLines = dropLines
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class LineChart(_LineChartBase):
|
||||
|
||||
tagname = "lineChart"
|
||||
|
||||
grouping = _LineChartBase.grouping
|
||||
varyColors = _LineChartBase.varyColors
|
||||
ser = _LineChartBase.ser
|
||||
dLbls = _LineChartBase.dLbls
|
||||
dropLines =_LineChartBase.dropLines
|
||||
|
||||
hiLowLines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
upDownBars = Typed(expected_type=UpDownBars, allow_none=True)
|
||||
marker = NestedBool(allow_none=True)
|
||||
smooth = NestedBool(allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
x_axis = Typed(expected_type=_BaseAxis)
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
|
||||
__elements__ = _LineChartBase.__elements__ + ('hiLowLines', 'upDownBars', 'marker', 'smooth', 'axId')
|
||||
|
||||
def __init__(self,
|
||||
hiLowLines=None,
|
||||
upDownBars=None,
|
||||
marker=None,
|
||||
smooth=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.hiLowLines = hiLowLines
|
||||
self.upDownBars = upDownBars
|
||||
self.marker = marker
|
||||
self.smooth = smooth
|
||||
self.x_axis = TextAxis()
|
||||
self.y_axis = NumericAxis()
|
||||
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class LineChart3D(_LineChartBase):
|
||||
|
||||
tagname = "line3DChart"
|
||||
|
||||
grouping = _LineChartBase.grouping
|
||||
varyColors = _LineChartBase.varyColors
|
||||
ser = _LineChartBase.ser
|
||||
dLbls = _LineChartBase.dLbls
|
||||
dropLines =_LineChartBase.dropLines
|
||||
|
||||
gapDepth = NestedGapAmount()
|
||||
hiLowLines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
upDownBars = Typed(expected_type=UpDownBars, allow_none=True)
|
||||
marker = NestedBool(allow_none=True)
|
||||
smooth = NestedBool(allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
x_axis = Typed(expected_type=TextAxis)
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
z_axis = Typed(expected_type=SeriesAxis)
|
||||
|
||||
__elements__ = _LineChartBase.__elements__ + ('gapDepth', 'hiLowLines',
|
||||
'upDownBars', 'marker', 'smooth', 'axId')
|
||||
|
||||
def __init__(self,
|
||||
gapDepth=None,
|
||||
hiLowLines=None,
|
||||
upDownBars=None,
|
||||
marker=None,
|
||||
smooth=None,
|
||||
**kw
|
||||
):
|
||||
self.gapDepth = gapDepth
|
||||
self.hiLowLines = hiLowLines
|
||||
self.upDownBars = upDownBars
|
||||
self.marker = marker
|
||||
self.smooth = smooth
|
||||
self.x_axis = TextAxis()
|
||||
self.y_axis = NumericAxis()
|
||||
self.z_axis = SeriesAxis()
|
||||
super(LineChart3D, self).__init__(**kw)
|
90
lib/python3.13/site-packages/openpyxl/chart/marker.py
Normal file
90
lib/python3.13/site-packages/openpyxl/chart/marker.py
Normal file
@ -0,0 +1,90 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Alias,
|
||||
)
|
||||
|
||||
from openpyxl.descriptors.excel import(
|
||||
ExtensionList,
|
||||
_explicit_none,
|
||||
)
|
||||
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedBool,
|
||||
NestedInteger,
|
||||
NestedMinMax,
|
||||
NestedNoneSet,
|
||||
)
|
||||
|
||||
from .layout import Layout
|
||||
from .picture import PictureOptions
|
||||
from .shapes import *
|
||||
from .text import *
|
||||
from .error_bar import *
|
||||
|
||||
|
||||
class Marker(Serialisable):
|
||||
|
||||
tagname = "marker"
|
||||
|
||||
symbol = NestedNoneSet(values=(['circle', 'dash', 'diamond', 'dot', 'picture',
|
||||
'plus', 'square', 'star', 'triangle', 'x', 'auto']),
|
||||
to_tree=_explicit_none)
|
||||
size = NestedMinMax(min=2, max=72, allow_none=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('symbol', 'size', 'spPr')
|
||||
|
||||
def __init__(self,
|
||||
symbol=None,
|
||||
size=None,
|
||||
spPr=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.symbol = symbol
|
||||
self.size = size
|
||||
if spPr is None:
|
||||
spPr = GraphicalProperties()
|
||||
self.spPr = spPr
|
||||
|
||||
|
||||
class DataPoint(Serialisable):
|
||||
|
||||
tagname = "dPt"
|
||||
|
||||
idx = NestedInteger()
|
||||
invertIfNegative = NestedBool(allow_none=True)
|
||||
marker = Typed(expected_type=Marker, allow_none=True)
|
||||
bubble3D = NestedBool(allow_none=True)
|
||||
explosion = NestedInteger(allow_none=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
pictureOptions = Typed(expected_type=PictureOptions, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('idx', 'invertIfNegative', 'marker', 'bubble3D',
|
||||
'explosion', 'spPr', 'pictureOptions')
|
||||
|
||||
def __init__(self,
|
||||
idx=None,
|
||||
invertIfNegative=None,
|
||||
marker=None,
|
||||
bubble3D=None,
|
||||
explosion=None,
|
||||
spPr=None,
|
||||
pictureOptions=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.idx = idx
|
||||
self.invertIfNegative = invertIfNegative
|
||||
self.marker = marker
|
||||
self.bubble3D = bubble3D
|
||||
self.explosion = explosion
|
||||
if spPr is None:
|
||||
spPr = GraphicalProperties()
|
||||
self.spPr = spPr
|
||||
self.pictureOptions = pictureOptions
|
35
lib/python3.13/site-packages/openpyxl/chart/picture.py
Normal file
35
lib/python3.13/site-packages/openpyxl/chart/picture.py
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedBool,
|
||||
NestedFloat,
|
||||
NestedMinMax,
|
||||
NestedNoneSet,
|
||||
)
|
||||
|
||||
class PictureOptions(Serialisable):
|
||||
|
||||
tagname = "pictureOptions"
|
||||
|
||||
applyToFront = NestedBool(allow_none=True, nested=True)
|
||||
applyToSides = NestedBool(allow_none=True, nested=True)
|
||||
applyToEnd = NestedBool(allow_none=True, nested=True)
|
||||
pictureFormat = NestedNoneSet(values=(['stretch', 'stack', 'stackScale']), nested=True)
|
||||
pictureStackUnit = NestedFloat(allow_none=True, nested=True)
|
||||
|
||||
__elements__ = ('applyToFront', 'applyToSides', 'applyToEnd', 'pictureFormat', 'pictureStackUnit')
|
||||
|
||||
def __init__(self,
|
||||
applyToFront=None,
|
||||
applyToSides=None,
|
||||
applyToEnd=None,
|
||||
pictureFormat=None,
|
||||
pictureStackUnit=None,
|
||||
):
|
||||
self.applyToFront = applyToFront
|
||||
self.applyToSides = applyToSides
|
||||
self.applyToEnd = applyToEnd
|
||||
self.pictureFormat = pictureFormat
|
||||
self.pictureStackUnit = pictureStackUnit
|
177
lib/python3.13/site-packages/openpyxl/chart/pie_chart.py
Normal file
177
lib/python3.13/site-packages/openpyxl/chart/pie_chart.py
Normal file
@ -0,0 +1,177 @@
|
||||
#Autogenerated schema
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Bool,
|
||||
MinMax,
|
||||
Integer,
|
||||
NoneSet,
|
||||
Float,
|
||||
Alias,
|
||||
Sequence,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList, Percentage
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedBool,
|
||||
NestedMinMax,
|
||||
NestedInteger,
|
||||
NestedFloat,
|
||||
NestedNoneSet,
|
||||
NestedSet,
|
||||
)
|
||||
from openpyxl.descriptors.sequence import ValueSequence
|
||||
|
||||
from ._chart import ChartBase
|
||||
from .axis import ChartLines
|
||||
from .descriptors import NestedGapAmount
|
||||
from .series import Series
|
||||
from .label import DataLabelList
|
||||
|
||||
|
||||
class _PieChartBase(ChartBase):
|
||||
|
||||
varyColors = NestedBool(allow_none=True)
|
||||
ser = Sequence(expected_type=Series, allow_none=True)
|
||||
dLbls = Typed(expected_type=DataLabelList, allow_none=True)
|
||||
dataLabels = Alias("dLbls")
|
||||
|
||||
_series_type = "pie"
|
||||
|
||||
__elements__ = ('varyColors', 'ser', 'dLbls')
|
||||
|
||||
def __init__(self,
|
||||
varyColors=True,
|
||||
ser=(),
|
||||
dLbls=None,
|
||||
):
|
||||
self.varyColors = varyColors
|
||||
self.ser = ser
|
||||
self.dLbls = dLbls
|
||||
super().__init__()
|
||||
|
||||
|
||||
|
||||
class PieChart(_PieChartBase):
|
||||
|
||||
tagname = "pieChart"
|
||||
|
||||
varyColors = _PieChartBase.varyColors
|
||||
ser = _PieChartBase.ser
|
||||
dLbls = _PieChartBase.dLbls
|
||||
|
||||
firstSliceAng = NestedMinMax(min=0, max=360)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = _PieChartBase.__elements__ + ('firstSliceAng', )
|
||||
|
||||
def __init__(self,
|
||||
firstSliceAng=0,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.firstSliceAng = firstSliceAng
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class PieChart3D(_PieChartBase):
|
||||
|
||||
tagname = "pie3DChart"
|
||||
|
||||
varyColors = _PieChartBase.varyColors
|
||||
ser = _PieChartBase.ser
|
||||
dLbls = _PieChartBase.dLbls
|
||||
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = _PieChartBase.__elements__
|
||||
|
||||
|
||||
class DoughnutChart(_PieChartBase):
|
||||
|
||||
tagname = "doughnutChart"
|
||||
|
||||
varyColors = _PieChartBase.varyColors
|
||||
ser = _PieChartBase.ser
|
||||
dLbls = _PieChartBase.dLbls
|
||||
|
||||
firstSliceAng = NestedMinMax(min=0, max=360)
|
||||
holeSize = NestedMinMax(min=1, max=90, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = _PieChartBase.__elements__ + ('firstSliceAng', 'holeSize')
|
||||
|
||||
def __init__(self,
|
||||
firstSliceAng=0,
|
||||
holeSize=10,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.firstSliceAng = firstSliceAng
|
||||
self.holeSize = holeSize
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class CustomSplit(Serialisable):
|
||||
|
||||
tagname = "custSplit"
|
||||
|
||||
secondPiePt = ValueSequence(expected_type=int)
|
||||
|
||||
__elements__ = ('secondPiePt',)
|
||||
|
||||
def __init__(self,
|
||||
secondPiePt=(),
|
||||
):
|
||||
self.secondPiePt = secondPiePt
|
||||
|
||||
|
||||
class ProjectedPieChart(_PieChartBase):
|
||||
|
||||
"""
|
||||
From the spec 21.2.2.126
|
||||
|
||||
This element contains the pie of pie or bar of pie series on this
|
||||
chart. Only the first series shall be displayed. The splitType element
|
||||
shall determine whether the splitPos and custSplit elements apply.
|
||||
"""
|
||||
|
||||
tagname = "ofPieChart"
|
||||
|
||||
varyColors = _PieChartBase.varyColors
|
||||
ser = _PieChartBase.ser
|
||||
dLbls = _PieChartBase.dLbls
|
||||
|
||||
ofPieType = NestedSet(values=(['pie', 'bar']))
|
||||
type = Alias('ofPieType')
|
||||
gapWidth = NestedGapAmount()
|
||||
splitType = NestedNoneSet(values=(['auto', 'cust', 'percent', 'pos', 'val']))
|
||||
splitPos = NestedFloat(allow_none=True)
|
||||
custSplit = Typed(expected_type=CustomSplit, allow_none=True)
|
||||
secondPieSize = NestedMinMax(min=5, max=200, allow_none=True)
|
||||
serLines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
join_lines = Alias('serLines')
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = _PieChartBase.__elements__ + ('ofPieType', 'gapWidth',
|
||||
'splitType', 'splitPos', 'custSplit', 'secondPieSize', 'serLines')
|
||||
|
||||
def __init__(self,
|
||||
ofPieType="pie",
|
||||
gapWidth=None,
|
||||
splitType="auto",
|
||||
splitPos=None,
|
||||
custSplit=None,
|
||||
secondPieSize=75,
|
||||
serLines=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.ofPieType = ofPieType
|
||||
self.gapWidth = gapWidth
|
||||
self.splitType = splitType
|
||||
self.splitPos = splitPos
|
||||
self.custSplit = custSplit
|
||||
self.secondPieSize = secondPieSize
|
||||
if serLines is None:
|
||||
self.serLines = ChartLines()
|
||||
super().__init__(**kw)
|
65
lib/python3.13/site-packages/openpyxl/chart/pivot.py
Normal file
65
lib/python3.13/site-packages/openpyxl/chart/pivot.py
Normal file
@ -0,0 +1,65 @@
|
||||
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Alias,
|
||||
Typed,
|
||||
)
|
||||
from openpyxl.descriptors.nested import NestedInteger, NestedText
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
|
||||
from .label import DataLabel
|
||||
from .marker import Marker
|
||||
from .shapes import GraphicalProperties
|
||||
from .text import RichText
|
||||
|
||||
|
||||
class PivotSource(Serialisable):
|
||||
|
||||
tagname = "pivotSource"
|
||||
|
||||
name = NestedText(expected_type=str)
|
||||
fmtId = NestedInteger(expected_type=int)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('name', 'fmtId')
|
||||
|
||||
def __init__(self,
|
||||
name=None,
|
||||
fmtId=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.name = name
|
||||
self.fmtId = fmtId
|
||||
|
||||
|
||||
class PivotFormat(Serialisable):
|
||||
|
||||
tagname = "pivotFmt"
|
||||
|
||||
idx = NestedInteger(nested=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias("spPr")
|
||||
txPr = Typed(expected_type=RichText, allow_none=True)
|
||||
TextBody = Alias("txPr")
|
||||
marker = Typed(expected_type=Marker, allow_none=True)
|
||||
dLbl = Typed(expected_type=DataLabel, allow_none=True)
|
||||
DataLabel = Alias("dLbl")
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('idx', 'spPr', 'txPr', 'marker', 'dLbl')
|
||||
|
||||
def __init__(self,
|
||||
idx=0,
|
||||
spPr=None,
|
||||
txPr=None,
|
||||
marker=None,
|
||||
dLbl=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.idx = idx
|
||||
self.spPr = spPr
|
||||
self.txPr = txPr
|
||||
self.marker = marker
|
||||
self.dLbl = dLbl
|
162
lib/python3.13/site-packages/openpyxl/chart/plotarea.py
Normal file
162
lib/python3.13/site-packages/openpyxl/chart/plotarea.py
Normal file
@ -0,0 +1,162 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Alias,
|
||||
)
|
||||
from openpyxl.descriptors.excel import (
|
||||
ExtensionList,
|
||||
)
|
||||
from openpyxl.descriptors.sequence import (
|
||||
MultiSequence,
|
||||
MultiSequencePart,
|
||||
)
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedBool,
|
||||
)
|
||||
|
||||
from ._3d import _3DBase
|
||||
from .area_chart import AreaChart, AreaChart3D
|
||||
from .bar_chart import BarChart, BarChart3D
|
||||
from .bubble_chart import BubbleChart
|
||||
from .line_chart import LineChart, LineChart3D
|
||||
from .pie_chart import PieChart, PieChart3D, ProjectedPieChart, DoughnutChart
|
||||
from .radar_chart import RadarChart
|
||||
from .scatter_chart import ScatterChart
|
||||
from .stock_chart import StockChart
|
||||
from .surface_chart import SurfaceChart, SurfaceChart3D
|
||||
from .layout import Layout
|
||||
from .shapes import GraphicalProperties
|
||||
from .text import RichText
|
||||
|
||||
from .axis import (
|
||||
NumericAxis,
|
||||
TextAxis,
|
||||
SeriesAxis,
|
||||
DateAxis,
|
||||
)
|
||||
|
||||
|
||||
class DataTable(Serialisable):
|
||||
|
||||
tagname = "dTable"
|
||||
|
||||
showHorzBorder = NestedBool(allow_none=True)
|
||||
showVertBorder = NestedBool(allow_none=True)
|
||||
showOutline = NestedBool(allow_none=True)
|
||||
showKeys = NestedBool(allow_none=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
txPr = Typed(expected_type=RichText, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('showHorzBorder', 'showVertBorder', 'showOutline',
|
||||
'showKeys', 'spPr', 'txPr')
|
||||
|
||||
def __init__(self,
|
||||
showHorzBorder=None,
|
||||
showVertBorder=None,
|
||||
showOutline=None,
|
||||
showKeys=None,
|
||||
spPr=None,
|
||||
txPr=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.showHorzBorder = showHorzBorder
|
||||
self.showVertBorder = showVertBorder
|
||||
self.showOutline = showOutline
|
||||
self.showKeys = showKeys
|
||||
self.spPr = spPr
|
||||
self.txPr = txPr
|
||||
|
||||
|
||||
class PlotArea(Serialisable):
|
||||
|
||||
tagname = "plotArea"
|
||||
|
||||
layout = Typed(expected_type=Layout, allow_none=True)
|
||||
dTable = Typed(expected_type=DataTable, allow_none=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias("spPr")
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
# at least one chart
|
||||
_charts = MultiSequence()
|
||||
areaChart = MultiSequencePart(expected_type=AreaChart, store="_charts")
|
||||
area3DChart = MultiSequencePart(expected_type=AreaChart3D, store="_charts")
|
||||
lineChart = MultiSequencePart(expected_type=LineChart, store="_charts")
|
||||
line3DChart = MultiSequencePart(expected_type=LineChart3D, store="_charts")
|
||||
stockChart = MultiSequencePart(expected_type=StockChart, store="_charts")
|
||||
radarChart = MultiSequencePart(expected_type=RadarChart, store="_charts")
|
||||
scatterChart = MultiSequencePart(expected_type=ScatterChart, store="_charts")
|
||||
pieChart = MultiSequencePart(expected_type=PieChart, store="_charts")
|
||||
pie3DChart = MultiSequencePart(expected_type=PieChart3D, store="_charts")
|
||||
doughnutChart = MultiSequencePart(expected_type=DoughnutChart, store="_charts")
|
||||
barChart = MultiSequencePart(expected_type=BarChart, store="_charts")
|
||||
bar3DChart = MultiSequencePart(expected_type=BarChart3D, store="_charts")
|
||||
ofPieChart = MultiSequencePart(expected_type=ProjectedPieChart, store="_charts")
|
||||
surfaceChart = MultiSequencePart(expected_type=SurfaceChart, store="_charts")
|
||||
surface3DChart = MultiSequencePart(expected_type=SurfaceChart3D, store="_charts")
|
||||
bubbleChart = MultiSequencePart(expected_type=BubbleChart, store="_charts")
|
||||
|
||||
# axes
|
||||
_axes = MultiSequence()
|
||||
valAx = MultiSequencePart(expected_type=NumericAxis, store="_axes")
|
||||
catAx = MultiSequencePart(expected_type=TextAxis, store="_axes")
|
||||
dateAx = MultiSequencePart(expected_type=DateAxis, store="_axes")
|
||||
serAx = MultiSequencePart(expected_type=SeriesAxis, store="_axes")
|
||||
|
||||
__elements__ = ('layout', '_charts', '_axes', 'dTable', 'spPr')
|
||||
|
||||
def __init__(self,
|
||||
layout=None,
|
||||
dTable=None,
|
||||
spPr=None,
|
||||
_charts=(),
|
||||
_axes=(),
|
||||
extLst=None,
|
||||
):
|
||||
self.layout = layout
|
||||
self.dTable = dTable
|
||||
self.spPr = spPr
|
||||
self._charts = _charts
|
||||
self._axes = _axes
|
||||
|
||||
|
||||
def to_tree(self, tagname=None, idx=None, namespace=None):
|
||||
axIds = {ax.axId for ax in self._axes}
|
||||
for chart in self._charts:
|
||||
for id, axis in chart._axes.items():
|
||||
if id not in axIds:
|
||||
setattr(self, axis.tagname, axis)
|
||||
axIds.add(id)
|
||||
|
||||
return super().to_tree(tagname)
|
||||
|
||||
|
||||
@classmethod
|
||||
def from_tree(cls, node):
|
||||
self = super().from_tree(node)
|
||||
axes = dict((axis.axId, axis) for axis in self._axes)
|
||||
for chart in self._charts:
|
||||
if isinstance(chart, (ScatterChart, BubbleChart)):
|
||||
x, y = (axes[axId] for axId in chart.axId)
|
||||
chart.x_axis = x
|
||||
chart.y_axis = y
|
||||
continue
|
||||
|
||||
for axId in chart.axId:
|
||||
axis = axes.get(axId)
|
||||
if axis is None and isinstance(chart, _3DBase):
|
||||
# Series Axis can be optional
|
||||
chart.z_axis = None
|
||||
continue
|
||||
if axis.tagname in ("catAx", "dateAx"):
|
||||
chart.x_axis = axis
|
||||
elif axis.tagname == "valAx":
|
||||
chart.y_axis = axis
|
||||
elif axis.tagname == "serAx":
|
||||
chart.z_axis = axis
|
||||
|
||||
return self
|
@ -0,0 +1,57 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Float,
|
||||
Typed,
|
||||
Alias,
|
||||
)
|
||||
|
||||
from openpyxl.worksheet.page import PrintPageSetup
|
||||
from openpyxl.worksheet.header_footer import HeaderFooter
|
||||
|
||||
|
||||
class PageMargins(Serialisable):
|
||||
"""
|
||||
Identical to openpyxl.worksheet.page.Pagemargins but element names are different :-/
|
||||
"""
|
||||
tagname = "pageMargins"
|
||||
|
||||
l = Float()
|
||||
left = Alias('l')
|
||||
r = Float()
|
||||
right = Alias('r')
|
||||
t = Float()
|
||||
top = Alias('t')
|
||||
b = Float()
|
||||
bottom = Alias('b')
|
||||
header = Float()
|
||||
footer = Float()
|
||||
|
||||
def __init__(self, l=0.75, r=0.75, t=1, b=1, header=0.5, footer=0.5):
|
||||
self.l = l
|
||||
self.r = r
|
||||
self.t = t
|
||||
self.b = b
|
||||
self.header = header
|
||||
self.footer = footer
|
||||
|
||||
|
||||
class PrintSettings(Serialisable):
|
||||
|
||||
tagname = "printSettings"
|
||||
|
||||
headerFooter = Typed(expected_type=HeaderFooter, allow_none=True)
|
||||
pageMargins = Typed(expected_type=PageMargins, allow_none=True)
|
||||
pageSetup = Typed(expected_type=PrintPageSetup, allow_none=True)
|
||||
|
||||
__elements__ = ("headerFooter", "pageMargins", "pageMargins")
|
||||
|
||||
def __init__(self,
|
||||
headerFooter=None,
|
||||
pageMargins=None,
|
||||
pageSetup=None,
|
||||
):
|
||||
self.headerFooter = headerFooter
|
||||
self.pageMargins = pageMargins
|
||||
self.pageSetup = pageSetup
|
55
lib/python3.13/site-packages/openpyxl/chart/radar_chart.py
Normal file
55
lib/python3.13/site-packages/openpyxl/chart/radar_chart.py
Normal file
@ -0,0 +1,55 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Sequence,
|
||||
Typed,
|
||||
Alias,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedBool,
|
||||
NestedInteger,
|
||||
NestedSet
|
||||
)
|
||||
|
||||
from ._chart import ChartBase
|
||||
from .axis import TextAxis, NumericAxis
|
||||
from .series import Series
|
||||
from .label import DataLabelList
|
||||
|
||||
|
||||
class RadarChart(ChartBase):
|
||||
|
||||
tagname = "radarChart"
|
||||
|
||||
radarStyle = NestedSet(values=(['standard', 'marker', 'filled']))
|
||||
type = Alias("radarStyle")
|
||||
varyColors = NestedBool(nested=True, allow_none=True)
|
||||
ser = Sequence(expected_type=Series, allow_none=True)
|
||||
dLbls = Typed(expected_type=DataLabelList, allow_none=True)
|
||||
dataLabels = Alias("dLbls")
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
_series_type = "radar"
|
||||
|
||||
x_axis = Typed(expected_type=TextAxis)
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
|
||||
__elements__ = ('radarStyle', 'varyColors', 'ser', 'dLbls', 'axId')
|
||||
|
||||
def __init__(self,
|
||||
radarStyle="standard",
|
||||
varyColors=None,
|
||||
ser=(),
|
||||
dLbls=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.radarStyle = radarStyle
|
||||
self.varyColors = varyColors
|
||||
self.ser = ser
|
||||
self.dLbls = dLbls
|
||||
self.x_axis = TextAxis()
|
||||
self.y_axis = NumericAxis()
|
||||
super().__init__(**kw)
|
32
lib/python3.13/site-packages/openpyxl/chart/reader.py
Normal file
32
lib/python3.13/site-packages/openpyxl/chart/reader.py
Normal file
@ -0,0 +1,32 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
"""
|
||||
Read a chart
|
||||
"""
|
||||
|
||||
def read_chart(chartspace):
|
||||
cs = chartspace
|
||||
plot = cs.chart.plotArea
|
||||
|
||||
chart = plot._charts[0]
|
||||
chart._charts = plot._charts
|
||||
|
||||
chart.title = cs.chart.title
|
||||
chart.display_blanks = cs.chart.dispBlanksAs
|
||||
chart.visible_cells_only = cs.chart.plotVisOnly
|
||||
chart.layout = plot.layout
|
||||
chart.legend = cs.chart.legend
|
||||
|
||||
# 3d attributes
|
||||
chart.floor = cs.chart.floor
|
||||
chart.sideWall = cs.chart.sideWall
|
||||
chart.backWall = cs.chart.backWall
|
||||
chart.pivotSource = cs.pivotSource
|
||||
chart.pivotFormats = cs.chart.pivotFmts
|
||||
chart.idx_base = min((s.idx for s in chart.series), default=0)
|
||||
chart._reindex()
|
||||
|
||||
# Border, fill, etc.
|
||||
chart.graphical_properties = cs.graphical_properties
|
||||
|
||||
return chart
|
124
lib/python3.13/site-packages/openpyxl/chart/reference.py
Normal file
124
lib/python3.13/site-packages/openpyxl/chart/reference.py
Normal file
@ -0,0 +1,124 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from itertools import chain
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
MinMax,
|
||||
Typed,
|
||||
String,
|
||||
Strict,
|
||||
)
|
||||
from openpyxl.worksheet.worksheet import Worksheet
|
||||
from openpyxl.utils import (
|
||||
get_column_letter,
|
||||
range_to_tuple,
|
||||
quote_sheetname
|
||||
)
|
||||
|
||||
|
||||
class DummyWorksheet:
|
||||
|
||||
|
||||
def __init__(self, title):
|
||||
self.title = title
|
||||
|
||||
|
||||
class Reference(Strict):
|
||||
|
||||
"""
|
||||
Normalise cell range references
|
||||
"""
|
||||
|
||||
min_row = MinMax(min=1, max=1000000, expected_type=int)
|
||||
max_row = MinMax(min=1, max=1000000, expected_type=int)
|
||||
min_col = MinMax(min=1, max=16384, expected_type=int)
|
||||
max_col = MinMax(min=1, max=16384, expected_type=int)
|
||||
range_string = String(allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
worksheet=None,
|
||||
min_col=None,
|
||||
min_row=None,
|
||||
max_col=None,
|
||||
max_row=None,
|
||||
range_string=None
|
||||
):
|
||||
if range_string is not None:
|
||||
sheetname, boundaries = range_to_tuple(range_string)
|
||||
min_col, min_row, max_col, max_row = boundaries
|
||||
worksheet = DummyWorksheet(sheetname)
|
||||
|
||||
self.worksheet = worksheet
|
||||
self.min_col = min_col
|
||||
self.min_row = min_row
|
||||
if max_col is None:
|
||||
max_col = min_col
|
||||
self.max_col = max_col
|
||||
if max_row is None:
|
||||
max_row = min_row
|
||||
self.max_row = max_row
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
fmt = u"{0}!${1}${2}:${3}${4}"
|
||||
if (self.min_col == self.max_col
|
||||
and self.min_row == self.max_row):
|
||||
fmt = u"{0}!${1}${2}"
|
||||
return fmt.format(self.sheetname,
|
||||
get_column_letter(self.min_col), self.min_row,
|
||||
get_column_letter(self.max_col), self.max_row
|
||||
)
|
||||
|
||||
|
||||
__str__ = __str__
|
||||
|
||||
|
||||
|
||||
def __len__(self):
|
||||
if self.min_row == self.max_row:
|
||||
return 1 + self.max_col - self.min_col
|
||||
return 1 + self.max_row - self.min_row
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
return str(self) == str(other)
|
||||
|
||||
|
||||
@property
|
||||
def rows(self):
|
||||
"""
|
||||
Return all rows in the range
|
||||
"""
|
||||
for row in range(self.min_row, self.max_row+1):
|
||||
yield Reference(self.worksheet, self.min_col, row, self.max_col, row)
|
||||
|
||||
|
||||
@property
|
||||
def cols(self):
|
||||
"""
|
||||
Return all columns in the range
|
||||
"""
|
||||
for col in range(self.min_col, self.max_col+1):
|
||||
yield Reference(self.worksheet, col, self.min_row, col, self.max_row)
|
||||
|
||||
|
||||
def pop(self):
|
||||
"""
|
||||
Return and remove the first cell
|
||||
"""
|
||||
cell = "{0}{1}".format(get_column_letter(self.min_col), self.min_row)
|
||||
if self.min_row == self.max_row:
|
||||
self.min_col += 1
|
||||
else:
|
||||
self.min_row += 1
|
||||
return cell
|
||||
|
||||
|
||||
@property
|
||||
def sheetname(self):
|
||||
return quote_sheetname(self.worksheet.title)
|
53
lib/python3.13/site-packages/openpyxl/chart/scatter_chart.py
Normal file
53
lib/python3.13/site-packages/openpyxl/chart/scatter_chart.py
Normal file
@ -0,0 +1,53 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Sequence,
|
||||
Alias
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedNoneSet,
|
||||
NestedBool,
|
||||
)
|
||||
|
||||
from ._chart import ChartBase
|
||||
from .axis import NumericAxis, TextAxis
|
||||
from .series import XYSeries
|
||||
from .label import DataLabelList
|
||||
|
||||
|
||||
class ScatterChart(ChartBase):
|
||||
|
||||
tagname = "scatterChart"
|
||||
|
||||
scatterStyle = NestedNoneSet(values=(['line', 'lineMarker', 'marker', 'smooth', 'smoothMarker']))
|
||||
varyColors = NestedBool(allow_none=True)
|
||||
ser = Sequence(expected_type=XYSeries, allow_none=True)
|
||||
dLbls = Typed(expected_type=DataLabelList, allow_none=True)
|
||||
dataLabels = Alias("dLbls")
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
x_axis = Typed(expected_type=(NumericAxis, TextAxis))
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
|
||||
_series_type = "scatter"
|
||||
|
||||
__elements__ = ('scatterStyle', 'varyColors', 'ser', 'dLbls', 'axId',)
|
||||
|
||||
def __init__(self,
|
||||
scatterStyle=None,
|
||||
varyColors=None,
|
||||
ser=(),
|
||||
dLbls=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.scatterStyle = scatterStyle
|
||||
self.varyColors = varyColors
|
||||
self.ser = ser
|
||||
self.dLbls = dLbls
|
||||
self.x_axis = NumericAxis(axId=10, crossAx=20)
|
||||
self.y_axis = NumericAxis(axId=20, crossAx=10)
|
||||
super().__init__(**kw)
|
197
lib/python3.13/site-packages/openpyxl/chart/series.py
Normal file
197
lib/python3.13/site-packages/openpyxl/chart/series.py
Normal file
@ -0,0 +1,197 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
String,
|
||||
Integer,
|
||||
Bool,
|
||||
Alias,
|
||||
Sequence,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedInteger,
|
||||
NestedBool,
|
||||
NestedNoneSet,
|
||||
NestedText,
|
||||
)
|
||||
|
||||
from .shapes import GraphicalProperties
|
||||
from .data_source import (
|
||||
AxDataSource,
|
||||
NumDataSource,
|
||||
NumRef,
|
||||
StrRef,
|
||||
)
|
||||
from .error_bar import ErrorBars
|
||||
from .label import DataLabelList
|
||||
from .marker import DataPoint, PictureOptions, Marker
|
||||
from .trendline import Trendline
|
||||
|
||||
attribute_mapping = {
|
||||
'area': ('idx', 'order', 'tx', 'spPr', 'pictureOptions', 'dPt', 'dLbls', 'errBars',
|
||||
'trendline', 'cat', 'val',),
|
||||
'bar':('idx', 'order','tx', 'spPr', 'invertIfNegative', 'pictureOptions', 'dPt',
|
||||
'dLbls', 'trendline', 'errBars', 'cat', 'val', 'shape'),
|
||||
'bubble':('idx','order', 'tx', 'spPr', 'invertIfNegative', 'dPt', 'dLbls',
|
||||
'trendline', 'errBars', 'xVal', 'yVal', 'bubbleSize', 'bubble3D'),
|
||||
'line':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'trendline',
|
||||
'errBars', 'cat', 'val', 'smooth'),
|
||||
'pie':('idx', 'order', 'tx', 'spPr', 'explosion', 'dPt', 'dLbls', 'cat', 'val'),
|
||||
'radar':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'cat', 'val'),
|
||||
'scatter':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'trendline',
|
||||
'errBars', 'xVal', 'yVal', 'smooth'),
|
||||
'surface':('idx', 'order', 'tx', 'spPr', 'cat', 'val'),
|
||||
}
|
||||
|
||||
|
||||
class SeriesLabel(Serialisable):
|
||||
|
||||
tagname = "tx"
|
||||
|
||||
strRef = Typed(expected_type=StrRef, allow_none=True)
|
||||
v = NestedText(expected_type=str, allow_none=True)
|
||||
value = Alias('v')
|
||||
|
||||
__elements__ = ('strRef', 'v')
|
||||
|
||||
def __init__(self,
|
||||
strRef=None,
|
||||
v=None):
|
||||
self.strRef = strRef
|
||||
self.v = v
|
||||
|
||||
|
||||
class Series(Serialisable):
|
||||
|
||||
"""
|
||||
Generic series object. Should not be instantiated directly.
|
||||
User the chart.Series factory instead.
|
||||
"""
|
||||
|
||||
tagname = "ser"
|
||||
|
||||
idx = NestedInteger()
|
||||
order = NestedInteger()
|
||||
tx = Typed(expected_type=SeriesLabel, allow_none=True)
|
||||
title = Alias('tx')
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
|
||||
# area chart
|
||||
pictureOptions = Typed(expected_type=PictureOptions, allow_none=True)
|
||||
dPt = Sequence(expected_type=DataPoint, allow_none=True)
|
||||
data_points = Alias("dPt")
|
||||
dLbls = Typed(expected_type=DataLabelList, allow_none=True)
|
||||
labels = Alias("dLbls")
|
||||
trendline = Typed(expected_type=Trendline, allow_none=True)
|
||||
errBars = Typed(expected_type=ErrorBars, allow_none=True)
|
||||
cat = Typed(expected_type=AxDataSource, allow_none=True)
|
||||
identifiers = Alias("cat")
|
||||
val = Typed(expected_type=NumDataSource, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
#bar chart
|
||||
invertIfNegative = NestedBool(allow_none=True)
|
||||
shape = NestedNoneSet(values=(['cone', 'coneToMax', 'box', 'cylinder', 'pyramid', 'pyramidToMax']))
|
||||
|
||||
#bubble chart
|
||||
xVal = Typed(expected_type=AxDataSource, allow_none=True)
|
||||
yVal = Typed(expected_type=NumDataSource, allow_none=True)
|
||||
bubbleSize = Typed(expected_type=NumDataSource, allow_none=True)
|
||||
zVal = Alias("bubbleSize")
|
||||
bubble3D = NestedBool(allow_none=True)
|
||||
|
||||
#line chart
|
||||
marker = Typed(expected_type=Marker, allow_none=True)
|
||||
smooth = NestedBool(allow_none=True)
|
||||
|
||||
#pie chart
|
||||
explosion = NestedInteger(allow_none=True)
|
||||
|
||||
__elements__ = ()
|
||||
|
||||
|
||||
def __init__(self,
|
||||
idx=0,
|
||||
order=0,
|
||||
tx=None,
|
||||
spPr=None,
|
||||
pictureOptions=None,
|
||||
dPt=(),
|
||||
dLbls=None,
|
||||
trendline=None,
|
||||
errBars=None,
|
||||
cat=None,
|
||||
val=None,
|
||||
invertIfNegative=None,
|
||||
shape=None,
|
||||
xVal=None,
|
||||
yVal=None,
|
||||
bubbleSize=None,
|
||||
bubble3D=None,
|
||||
marker=None,
|
||||
smooth=None,
|
||||
explosion=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.idx = idx
|
||||
self.order = order
|
||||
self.tx = tx
|
||||
if spPr is None:
|
||||
spPr = GraphicalProperties()
|
||||
self.spPr = spPr
|
||||
self.pictureOptions = pictureOptions
|
||||
self.dPt = dPt
|
||||
self.dLbls = dLbls
|
||||
self.trendline = trendline
|
||||
self.errBars = errBars
|
||||
self.cat = cat
|
||||
self.val = val
|
||||
self.invertIfNegative = invertIfNegative
|
||||
self.shape = shape
|
||||
self.xVal = xVal
|
||||
self.yVal = yVal
|
||||
self.bubbleSize = bubbleSize
|
||||
self.bubble3D = bubble3D
|
||||
if marker is None:
|
||||
marker = Marker()
|
||||
self.marker = marker
|
||||
self.smooth = smooth
|
||||
self.explosion = explosion
|
||||
|
||||
|
||||
def to_tree(self, tagname=None, idx=None):
|
||||
"""The index can need rebasing"""
|
||||
if idx is not None:
|
||||
if self.order == self.idx:
|
||||
self.order = idx # rebase the order if the index has been rebased
|
||||
self.idx = idx
|
||||
return super().to_tree(tagname)
|
||||
|
||||
|
||||
class XYSeries(Series):
|
||||
|
||||
"""Dedicated series for charts that have x and y series"""
|
||||
|
||||
idx = Series.idx
|
||||
order = Series.order
|
||||
tx = Series.tx
|
||||
spPr = Series.spPr
|
||||
|
||||
dPt = Series.dPt
|
||||
dLbls = Series.dLbls
|
||||
trendline = Series.trendline
|
||||
errBars = Series.errBars
|
||||
xVal = Series.xVal
|
||||
yVal = Series.yVal
|
||||
|
||||
invertIfNegative = Series.invertIfNegative
|
||||
|
||||
bubbleSize = Series.bubbleSize
|
||||
bubble3D = Series.bubble3D
|
||||
|
||||
marker = Series.marker
|
||||
smooth = Series.smooth
|
@ -0,0 +1,41 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from .data_source import NumDataSource, NumRef, AxDataSource
|
||||
from .reference import Reference
|
||||
from .series import Series, XYSeries, SeriesLabel, StrRef
|
||||
from openpyxl.utils import rows_from_range, quote_sheetname
|
||||
|
||||
|
||||
def SeriesFactory(values, xvalues=None, zvalues=None, title=None, title_from_data=False):
|
||||
"""
|
||||
Convenience Factory for creating chart data series.
|
||||
"""
|
||||
|
||||
if not isinstance(values, Reference):
|
||||
values = Reference(range_string=values)
|
||||
|
||||
if title_from_data:
|
||||
cell = values.pop()
|
||||
title = u"{0}!{1}".format(values.sheetname, cell)
|
||||
title = SeriesLabel(strRef=StrRef(title))
|
||||
elif title is not None:
|
||||
title = SeriesLabel(v=title)
|
||||
|
||||
source = NumDataSource(numRef=NumRef(f=values))
|
||||
if xvalues is not None:
|
||||
if not isinstance(xvalues, Reference):
|
||||
xvalues = Reference(range_string=xvalues)
|
||||
series = XYSeries()
|
||||
series.yVal = source
|
||||
series.xVal = AxDataSource(numRef=NumRef(f=xvalues))
|
||||
if zvalues is not None:
|
||||
if not isinstance(zvalues, Reference):
|
||||
zvalues = Reference(range_string=zvalues)
|
||||
series.zVal = NumDataSource(NumRef(f=zvalues))
|
||||
else:
|
||||
series = Series()
|
||||
series.val = source
|
||||
|
||||
if title is not None:
|
||||
series.title = title
|
||||
return series
|
89
lib/python3.13/site-packages/openpyxl/chart/shapes.py
Normal file
89
lib/python3.13/site-packages/openpyxl/chart/shapes.py
Normal file
@ -0,0 +1,89 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Alias
|
||||
)
|
||||
from openpyxl.descriptors.nested import (
|
||||
EmptyTag
|
||||
)
|
||||
from openpyxl.drawing.colors import ColorChoiceDescriptor
|
||||
from openpyxl.drawing.fill import *
|
||||
from openpyxl.drawing.line import LineProperties
|
||||
from openpyxl.drawing.geometry import (
|
||||
Shape3D,
|
||||
Scene3D,
|
||||
Transform2D,
|
||||
CustomGeometry2D,
|
||||
PresetGeometry2D,
|
||||
)
|
||||
|
||||
|
||||
class GraphicalProperties(Serialisable):
|
||||
|
||||
"""
|
||||
Somewhat vaguely 21.2.2.197 says this:
|
||||
|
||||
This element specifies the formatting for the parent chart element. The
|
||||
custGeom, prstGeom, scene3d, and xfrm elements are not supported. The
|
||||
bwMode attribute is not supported.
|
||||
|
||||
This doesn't leave much. And the element is used in different places.
|
||||
"""
|
||||
|
||||
tagname = "spPr"
|
||||
|
||||
bwMode = NoneSet(values=(['clr', 'auto', 'gray', 'ltGray', 'invGray',
|
||||
'grayWhite', 'blackGray', 'blackWhite', 'black', 'white', 'hidden']
|
||||
)
|
||||
)
|
||||
|
||||
xfrm = Typed(expected_type=Transform2D, allow_none=True)
|
||||
transform = Alias('xfrm')
|
||||
custGeom = Typed(expected_type=CustomGeometry2D, allow_none=True) # either or
|
||||
prstGeom = Typed(expected_type=PresetGeometry2D, allow_none=True)
|
||||
|
||||
# fills one of
|
||||
noFill = EmptyTag(namespace=DRAWING_NS)
|
||||
solidFill = ColorChoiceDescriptor()
|
||||
gradFill = Typed(expected_type=GradientFillProperties, allow_none=True)
|
||||
pattFill = Typed(expected_type=PatternFillProperties, allow_none=True)
|
||||
|
||||
ln = Typed(expected_type=LineProperties, allow_none=True)
|
||||
line = Alias('ln')
|
||||
scene3d = Typed(expected_type=Scene3D, allow_none=True)
|
||||
sp3d = Typed(expected_type=Shape3D, allow_none=True)
|
||||
shape3D = Alias('sp3d')
|
||||
extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('xfrm', 'prstGeom', 'noFill', 'solidFill', 'gradFill', 'pattFill',
|
||||
'ln', 'scene3d', 'sp3d')
|
||||
|
||||
def __init__(self,
|
||||
bwMode=None,
|
||||
xfrm=None,
|
||||
noFill=None,
|
||||
solidFill=None,
|
||||
gradFill=None,
|
||||
pattFill=None,
|
||||
ln=None,
|
||||
scene3d=None,
|
||||
custGeom=None,
|
||||
prstGeom=None,
|
||||
sp3d=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.bwMode = bwMode
|
||||
self.xfrm = xfrm
|
||||
self.noFill = noFill
|
||||
self.solidFill = solidFill
|
||||
self.gradFill = gradFill
|
||||
self.pattFill = pattFill
|
||||
if ln is None:
|
||||
ln = LineProperties()
|
||||
self.ln = ln
|
||||
self.custGeom = custGeom
|
||||
self.prstGeom = prstGeom
|
||||
self.scene3d = scene3d
|
||||
self.sp3d = sp3d
|
54
lib/python3.13/site-packages/openpyxl/chart/stock_chart.py
Normal file
54
lib/python3.13/site-packages/openpyxl/chart/stock_chart.py
Normal file
@ -0,0 +1,54 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Sequence,
|
||||
Alias,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
|
||||
from ._chart import ChartBase
|
||||
from .axis import TextAxis, NumericAxis, ChartLines
|
||||
from .updown_bars import UpDownBars
|
||||
from .label import DataLabelList
|
||||
from .series import Series
|
||||
|
||||
|
||||
class StockChart(ChartBase):
|
||||
|
||||
tagname = "stockChart"
|
||||
|
||||
ser = Sequence(expected_type=Series) #min 3, max4
|
||||
dLbls = Typed(expected_type=DataLabelList, allow_none=True)
|
||||
dataLabels = Alias('dLbls')
|
||||
dropLines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
hiLowLines = Typed(expected_type=ChartLines, allow_none=True)
|
||||
upDownBars = Typed(expected_type=UpDownBars, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
x_axis = Typed(expected_type=TextAxis)
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
|
||||
_series_type = "line"
|
||||
|
||||
__elements__ = ('ser', 'dLbls', 'dropLines', 'hiLowLines', 'upDownBars',
|
||||
'axId')
|
||||
|
||||
def __init__(self,
|
||||
ser=(),
|
||||
dLbls=None,
|
||||
dropLines=None,
|
||||
hiLowLines=None,
|
||||
upDownBars=None,
|
||||
extLst=None,
|
||||
**kw
|
||||
):
|
||||
self.ser = ser
|
||||
self.dLbls = dLbls
|
||||
self.dropLines = dropLines
|
||||
self.hiLowLines = hiLowLines
|
||||
self.upDownBars = upDownBars
|
||||
self.x_axis = TextAxis()
|
||||
self.y_axis = NumericAxis()
|
||||
super().__init__(**kw)
|
119
lib/python3.13/site-packages/openpyxl/chart/surface_chart.py
Normal file
119
lib/python3.13/site-packages/openpyxl/chart/surface_chart.py
Normal file
@ -0,0 +1,119 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Integer,
|
||||
Bool,
|
||||
Alias,
|
||||
Sequence,
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedInteger,
|
||||
NestedBool,
|
||||
)
|
||||
|
||||
from ._chart import ChartBase
|
||||
from ._3d import _3DBase
|
||||
from .axis import TextAxis, NumericAxis, SeriesAxis
|
||||
from .shapes import GraphicalProperties
|
||||
from .series import Series
|
||||
|
||||
|
||||
class BandFormat(Serialisable):
|
||||
|
||||
tagname = "bandFmt"
|
||||
|
||||
idx = NestedInteger()
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias("spPr")
|
||||
|
||||
__elements__ = ('idx', 'spPr')
|
||||
|
||||
def __init__(self,
|
||||
idx=0,
|
||||
spPr=None,
|
||||
):
|
||||
self.idx = idx
|
||||
self.spPr = spPr
|
||||
|
||||
|
||||
class BandFormatList(Serialisable):
|
||||
|
||||
tagname = "bandFmts"
|
||||
|
||||
bandFmt = Sequence(expected_type=BandFormat, allow_none=True)
|
||||
|
||||
__elements__ = ('bandFmt',)
|
||||
|
||||
def __init__(self,
|
||||
bandFmt=(),
|
||||
):
|
||||
self.bandFmt = bandFmt
|
||||
|
||||
|
||||
class _SurfaceChartBase(ChartBase):
|
||||
|
||||
wireframe = NestedBool(allow_none=True)
|
||||
ser = Sequence(expected_type=Series, allow_none=True)
|
||||
bandFmts = Typed(expected_type=BandFormatList, allow_none=True)
|
||||
|
||||
_series_type = "surface"
|
||||
|
||||
__elements__ = ('wireframe', 'ser', 'bandFmts')
|
||||
|
||||
def __init__(self,
|
||||
wireframe=None,
|
||||
ser=(),
|
||||
bandFmts=None,
|
||||
**kw
|
||||
):
|
||||
self.wireframe = wireframe
|
||||
self.ser = ser
|
||||
self.bandFmts = bandFmts
|
||||
super().__init__(**kw)
|
||||
|
||||
|
||||
class SurfaceChart3D(_SurfaceChartBase, _3DBase):
|
||||
|
||||
tagname = "surface3DChart"
|
||||
|
||||
wireframe = _SurfaceChartBase.wireframe
|
||||
ser = _SurfaceChartBase.ser
|
||||
bandFmts = _SurfaceChartBase.bandFmts
|
||||
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
x_axis = Typed(expected_type=TextAxis)
|
||||
y_axis = Typed(expected_type=NumericAxis)
|
||||
z_axis = Typed(expected_type=SeriesAxis)
|
||||
|
||||
__elements__ = _SurfaceChartBase.__elements__ + ('axId',)
|
||||
|
||||
def __init__(self, **kw):
|
||||
self.x_axis = TextAxis()
|
||||
self.y_axis = NumericAxis()
|
||||
self.z_axis = SeriesAxis()
|
||||
super(SurfaceChart3D, self).__init__(**kw)
|
||||
|
||||
|
||||
class SurfaceChart(SurfaceChart3D):
|
||||
|
||||
tagname = "surfaceChart"
|
||||
|
||||
wireframe = _SurfaceChartBase.wireframe
|
||||
ser = _SurfaceChartBase.ser
|
||||
bandFmts = _SurfaceChartBase.bandFmts
|
||||
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = SurfaceChart3D.__elements__
|
||||
|
||||
def __init__(self, **kw):
|
||||
super().__init__(**kw)
|
||||
self.y_axis.delete = True
|
||||
self.view3D.x_rotation = 90
|
||||
self.view3D.y_rotation = 0
|
||||
self.view3D.perspective = False
|
||||
self.view3D.right_angle_axes = False
|
78
lib/python3.13/site-packages/openpyxl/chart/text.py
Normal file
78
lib/python3.13/site-packages/openpyxl/chart/text.py
Normal file
@ -0,0 +1,78 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Alias,
|
||||
Sequence,
|
||||
)
|
||||
|
||||
|
||||
from openpyxl.drawing.text import (
|
||||
RichTextProperties,
|
||||
ListStyle,
|
||||
Paragraph,
|
||||
)
|
||||
|
||||
from .data_source import StrRef
|
||||
|
||||
|
||||
class RichText(Serialisable):
|
||||
|
||||
"""
|
||||
From the specification: 21.2.2.216
|
||||
|
||||
This element specifies text formatting. The lstStyle element is not supported.
|
||||
"""
|
||||
|
||||
tagname = "rich"
|
||||
|
||||
bodyPr = Typed(expected_type=RichTextProperties)
|
||||
properties = Alias("bodyPr")
|
||||
lstStyle = Typed(expected_type=ListStyle, allow_none=True)
|
||||
p = Sequence(expected_type=Paragraph)
|
||||
paragraphs = Alias('p')
|
||||
|
||||
__elements__ = ("bodyPr", "lstStyle", "p")
|
||||
|
||||
def __init__(self,
|
||||
bodyPr=None,
|
||||
lstStyle=None,
|
||||
p=None,
|
||||
):
|
||||
if bodyPr is None:
|
||||
bodyPr = RichTextProperties()
|
||||
self.bodyPr = bodyPr
|
||||
self.lstStyle = lstStyle
|
||||
if p is None:
|
||||
p = [Paragraph()]
|
||||
self.p = p
|
||||
|
||||
|
||||
class Text(Serialisable):
|
||||
|
||||
"""
|
||||
The value can be either a cell reference or a text element
|
||||
If both are present then the reference will be used.
|
||||
"""
|
||||
|
||||
tagname = "tx"
|
||||
|
||||
strRef = Typed(expected_type=StrRef, allow_none=True)
|
||||
rich = Typed(expected_type=RichText, allow_none=True)
|
||||
|
||||
__elements__ = ("strRef", "rich")
|
||||
|
||||
def __init__(self,
|
||||
strRef=None,
|
||||
rich=None
|
||||
):
|
||||
self.strRef = strRef
|
||||
if rich is None:
|
||||
rich = RichText()
|
||||
self.rich = rich
|
||||
|
||||
|
||||
def to_tree(self, tagname=None, idx=None, namespace=None):
|
||||
if self.strRef and self.rich:
|
||||
self.rich = None # can only have one
|
||||
return super().to_tree(tagname, idx, namespace)
|
76
lib/python3.13/site-packages/openpyxl/chart/title.py
Normal file
76
lib/python3.13/site-packages/openpyxl/chart/title.py
Normal file
@ -0,0 +1,76 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Alias,
|
||||
)
|
||||
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import NestedBool
|
||||
|
||||
from .text import Text, RichText
|
||||
from .layout import Layout
|
||||
from .shapes import GraphicalProperties
|
||||
|
||||
from openpyxl.drawing.text import (
|
||||
Paragraph,
|
||||
RegularTextRun,
|
||||
LineBreak,
|
||||
ParagraphProperties,
|
||||
CharacterProperties,
|
||||
)
|
||||
|
||||
|
||||
class Title(Serialisable):
|
||||
tagname = "title"
|
||||
|
||||
tx = Typed(expected_type=Text, allow_none=True)
|
||||
text = Alias('tx')
|
||||
layout = Typed(expected_type=Layout, allow_none=True)
|
||||
overlay = NestedBool(allow_none=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
txPr = Typed(expected_type=RichText, allow_none=True)
|
||||
body = Alias('txPr')
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('tx', 'layout', 'overlay', 'spPr', 'txPr')
|
||||
|
||||
def __init__(self,
|
||||
tx=None,
|
||||
layout=None,
|
||||
overlay=None,
|
||||
spPr=None,
|
||||
txPr=None,
|
||||
extLst=None,
|
||||
):
|
||||
if tx is None:
|
||||
tx = Text()
|
||||
self.tx = tx
|
||||
self.layout = layout
|
||||
self.overlay = overlay
|
||||
self.spPr = spPr
|
||||
self.txPr = txPr
|
||||
|
||||
|
||||
|
||||
def title_maker(text):
|
||||
title = Title()
|
||||
paraprops = ParagraphProperties()
|
||||
paraprops.defRPr = CharacterProperties()
|
||||
paras = [Paragraph(r=[RegularTextRun(t=s)], pPr=paraprops) for s in text.split("\n")]
|
||||
|
||||
title.tx.rich.paragraphs = paras
|
||||
return title
|
||||
|
||||
|
||||
class TitleDescriptor(Typed):
|
||||
|
||||
expected_type = Title
|
||||
allow_none = True
|
||||
|
||||
def __set__(self, instance, value):
|
||||
if isinstance(value, str):
|
||||
value = title_maker(value)
|
||||
super().__set__(instance, value)
|
98
lib/python3.13/site-packages/openpyxl/chart/trendline.py
Normal file
98
lib/python3.13/site-packages/openpyxl/chart/trendline.py
Normal file
@ -0,0 +1,98 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
String,
|
||||
Alias
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.nested import (
|
||||
NestedBool,
|
||||
NestedInteger,
|
||||
NestedFloat,
|
||||
NestedSet
|
||||
)
|
||||
|
||||
from .data_source import NumFmt
|
||||
from .shapes import GraphicalProperties
|
||||
from .text import RichText, Text
|
||||
from .layout import Layout
|
||||
|
||||
|
||||
class TrendlineLabel(Serialisable):
|
||||
|
||||
tagname = "trendlineLbl"
|
||||
|
||||
layout = Typed(expected_type=Layout, allow_none=True)
|
||||
tx = Typed(expected_type=Text, allow_none=True)
|
||||
numFmt = Typed(expected_type=NumFmt, allow_none=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias("spPr")
|
||||
txPr = Typed(expected_type=RichText, allow_none=True)
|
||||
textProperties = Alias("txPr")
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('layout', 'tx', 'numFmt', 'spPr', 'txPr')
|
||||
|
||||
def __init__(self,
|
||||
layout=None,
|
||||
tx=None,
|
||||
numFmt=None,
|
||||
spPr=None,
|
||||
txPr=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.layout = layout
|
||||
self.tx = tx
|
||||
self.numFmt = numFmt
|
||||
self.spPr = spPr
|
||||
self.txPr = txPr
|
||||
|
||||
|
||||
class Trendline(Serialisable):
|
||||
|
||||
tagname = "trendline"
|
||||
|
||||
name = String(allow_none=True)
|
||||
spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
|
||||
graphicalProperties = Alias('spPr')
|
||||
trendlineType = NestedSet(values=(['exp', 'linear', 'log', 'movingAvg', 'poly', 'power']))
|
||||
order = NestedInteger(allow_none=True)
|
||||
period = NestedInteger(allow_none=True)
|
||||
forward = NestedFloat(allow_none=True)
|
||||
backward = NestedFloat(allow_none=True)
|
||||
intercept = NestedFloat(allow_none=True)
|
||||
dispRSqr = NestedBool(allow_none=True)
|
||||
dispEq = NestedBool(allow_none=True)
|
||||
trendlineLbl = Typed(expected_type=TrendlineLabel, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('spPr', 'trendlineType', 'order', 'period', 'forward',
|
||||
'backward', 'intercept', 'dispRSqr', 'dispEq', 'trendlineLbl')
|
||||
|
||||
def __init__(self,
|
||||
name=None,
|
||||
spPr=None,
|
||||
trendlineType='linear',
|
||||
order=None,
|
||||
period=None,
|
||||
forward=None,
|
||||
backward=None,
|
||||
intercept=None,
|
||||
dispRSqr=None,
|
||||
dispEq=None,
|
||||
trendlineLbl=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.name = name
|
||||
self.spPr = spPr
|
||||
self.trendlineType = trendlineType
|
||||
self.order = order
|
||||
self.period = period
|
||||
self.forward = forward
|
||||
self.backward = backward
|
||||
self.intercept = intercept
|
||||
self.dispRSqr = dispRSqr
|
||||
self.dispEq = dispEq
|
||||
self.trendlineLbl = trendlineLbl
|
31
lib/python3.13/site-packages/openpyxl/chart/updown_bars.py
Normal file
31
lib/python3.13/site-packages/openpyxl/chart/updown_bars.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import Typed
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
|
||||
from .shapes import GraphicalProperties
|
||||
from .axis import ChartLines
|
||||
from .descriptors import NestedGapAmount
|
||||
|
||||
|
||||
class UpDownBars(Serialisable):
|
||||
|
||||
tagname = "upbars"
|
||||
|
||||
gapWidth = NestedGapAmount()
|
||||
upBars = Typed(expected_type=ChartLines, allow_none=True)
|
||||
downBars = Typed(expected_type=ChartLines, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('gapWidth', 'upBars', 'downBars')
|
||||
|
||||
def __init__(self,
|
||||
gapWidth=150,
|
||||
upBars=None,
|
||||
downBars=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.gapWidth = gapWidth
|
||||
self.upBars = upBars
|
||||
self.downBars = downBars
|
@ -0,0 +1,3 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from .chartsheet import Chartsheet
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
107
lib/python3.13/site-packages/openpyxl/chartsheet/chartsheet.py
Normal file
107
lib/python3.13/site-packages/openpyxl/chartsheet/chartsheet.py
Normal file
@ -0,0 +1,107 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
|
||||
from openpyxl.descriptors import Typed, Set, Alias
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.drawing.spreadsheet_drawing import (
|
||||
AbsoluteAnchor,
|
||||
SpreadsheetDrawing,
|
||||
)
|
||||
from openpyxl.worksheet.page import (
|
||||
PageMargins,
|
||||
PrintPageSetup
|
||||
)
|
||||
from openpyxl.worksheet.drawing import Drawing
|
||||
from openpyxl.worksheet.header_footer import HeaderFooter
|
||||
from openpyxl.workbook.child import _WorkbookChild
|
||||
from openpyxl.xml.constants import SHEET_MAIN_NS, REL_NS
|
||||
|
||||
from .relation import DrawingHF, SheetBackgroundPicture
|
||||
from .properties import ChartsheetProperties
|
||||
from .protection import ChartsheetProtection
|
||||
from .views import ChartsheetViewList
|
||||
from .custom import CustomChartsheetViews
|
||||
from .publish import WebPublishItems
|
||||
|
||||
|
||||
class Chartsheet(_WorkbookChild, Serialisable):
|
||||
|
||||
tagname = "chartsheet"
|
||||
_default_title = "Chart"
|
||||
_rel_type = "chartsheet"
|
||||
_path = "/xl/chartsheets/sheet{0}.xml"
|
||||
mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml"
|
||||
|
||||
sheetPr = Typed(expected_type=ChartsheetProperties, allow_none=True)
|
||||
sheetViews = Typed(expected_type=ChartsheetViewList)
|
||||
sheetProtection = Typed(expected_type=ChartsheetProtection, allow_none=True)
|
||||
customSheetViews = Typed(expected_type=CustomChartsheetViews, allow_none=True)
|
||||
pageMargins = Typed(expected_type=PageMargins, allow_none=True)
|
||||
pageSetup = Typed(expected_type=PrintPageSetup, allow_none=True)
|
||||
drawing = Typed(expected_type=Drawing, allow_none=True)
|
||||
drawingHF = Typed(expected_type=DrawingHF, allow_none=True)
|
||||
picture = Typed(expected_type=SheetBackgroundPicture, allow_none=True)
|
||||
webPublishItems = Typed(expected_type=WebPublishItems, allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
sheet_state = Set(values=('visible', 'hidden', 'veryHidden'))
|
||||
headerFooter = Typed(expected_type=HeaderFooter)
|
||||
HeaderFooter = Alias('headerFooter')
|
||||
|
||||
__elements__ = (
|
||||
'sheetPr', 'sheetViews', 'sheetProtection', 'customSheetViews',
|
||||
'pageMargins', 'pageSetup', 'headerFooter', 'drawing', 'drawingHF',
|
||||
'picture', 'webPublishItems')
|
||||
|
||||
__attrs__ = ()
|
||||
|
||||
def __init__(self,
|
||||
sheetPr=None,
|
||||
sheetViews=None,
|
||||
sheetProtection=None,
|
||||
customSheetViews=None,
|
||||
pageMargins=None,
|
||||
pageSetup=None,
|
||||
headerFooter=None,
|
||||
drawing=None,
|
||||
drawingHF=None,
|
||||
picture=None,
|
||||
webPublishItems=None,
|
||||
extLst=None,
|
||||
parent=None,
|
||||
title="",
|
||||
sheet_state='visible',
|
||||
):
|
||||
super().__init__(parent, title)
|
||||
self._charts = []
|
||||
self.sheetPr = sheetPr
|
||||
if sheetViews is None:
|
||||
sheetViews = ChartsheetViewList()
|
||||
self.sheetViews = sheetViews
|
||||
self.sheetProtection = sheetProtection
|
||||
self.customSheetViews = customSheetViews
|
||||
self.pageMargins = pageMargins
|
||||
self.pageSetup = pageSetup
|
||||
if headerFooter is not None:
|
||||
self.headerFooter = headerFooter
|
||||
self.drawing = Drawing("rId1")
|
||||
self.drawingHF = drawingHF
|
||||
self.picture = picture
|
||||
self.webPublishItems = webPublishItems
|
||||
self.sheet_state = sheet_state
|
||||
|
||||
|
||||
def add_chart(self, chart):
|
||||
chart.anchor = AbsoluteAnchor()
|
||||
self._charts.append(chart)
|
||||
|
||||
|
||||
def to_tree(self):
|
||||
self._drawing = SpreadsheetDrawing()
|
||||
self._drawing.charts = self._charts
|
||||
tree = super().to_tree()
|
||||
if not self.headerFooter:
|
||||
el = tree.find('headerFooter')
|
||||
tree.remove(el)
|
||||
tree.set("xmlns", SHEET_MAIN_NS)
|
||||
return tree
|
61
lib/python3.13/site-packages/openpyxl/chartsheet/custom.py
Normal file
61
lib/python3.13/site-packages/openpyxl/chartsheet/custom.py
Normal file
@ -0,0 +1,61 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.worksheet.header_footer import HeaderFooter
|
||||
|
||||
from openpyxl.descriptors import (
|
||||
Bool,
|
||||
Integer,
|
||||
Set,
|
||||
Typed,
|
||||
Sequence
|
||||
)
|
||||
from openpyxl.descriptors.excel import Guid
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.worksheet.page import (
|
||||
PageMargins,
|
||||
PrintPageSetup
|
||||
)
|
||||
|
||||
|
||||
class CustomChartsheetView(Serialisable):
|
||||
tagname = "customSheetView"
|
||||
|
||||
guid = Guid()
|
||||
scale = Integer()
|
||||
state = Set(values=(['visible', 'hidden', 'veryHidden']))
|
||||
zoomToFit = Bool(allow_none=True)
|
||||
pageMargins = Typed(expected_type=PageMargins, allow_none=True)
|
||||
pageSetup = Typed(expected_type=PrintPageSetup, allow_none=True)
|
||||
headerFooter = Typed(expected_type=HeaderFooter, allow_none=True)
|
||||
|
||||
__elements__ = ('pageMargins', 'pageSetup', 'headerFooter')
|
||||
|
||||
def __init__(self,
|
||||
guid=None,
|
||||
scale=None,
|
||||
state='visible',
|
||||
zoomToFit=None,
|
||||
pageMargins=None,
|
||||
pageSetup=None,
|
||||
headerFooter=None,
|
||||
):
|
||||
self.guid = guid
|
||||
self.scale = scale
|
||||
self.state = state
|
||||
self.zoomToFit = zoomToFit
|
||||
self.pageMargins = pageMargins
|
||||
self.pageSetup = pageSetup
|
||||
self.headerFooter = headerFooter
|
||||
|
||||
|
||||
class CustomChartsheetViews(Serialisable):
|
||||
tagname = "customSheetViews"
|
||||
|
||||
customSheetView = Sequence(expected_type=CustomChartsheetView, allow_none=True)
|
||||
|
||||
__elements__ = ('customSheetView',)
|
||||
|
||||
def __init__(self,
|
||||
customSheetView=None,
|
||||
):
|
||||
self.customSheetView = customSheetView
|
@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors import (
|
||||
Bool,
|
||||
String,
|
||||
Typed
|
||||
)
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.styles import Color
|
||||
|
||||
|
||||
class ChartsheetProperties(Serialisable):
|
||||
tagname = "sheetPr"
|
||||
|
||||
published = Bool(allow_none=True)
|
||||
codeName = String(allow_none=True)
|
||||
tabColor = Typed(expected_type=Color, allow_none=True)
|
||||
|
||||
__elements__ = ('tabColor',)
|
||||
|
||||
def __init__(self,
|
||||
published=None,
|
||||
codeName=None,
|
||||
tabColor=None,
|
||||
):
|
||||
self.published = published
|
||||
self.codeName = codeName
|
||||
self.tabColor = tabColor
|
@ -0,0 +1,41 @@
|
||||
import hashlib
|
||||
|
||||
from openpyxl.descriptors import (Bool, Integer, String)
|
||||
from openpyxl.descriptors.excel import Base64Binary
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
|
||||
from openpyxl.worksheet.protection import (
|
||||
hash_password,
|
||||
_Protected
|
||||
)
|
||||
|
||||
|
||||
class ChartsheetProtection(Serialisable, _Protected):
|
||||
tagname = "sheetProtection"
|
||||
|
||||
algorithmName = String(allow_none=True)
|
||||
hashValue = Base64Binary(allow_none=True)
|
||||
saltValue = Base64Binary(allow_none=True)
|
||||
spinCount = Integer(allow_none=True)
|
||||
content = Bool(allow_none=True)
|
||||
objects = Bool(allow_none=True)
|
||||
|
||||
__attrs__ = ("content", "objects", "password", "hashValue", "spinCount", "saltValue", "algorithmName")
|
||||
|
||||
def __init__(self,
|
||||
content=None,
|
||||
objects=None,
|
||||
hashValue=None,
|
||||
spinCount=None,
|
||||
saltValue=None,
|
||||
algorithmName=None,
|
||||
password=None,
|
||||
):
|
||||
self.content = content
|
||||
self.objects = objects
|
||||
self.hashValue = hashValue
|
||||
self.spinCount = spinCount
|
||||
self.saltValue = saltValue
|
||||
self.algorithmName = algorithmName
|
||||
if password is not None:
|
||||
self.password = password
|
58
lib/python3.13/site-packages/openpyxl/chartsheet/publish.py
Normal file
58
lib/python3.13/site-packages/openpyxl/chartsheet/publish.py
Normal file
@ -0,0 +1,58 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors import (
|
||||
Bool,
|
||||
Integer,
|
||||
String,
|
||||
Set,
|
||||
Sequence
|
||||
)
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
|
||||
|
||||
class WebPublishItem(Serialisable):
|
||||
tagname = "webPublishItem"
|
||||
|
||||
id = Integer()
|
||||
divId = String()
|
||||
sourceType = Set(values=(['sheet', 'printArea', 'autoFilter', 'range', 'chart', 'pivotTable', 'query', 'label']))
|
||||
sourceRef = String()
|
||||
sourceObject = String(allow_none=True)
|
||||
destinationFile = String()
|
||||
title = String(allow_none=True)
|
||||
autoRepublish = Bool(allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
id=None,
|
||||
divId=None,
|
||||
sourceType=None,
|
||||
sourceRef=None,
|
||||
sourceObject=None,
|
||||
destinationFile=None,
|
||||
title=None,
|
||||
autoRepublish=None,
|
||||
):
|
||||
self.id = id
|
||||
self.divId = divId
|
||||
self.sourceType = sourceType
|
||||
self.sourceRef = sourceRef
|
||||
self.sourceObject = sourceObject
|
||||
self.destinationFile = destinationFile
|
||||
self.title = title
|
||||
self.autoRepublish = autoRepublish
|
||||
|
||||
|
||||
class WebPublishItems(Serialisable):
|
||||
tagname = "WebPublishItems"
|
||||
|
||||
count = Integer(allow_none=True)
|
||||
webPublishItem = Sequence(expected_type=WebPublishItem, )
|
||||
|
||||
__elements__ = ('webPublishItem',)
|
||||
|
||||
def __init__(self,
|
||||
count=None,
|
||||
webPublishItem=None,
|
||||
):
|
||||
self.count = len(webPublishItem)
|
||||
self.webPublishItem = webPublishItem
|
97
lib/python3.13/site-packages/openpyxl/chartsheet/relation.py
Normal file
97
lib/python3.13/site-packages/openpyxl/chartsheet/relation.py
Normal file
@ -0,0 +1,97 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors import (
|
||||
Integer,
|
||||
Alias
|
||||
)
|
||||
from openpyxl.descriptors.excel import Relation
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
|
||||
|
||||
class SheetBackgroundPicture(Serialisable):
|
||||
tagname = "picture"
|
||||
id = Relation()
|
||||
|
||||
def __init__(self, id):
|
||||
self.id = id
|
||||
|
||||
|
||||
class DrawingHF(Serialisable):
|
||||
id = Relation()
|
||||
lho = Integer(allow_none=True)
|
||||
leftHeaderOddPages = Alias('lho')
|
||||
lhe = Integer(allow_none=True)
|
||||
leftHeaderEvenPages = Alias('lhe')
|
||||
lhf = Integer(allow_none=True)
|
||||
leftHeaderFirstPage = Alias('lhf')
|
||||
cho = Integer(allow_none=True)
|
||||
centerHeaderOddPages = Alias('cho')
|
||||
che = Integer(allow_none=True)
|
||||
centerHeaderEvenPages = Alias('che')
|
||||
chf = Integer(allow_none=True)
|
||||
centerHeaderFirstPage = Alias('chf')
|
||||
rho = Integer(allow_none=True)
|
||||
rightHeaderOddPages = Alias('rho')
|
||||
rhe = Integer(allow_none=True)
|
||||
rightHeaderEvenPages = Alias('rhe')
|
||||
rhf = Integer(allow_none=True)
|
||||
rightHeaderFirstPage = Alias('rhf')
|
||||
lfo = Integer(allow_none=True)
|
||||
leftFooterOddPages = Alias('lfo')
|
||||
lfe = Integer(allow_none=True)
|
||||
leftFooterEvenPages = Alias('lfe')
|
||||
lff = Integer(allow_none=True)
|
||||
leftFooterFirstPage = Alias('lff')
|
||||
cfo = Integer(allow_none=True)
|
||||
centerFooterOddPages = Alias('cfo')
|
||||
cfe = Integer(allow_none=True)
|
||||
centerFooterEvenPages = Alias('cfe')
|
||||
cff = Integer(allow_none=True)
|
||||
centerFooterFirstPage = Alias('cff')
|
||||
rfo = Integer(allow_none=True)
|
||||
rightFooterOddPages = Alias('rfo')
|
||||
rfe = Integer(allow_none=True)
|
||||
rightFooterEvenPages = Alias('rfe')
|
||||
rff = Integer(allow_none=True)
|
||||
rightFooterFirstPage = Alias('rff')
|
||||
|
||||
def __init__(self,
|
||||
id=None,
|
||||
lho=None,
|
||||
lhe=None,
|
||||
lhf=None,
|
||||
cho=None,
|
||||
che=None,
|
||||
chf=None,
|
||||
rho=None,
|
||||
rhe=None,
|
||||
rhf=None,
|
||||
lfo=None,
|
||||
lfe=None,
|
||||
lff=None,
|
||||
cfo=None,
|
||||
cfe=None,
|
||||
cff=None,
|
||||
rfo=None,
|
||||
rfe=None,
|
||||
rff=None,
|
||||
):
|
||||
self.id = id
|
||||
self.lho = lho
|
||||
self.lhe = lhe
|
||||
self.lhf = lhf
|
||||
self.cho = cho
|
||||
self.che = che
|
||||
self.chf = chf
|
||||
self.rho = rho
|
||||
self.rhe = rhe
|
||||
self.rhf = rhf
|
||||
self.lfo = lfo
|
||||
self.lfe = lfe
|
||||
self.lff = lff
|
||||
self.cfo = cfo
|
||||
self.cfe = cfe
|
||||
self.cff = cff
|
||||
self.rfo = rfo
|
||||
self.rfe = rfe
|
||||
self.rff = rff
|
51
lib/python3.13/site-packages/openpyxl/chartsheet/views.py
Normal file
51
lib/python3.13/site-packages/openpyxl/chartsheet/views.py
Normal file
@ -0,0 +1,51 @@
|
||||
# Copyright (c) 2010-2024 openpyxl
|
||||
|
||||
from openpyxl.descriptors import (
|
||||
Bool,
|
||||
Integer,
|
||||
Typed,
|
||||
Sequence
|
||||
)
|
||||
from openpyxl.descriptors.excel import ExtensionList
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
|
||||
|
||||
class ChartsheetView(Serialisable):
|
||||
tagname = "sheetView"
|
||||
|
||||
tabSelected = Bool(allow_none=True)
|
||||
zoomScale = Integer(allow_none=True)
|
||||
workbookViewId = Integer()
|
||||
zoomToFit = Bool(allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ()
|
||||
|
||||
def __init__(self,
|
||||
tabSelected=None,
|
||||
zoomScale=None,
|
||||
workbookViewId=0,
|
||||
zoomToFit=True,
|
||||
extLst=None,
|
||||
):
|
||||
self.tabSelected = tabSelected
|
||||
self.zoomScale = zoomScale
|
||||
self.workbookViewId = workbookViewId
|
||||
self.zoomToFit = zoomToFit
|
||||
|
||||
|
||||
class ChartsheetViewList(Serialisable):
|
||||
tagname = "sheetViews"
|
||||
|
||||
sheetView = Sequence(expected_type=ChartsheetView, )
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ('sheetView',)
|
||||
|
||||
def __init__(self,
|
||||
sheetView=None,
|
||||
extLst=None,
|
||||
):
|
||||
if sheetView is None:
|
||||
sheetView = [ChartsheetView()]
|
||||
self.sheetView = sheetView
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user