Updated .venv

This commit is contained in:
Kristofers Solo 2021-11-22 17:12:51 +02:00
parent 1e065cc4b2
commit fc125db0e7
464 changed files with 51032 additions and 0 deletions

Binary file not shown.

410
.venv/bin/runxlrd.py Normal file
View File

@ -0,0 +1,410 @@
#!/media/HardDrive/Pyhton/School/.venv/bin/python
# Copyright (c) 2005-2012 Stephen John Machin, Lingfo Pty Ltd
# This script is part of the xlrd package, which is released under a
# BSD-style licence.
from __future__ import print_function
cmd_doc = """
Commands:
2rows Print the contents of first and last row in each sheet
3rows Print the contents of first, second and last row in each sheet
bench Same as "show", but doesn't print -- for profiling
biff_count[1] Print a count of each type of BIFF record in the file
biff_dump[1] Print a dump (char and hex) of the BIFF records in the file
fonts hdr + print a dump of all font objects
hdr Mini-overview of file (no per-sheet information)
hotshot Do a hotshot profile run e.g. ... -f1 hotshot bench bigfile*.xls
labels Dump of sheet.col_label_ranges and ...row... for each sheet
name_dump Dump of each object in book.name_obj_list
names Print brief information for each NAME record
ov Overview of file
profile Like "hotshot", but uses cProfile
show Print the contents of all rows in each sheet
version[0] Print versions of xlrd and Python and exit
xfc Print "XF counts" and cell-type counts -- see code for details
[0] means no file arg
[1] means only one file arg i.e. no glob.glob pattern
"""
options = None
if __name__ == "__main__":
import xlrd
import sys
import time
import glob
import traceback
import gc
from xlrd.timemachine import xrange, REPR
class LogHandler(object):
def __init__(self, logfileobj):
self.logfileobj = logfileobj
self.fileheading = None
self.shown = 0
def setfileheading(self, fileheading):
self.fileheading = fileheading
self.shown = 0
def write(self, text):
if self.fileheading and not self.shown:
self.logfileobj.write(self.fileheading)
self.shown = 1
self.logfileobj.write(text)
null_cell = xlrd.empty_cell
def show_row(bk, sh, rowx, colrange, printit):
if bk.ragged_rows:
colrange = range(sh.row_len(rowx))
if not colrange: return
if printit: print()
if bk.formatting_info:
for colx, ty, val, cxfx in get_row_data(bk, sh, rowx, colrange):
if printit:
print("cell %s%d: type=%d, data: %r, xfx: %s"
% (xlrd.colname(colx), rowx+1, ty, val, cxfx))
else:
for colx, ty, val, _unused in get_row_data(bk, sh, rowx, colrange):
if printit:
print("cell %s%d: type=%d, data: %r" % (xlrd.colname(colx), rowx+1, ty, val))
def get_row_data(bk, sh, rowx, colrange):
result = []
dmode = bk.datemode
ctys = sh.row_types(rowx)
cvals = sh.row_values(rowx)
for colx in colrange:
cty = ctys[colx]
cval = cvals[colx]
if bk.formatting_info:
cxfx = str(sh.cell_xf_index(rowx, colx))
else:
cxfx = ''
if cty == xlrd.XL_CELL_DATE:
try:
showval = xlrd.xldate_as_tuple(cval, dmode)
except xlrd.XLDateError as e:
showval = "%s:%s" % (type(e).__name__, e)
cty = xlrd.XL_CELL_ERROR
elif cty == xlrd.XL_CELL_ERROR:
showval = xlrd.error_text_from_code.get(cval, '<Unknown error code 0x%02x>' % cval)
else:
showval = cval
result.append((colx, cty, showval, cxfx))
return result
def bk_header(bk):
print()
print("BIFF version: %s; datemode: %s"
% (xlrd.biff_text_from_num[bk.biff_version], bk.datemode))
print("codepage: %r (encoding: %s); countries: %r"
% (bk.codepage, bk.encoding, bk.countries))
print("Last saved by: %r" % bk.user_name)
print("Number of data sheets: %d" % bk.nsheets)
print("Use mmap: %d; Formatting: %d; On demand: %d"
% (bk.use_mmap, bk.formatting_info, bk.on_demand))
print("Ragged rows: %d" % bk.ragged_rows)
if bk.formatting_info:
print("FORMATs: %d, FONTs: %d, XFs: %d"
% (len(bk.format_list), len(bk.font_list), len(bk.xf_list)))
if not options.suppress_timing:
print("Load time: %.2f seconds (stage 1) %.2f seconds (stage 2)"
% (bk.load_time_stage_1, bk.load_time_stage_2))
print()
def show_fonts(bk):
print("Fonts:")
for x in xrange(len(bk.font_list)):
font = bk.font_list[x]
font.dump(header='== Index %d ==' % x, indent=4)
def show_names(bk, dump=0):
bk_header(bk)
if bk.biff_version < 50:
print("Names not extracted in this BIFF version")
return
nlist = bk.name_obj_list
print("Name list: %d entries" % len(nlist))
for nobj in nlist:
if dump:
nobj.dump(sys.stdout,
header="\n=== Dump of name_obj_list[%d] ===" % nobj.name_index)
else:
print("[%d]\tName:%r macro:%r scope:%d\n\tresult:%r\n"
% (nobj.name_index, nobj.name, nobj.macro, nobj.scope, nobj.result))
def print_labels(sh, labs, title):
if not labs:return
for rlo, rhi, clo, chi in labs:
print("%s label range %s:%s contains:"
% (title, xlrd.cellname(rlo, clo), xlrd.cellname(rhi-1, chi-1)))
for rx in xrange(rlo, rhi):
for cx in xrange(clo, chi):
print(" %s: %r" % (xlrd.cellname(rx, cx), sh.cell_value(rx, cx)))
def show_labels(bk):
# bk_header(bk)
hdr = 0
for shx in range(bk.nsheets):
sh = bk.sheet_by_index(shx)
clabs = sh.col_label_ranges
rlabs = sh.row_label_ranges
if clabs or rlabs:
if not hdr:
bk_header(bk)
hdr = 1
print("sheet %d: name = %r; nrows = %d; ncols = %d" %
(shx, sh.name, sh.nrows, sh.ncols))
print_labels(sh, clabs, 'Col')
print_labels(sh, rlabs, 'Row')
if bk.on_demand: bk.unload_sheet(shx)
def show(bk, nshow=65535, printit=1):
bk_header(bk)
if 0:
rclist = xlrd.sheet.rc_stats.items()
rclist = sorted(rclist)
print("rc stats")
for k, v in rclist:
print("0x%04x %7d" % (k, v))
if options.onesheet:
try:
shx = int(options.onesheet)
except ValueError:
shx = bk.sheet_by_name(options.onesheet).number
shxrange = [shx]
else:
shxrange = range(bk.nsheets)
# print("shxrange", list(shxrange))
for shx in shxrange:
sh = bk.sheet_by_index(shx)
nrows, ncols = sh.nrows, sh.ncols
colrange = range(ncols)
anshow = min(nshow, nrows)
print("sheet %d: name = %s; nrows = %d; ncols = %d" %
(shx, REPR(sh.name), sh.nrows, sh.ncols))
if nrows and ncols:
# Beat the bounds
for rowx in xrange(nrows):
nc = sh.row_len(rowx)
if nc:
sh.row_types(rowx)[nc-1]
sh.row_values(rowx)[nc-1]
sh.cell(rowx, nc-1)
for rowx in xrange(anshow-1):
if not printit and rowx % 10000 == 1 and rowx > 1:
print("done %d rows" % (rowx-1,))
show_row(bk, sh, rowx, colrange, printit)
if anshow and nrows:
show_row(bk, sh, nrows-1, colrange, printit)
print()
if bk.on_demand: bk.unload_sheet(shx)
def count_xfs(bk):
bk_header(bk)
for shx in range(bk.nsheets):
sh = bk.sheet_by_index(shx)
nrows = sh.nrows
print("sheet %d: name = %r; nrows = %d; ncols = %d" %
(shx, sh.name, sh.nrows, sh.ncols))
# Access all xfindexes to force gathering stats
type_stats = [0, 0, 0, 0, 0, 0, 0]
for rowx in xrange(nrows):
for colx in xrange(sh.row_len(rowx)):
xfx = sh.cell_xf_index(rowx, colx)
assert xfx >= 0
cty = sh.cell_type(rowx, colx)
type_stats[cty] += 1
print("XF stats", sh._xf_index_stats)
print("type stats", type_stats)
print()
if bk.on_demand: bk.unload_sheet(shx)
def main(cmd_args):
import optparse
global options
usage = "\n%prog [options] command [input-file-patterns]\n" + cmd_doc
oparser = optparse.OptionParser(usage)
oparser.add_option(
"-l", "--logfilename",
default="",
help="contains error messages")
oparser.add_option(
"-v", "--verbosity",
type="int", default=0,
help="level of information and diagnostics provided")
oparser.add_option(
"-m", "--mmap",
type="int", default=-1,
help="1: use mmap; 0: don't use mmap; -1: accept heuristic")
oparser.add_option(
"-e", "--encoding",
default="",
help="encoding override")
oparser.add_option(
"-f", "--formatting",
type="int", default=0,
help="0 (default): no fmt info\n"
"1: fmt info (all cells)\n",
)
oparser.add_option(
"-g", "--gc",
type="int", default=0,
help="0: auto gc enabled; 1: auto gc disabled, manual collect after each file; 2: no gc")
oparser.add_option(
"-s", "--onesheet",
default="",
help="restrict output to this sheet (name or index)")
oparser.add_option(
"-u", "--unnumbered",
action="store_true", default=0,
help="omit line numbers or offsets in biff_dump")
oparser.add_option(
"-d", "--on-demand",
action="store_true", default=0,
help="load sheets on demand instead of all at once")
oparser.add_option(
"-t", "--suppress-timing",
action="store_true", default=0,
help="don't print timings (diffs are less messy)")
oparser.add_option(
"-r", "--ragged-rows",
action="store_true", default=0,
help="open_workbook(..., ragged_rows=True)")
options, args = oparser.parse_args(cmd_args)
if len(args) == 1 and args[0] in ("version", ):
pass
elif len(args) < 2:
oparser.error("Expected at least 2 args, found %d" % len(args))
cmd = args[0]
xlrd_version = getattr(xlrd, "__VERSION__", "unknown; before 0.5")
if cmd == 'biff_dump':
xlrd.dump(args[1], unnumbered=options.unnumbered)
sys.exit(0)
if cmd == 'biff_count':
xlrd.count_records(args[1])
sys.exit(0)
if cmd == 'version':
print("xlrd: %s, from %s" % (xlrd_version, xlrd.__file__))
print("Python:", sys.version)
sys.exit(0)
if options.logfilename:
logfile = LogHandler(open(options.logfilename, 'w'))
else:
logfile = sys.stdout
mmap_opt = options.mmap
mmap_arg = xlrd.USE_MMAP
if mmap_opt in (1, 0):
mmap_arg = mmap_opt
elif mmap_opt != -1:
print('Unexpected value (%r) for mmap option -- assuming default' % mmap_opt)
fmt_opt = options.formatting | (cmd in ('xfc', ))
gc_mode = options.gc
if gc_mode:
gc.disable()
for pattern in args[1:]:
for fname in glob.glob(pattern):
print("\n=== File: %s ===" % fname)
if logfile != sys.stdout:
logfile.setfileheading("\n=== File: %s ===\n" % fname)
if gc_mode == 1:
n_unreachable = gc.collect()
if n_unreachable:
print("GC before open:", n_unreachable, "unreachable objects")
try:
t0 = time.time()
bk = xlrd.open_workbook(
fname,
verbosity=options.verbosity, logfile=logfile,
use_mmap=mmap_arg,
encoding_override=options.encoding,
formatting_info=fmt_opt,
on_demand=options.on_demand,
ragged_rows=options.ragged_rows,
)
t1 = time.time()
if not options.suppress_timing:
print("Open took %.2f seconds" % (t1-t0,))
except xlrd.XLRDError as e:
print("*** Open failed: %s: %s" % (type(e).__name__, e))
continue
except KeyboardInterrupt:
print("*** KeyboardInterrupt ***")
traceback.print_exc(file=sys.stdout)
sys.exit(1)
except BaseException as e:
print("*** Open failed: %s: %s" % (type(e).__name__, e))
traceback.print_exc(file=sys.stdout)
continue
t0 = time.time()
if cmd == 'hdr':
bk_header(bk)
elif cmd == 'ov': # OverView
show(bk, 0)
elif cmd == 'show': # all rows
show(bk)
elif cmd == '2rows': # first row and last row
show(bk, 2)
elif cmd == '3rows': # first row, 2nd row and last row
show(bk, 3)
elif cmd == 'bench':
show(bk, printit=0)
elif cmd == 'fonts':
bk_header(bk)
show_fonts(bk)
elif cmd == 'names': # named reference list
show_names(bk)
elif cmd == 'name_dump': # named reference list
show_names(bk, dump=1)
elif cmd == 'labels':
show_labels(bk)
elif cmd == 'xfc':
count_xfs(bk)
else:
print("*** Unknown command <%s>" % cmd)
sys.exit(1)
del bk
if gc_mode == 1:
n_unreachable = gc.collect()
if n_unreachable:
print("GC post cmd:", fname, "->", n_unreachable, "unreachable objects")
if not options.suppress_timing:
t1 = time.time()
print("\ncommand took %.2f seconds\n" % (t1-t0,))
return None
av = sys.argv[1:]
if not av:
main(av)
firstarg = av[0].lower()
if firstarg == "hotshot":
import hotshot
import hotshot.stats
av = av[1:]
prof_log_name = "XXXX.prof"
prof = hotshot.Profile(prof_log_name)
# benchtime, result = prof.runcall(main, *av)
result = prof.runcall(main, *(av, ))
print("result", repr(result))
prof.close()
stats = hotshot.stats.load(prof_log_name)
stats.strip_dirs()
stats.sort_stats('time', 'calls')
stats.print_stats(20)
elif firstarg == "profile":
import cProfile
av = av[1:]
cProfile.run('main(av)', 'YYYY.prof')
import pstats
p = pstats.Stats('YYYY.prof')
p.strip_dirs().sort_stats('cumulative').print_stats(30)
else:
main(av)

View File

@ -0,0 +1,4 @@
The authors in alphabetical order
* Charlie Clark
* Elias Rabel

View File

@ -0,0 +1,34 @@
This software is under the MIT Licence
======================================
Copyright (c) 2010 openpyxl
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Odict implementation in openpyxl/writer/odict.py uses the following licence:
Copyright (c) 2001-2011 Python Software Foundation
2011 Raymond Hettinger
License: PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
See http://www.opensource.org/licenses/Python-2.0 for full terms
Note: backport changes by Raymond were originally distributed under MIT
license, but since the original license for Python is more
restrictive than MIT, code cannot be released under its terms and
still adheres to the limitations of Python license.

View File

@ -0,0 +1,37 @@
Metadata-Version: 2.1
Name: et-xmlfile
Version: 1.1.0
Summary: An implementation of lxml.xmlfile for the standard library
Home-page: https://foss.heptapod.net/openpyxl/et_xmlfile
Author: See ATUHORS.txt
Author-email: charlie.clark@clark-consulting.eu
License: MIT
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Requires-Python: >=3.6
et_xmfile
=========
et_xmlfile is a low memory library for creating large XML files.
It is based upon the `xmlfile module from lxml <http://lxml.de/api.html#incremental-xml-generation>`_ with the aim of allowing code to be developed that will work with both libraries. It was developed initially for the openpyxl project but is now a standalone module.
The code was written by Elias Rabel as part of the `Python Düsseldorf <http://pyddf.de>`_ openpyxl sprint in September 2014.
Note on performance
-------------------
The code was not developed with performance in mind but turned out to be faster than the existing SAX-based implementation but is significantly slower than lxml's xmlfile. There is one area where an optimisation for lxml will negatively affect the performance of et_xmfile and that is when using the `.element()` method on an xmlfile context manager. It is, therefore, recommended not to use this, though the method is provided for code compatibility.

View File

@ -0,0 +1,11 @@
et_xmlfile-1.1.0.dist-info/AUTHORS.txt,sha256=Y6mQLe0ywXMVP7WVFrZgEW3CqhIv-plM1CaOtdtBuXs,64
et_xmlfile-1.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
et_xmlfile-1.1.0.dist-info/LICENCE.rst,sha256=r-YrNgzcqB-43m7kt2ENodhsORd3qAx6y20RRVxTxCk,1694
et_xmlfile-1.1.0.dist-info/METADATA,sha256=B5hV5UW4GqmWGgwAW44C2ofZZEmV0MRnTEU98kzcUGw,1775
et_xmlfile-1.1.0.dist-info/RECORD,,
et_xmlfile-1.1.0.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92
et_xmlfile-1.1.0.dist-info/top_level.txt,sha256=34-74d5NNARgTsPxCMta5o28XpBNmSN0iCZhtmx2Fk8,11
et_xmlfile/__init__.py,sha256=-oTKwE6upIG2gOmnOc4KLgV-pKbBwy-zhQfizbmCruQ,269
et_xmlfile/__pycache__/__init__.cpython-39.pyc,,
et_xmlfile/__pycache__/xmlfile.cpython-39.pyc,,
et_xmlfile/xmlfile.py,sha256=_h20RRb3ptDZ6xXoxMU_Wrx8rG6UZsg0TS7HEOrotzg,3204

View File

@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.36.2)
Root-Is-Purelib: true
Tag: py3-none-any

View File

@ -0,0 +1 @@
et_xmlfile

View File

@ -0,0 +1,11 @@
from __future__ import absolute_import
from .xmlfile import xmlfile
# constants
__version__ = '1.1.0'
__author__ = 'See ATUHORS.txt'
__license__ = 'MIT'
__author_email__ = 'charlie.clark@clark-consulting.eu'
__url__ = 'https://foss.heptapod.net/openpyxl/et_xmlfile'

View File

@ -0,0 +1,104 @@
from __future__ import absolute_import
# Copyright (c) 2010-2015 openpyxl
"""Implements the lxml.etree.xmlfile API using the standard library xml.etree"""
from contextlib import contextmanager
from xml.etree.ElementTree import Element, tostring
class LxmlSyntaxError(Exception):
pass
class _FakeIncrementalFileWriter(object):
"""Replacement for _IncrementalFileWriter of lxml.
Uses ElementTree to build xml in memory."""
def __init__(self, output_file):
self._element_stack = []
self._top_element = None
self._file = output_file
self._have_root = False
@contextmanager
def element(self, tag, attrib=None, nsmap=None, **_extra):
"""Create a new xml element using a context manager.
The elements are written when the top level context is left.
This is for code compatibility only as it is quite slow.
"""
# __enter__ part
self._have_root = True
if attrib is None:
attrib = {}
self._top_element = Element(tag, attrib=attrib, **_extra)
self._top_element.text = ''
self._top_element.tail = ''
self._element_stack.append(self._top_element)
yield
# __exit__ part
el = self._element_stack.pop()
if self._element_stack:
parent = self._element_stack[-1]
parent.append(self._top_element)
self._top_element = parent
else:
self._write_element(el)
self._top_element = None
def write(self, arg):
"""Write a string or subelement."""
if isinstance(arg, str):
# it is not allowed to write a string outside of an element
if self._top_element is None:
raise LxmlSyntaxError()
if len(self._top_element) == 0:
# element has no children: add string to text
self._top_element.text += arg
else:
# element has children: add string to tail of last child
self._top_element[-1].tail += arg
else:
if self._top_element is not None:
self._top_element.append(arg)
elif not self._have_root:
self._write_element(arg)
else:
raise LxmlSyntaxError()
def _write_element(self, element):
xml = tostring(element)
self._file.write(xml)
def __enter__(self):
pass
def __exit__(self, type, value, traceback):
# without root the xml document is incomplete
if not self._have_root:
raise LxmlSyntaxError()
class xmlfile(object):
"""Context manager that can replace lxml.etree.xmlfile."""
def __init__(self, output_file, buffered=False, encoding=None, close=False):
if isinstance(output_file, str):
self._file = open(output_file, 'wb')
self._close = True
else:
self._file = output_file
self._close = close
def __enter__(self):
return _FakeIncrementalFileWriter(self._file)
def __exit__(self, type, value, traceback):
if self._close == True:
self._file.close()

View File

@ -0,0 +1,23 @@
This software is under the MIT Licence
======================================
Copyright (c) 2010 openpyxl
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,86 @@
Metadata-Version: 2.1
Name: openpyxl
Version: 3.0.9
Summary: A Python library to read/write Excel 2010 xlsx/xlsm files
Home-page: https://openpyxl.readthedocs.io
Author: See AUTHORS
Author-email: charlie.clark@clark-consulting.eu
License: MIT
Project-URL: Documentation, https://openpyxl.readthedocs.io/en/stable/
Project-URL: Source, https://foss.heptapod.net/openpyxl/openpyxl
Project-URL: Tracker, https://foss.heptapod.net/openpyxl/openpyxl/-/issues
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Requires-Python: >=3.6
Requires-Dist: et-xmlfile
.. image:: https://coveralls.io/repos/bitbucket/openpyxl/openpyxl/badge.svg?branch=default
:target: https://coveralls.io/bitbucket/openpyxl/openpyxl?branch=default
:alt: coverage status
Introduction
------------
openpyxl is a Python library to read/write Excel 2010 xlsx/xlsm/xltx/xltm files.
It was born from lack of existing library to read/write natively from Python
the Office Open XML format.
All kudos to the PHPExcel team as openpyxl was initially based on PHPExcel.
Security
--------
By default openpyxl does not guard against quadratic blowup or billion laughs
xml attacks. To guard against these attacks install defusedxml.
Mailing List
------------
The user list can be found on http://groups.google.com/group/openpyxl-users
Sample code::
from openpyxl import Workbook
wb = Workbook()
# grab the active worksheet
ws = wb.active
# Data can be assigned directly to cells
ws['A1'] = 42
# Rows can also be appended
ws.append([1, 2, 3])
# Python types will automatically be converted
import datetime
ws['A2'] = datetime.datetime.now()
# Save the file
wb.save("sample.xlsx")
Documentation
-------------
The documentation is at: https://openpyxl.readthedocs.io
* installation methods
* code examples
* instructions for contributing
Release notes: https://openpyxl.readthedocs.io/en/stable/changes.html

View File

@ -0,0 +1,377 @@
openpyxl-3.0.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
openpyxl-3.0.9.dist-info/LICENCE.rst,sha256=DIS7QvXTZ-Xr-fwt3jWxYUHfXuD9wYklCFi8bFVg9p4,1131
openpyxl-3.0.9.dist-info/METADATA,sha256=nyOB7PVYprTd7J8RFY9j81D4RTbwAKyaee9puN1aoLc,2402
openpyxl-3.0.9.dist-info/RECORD,,
openpyxl-3.0.9.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
openpyxl-3.0.9.dist-info/WHEEL,sha256=Z-nyYpwrcSqxfdux5Mbn_DQ525iP7J2DG3JgGvOYyTQ,110
openpyxl-3.0.9.dist-info/top_level.txt,sha256=mKJO5QFAsUEDtJ_c97F-IbmVtHYEDymqD7d5X0ULkVs,9
openpyxl/__init__.py,sha256=LwUYr610sjX-FNO8AT02VSLu9_Yqfm2VSth0jxY0guY,589
openpyxl/__pycache__/__init__.cpython-39.pyc,,
openpyxl/__pycache__/_constants.cpython-39.pyc,,
openpyxl/_constants.py,sha256=DkkixDltIGNgNXc3iMlgfAgipwp1qdCuX_AugMD2ELM,306
openpyxl/cell/__init__.py,sha256=fAUl7XybyQyh23ueFBrqscifJ7cEYFCRrisYOwIuacU,122
openpyxl/cell/__pycache__/__init__.cpython-39.pyc,,
openpyxl/cell/__pycache__/_writer.cpython-39.pyc,,
openpyxl/cell/__pycache__/cell.cpython-39.pyc,,
openpyxl/cell/__pycache__/read_only.cpython-39.pyc,,
openpyxl/cell/__pycache__/text.cpython-39.pyc,,
openpyxl/cell/_writer.py,sha256=wCS-bH6If6BVYjgNs3K75TEq44nREOWGbmtducFBcHE,3186
openpyxl/cell/cell.py,sha256=5LwtMVPSpKf3GzlgK0Wewn-_9e7lljlxlvogn8GSTts,8670
openpyxl/cell/read_only.py,sha256=LLrQscGUa7PVBhH_YEmrSLbr3P3Ipz4euYs_1sQqMLM,3113
openpyxl/cell/text.py,sha256=KaOdI6yy3sPD9Y_HEDgATmGobOnWCgyq8wrPXosJl_A,4367
openpyxl/chart/_3d.py,sha256=HvOtimbdR_-v_INDkUmrmzvHPndBTVToWdt-pe3rJHM,3104
openpyxl/chart/__init__.py,sha256=av7vi6nQcBqnGi58WkSIvTFNpvsmAfwu559ihLqwqoo,564
openpyxl/chart/__pycache__/_3d.cpython-39.pyc,,
openpyxl/chart/__pycache__/__init__.cpython-39.pyc,,
openpyxl/chart/__pycache__/_chart.cpython-39.pyc,,
openpyxl/chart/__pycache__/area_chart.cpython-39.pyc,,
openpyxl/chart/__pycache__/axis.cpython-39.pyc,,
openpyxl/chart/__pycache__/bar_chart.cpython-39.pyc,,
openpyxl/chart/__pycache__/bubble_chart.cpython-39.pyc,,
openpyxl/chart/__pycache__/chartspace.cpython-39.pyc,,
openpyxl/chart/__pycache__/data_source.cpython-39.pyc,,
openpyxl/chart/__pycache__/descriptors.cpython-39.pyc,,
openpyxl/chart/__pycache__/error_bar.cpython-39.pyc,,
openpyxl/chart/__pycache__/label.cpython-39.pyc,,
openpyxl/chart/__pycache__/layout.cpython-39.pyc,,
openpyxl/chart/__pycache__/legend.cpython-39.pyc,,
openpyxl/chart/__pycache__/line_chart.cpython-39.pyc,,
openpyxl/chart/__pycache__/marker.cpython-39.pyc,,
openpyxl/chart/__pycache__/picture.cpython-39.pyc,,
openpyxl/chart/__pycache__/pie_chart.cpython-39.pyc,,
openpyxl/chart/__pycache__/pivot.cpython-39.pyc,,
openpyxl/chart/__pycache__/plotarea.cpython-39.pyc,,
openpyxl/chart/__pycache__/print_settings.cpython-39.pyc,,
openpyxl/chart/__pycache__/radar_chart.cpython-39.pyc,,
openpyxl/chart/__pycache__/reader.cpython-39.pyc,,
openpyxl/chart/__pycache__/reference.cpython-39.pyc,,
openpyxl/chart/__pycache__/scatter_chart.cpython-39.pyc,,
openpyxl/chart/__pycache__/series.cpython-39.pyc,,
openpyxl/chart/__pycache__/series_factory.cpython-39.pyc,,
openpyxl/chart/__pycache__/shapes.cpython-39.pyc,,
openpyxl/chart/__pycache__/stock_chart.cpython-39.pyc,,
openpyxl/chart/__pycache__/surface_chart.cpython-39.pyc,,
openpyxl/chart/__pycache__/text.cpython-39.pyc,,
openpyxl/chart/__pycache__/title.cpython-39.pyc,,
openpyxl/chart/__pycache__/trendline.cpython-39.pyc,,
openpyxl/chart/__pycache__/updown_bars.cpython-39.pyc,,
openpyxl/chart/_chart.py,sha256=zWv9EVLTCb1PnQGGigmAIYce3fLi0mlC30j9lapcaWQ,5583
openpyxl/chart/area_chart.py,sha256=e9dGvxHLSCCKINixj4fSATVd3Ua_h-F1URARDgPUCr0,2925
openpyxl/chart/axis.py,sha256=27sfB6ocrOL-ea0fK_K5eSlKxPSIl79CR6GfbZ0Yh-8,12657
openpyxl/chart/bar_chart.py,sha256=aINFtJNQKz3GS8xRRTtOvs0L7YDYfaNgm8X86v_DU7Q,4175
openpyxl/chart/bubble_chart.py,sha256=oQFIoXmFbck665Xrha8tTJkgaWYzXpnSaIWRaN20_FU,2021
openpyxl/chart/chartspace.py,sha256=uWSLy5bHdEYFkknUauCNi4OZ4VcbJVWdixH-rVuRAxg,6122
openpyxl/chart/data_source.py,sha256=ZGFU04_tol5aj99Cy_z90A0TOySo-zsdgLXXLm98ZnU,5809
openpyxl/chart/descriptors.py,sha256=U_9bYcapV0h-JB09bEPxjGqy2UIiYFfK6wuxmIKQ05U,764
openpyxl/chart/error_bar.py,sha256=z9wX9DL7DIiASfKZHkxylQgtRsZGUbXX1nduhEFbGM0,1832
openpyxl/chart/label.py,sha256=vBKKrK3FNASphKfbj8thZgYbqB3q5MOcBydKn9VmA10,4167
openpyxl/chart/layout.py,sha256=Cdn9GpkzBqlNeHo6Bo3t1L0zT3JD0zdW6XyQR0G2L-Y,2040
openpyxl/chart/legend.py,sha256=guKi88vLYDmUV9mvz80kGTkVVisHT06y-nSVDqnrcgY,2040
openpyxl/chart/line_chart.py,sha256=CiVznoifZD8fBclgJXqXl5GgoC3B-GXF8FyQA48GMQI,3986
openpyxl/chart/marker.py,sha256=MB7NmYfAPizDueNn-_0n0OoQTU6tbBMulyxjHrKNpKw,2600
openpyxl/chart/picture.py,sha256=xNjAGqYIGUHUAboSVnmAKD9yDNXiXG4nK7mxo8V935A,1156
openpyxl/chart/pie_chart.py,sha256=gyX0Wx4qJs4J7UFfyG1aPd1Dmp-lGyssK--TwsZNuZ8,4868
openpyxl/chart/pivot.py,sha256=8zTdCLHxfZqPBj0Ffz9p0P2SioOsiTsTeEZS-AgMqOI,1779
openpyxl/chart/plotarea.py,sha256=at7r2AP67z5seangCuvQNPpt7W_f3DUC8-PsA4rQfnU,5832
openpyxl/chart/print_settings.py,sha256=oPGqTrBebiRyrNka5NCbwT0ARBn7nh4Ykm51YHPRdJ4,1454
openpyxl/chart/radar_chart.py,sha256=VjHjqPKGuLSK9kkXmLM6K_J38Ed4QBr_u5oMI8wBk4M,1537
openpyxl/chart/reader.py,sha256=ffUGLiMWCc9dgjlz6LdU8Q_aMhU4TZcP6VqvmzIDezg,719
openpyxl/chart/reference.py,sha256=sAhYJdEEVe4GkvbmnSDF_2kjZ_pnEeocSqhEkqRlfQY,3098
openpyxl/chart/scatter_chart.py,sha256=1Uwjv5t7EK_Z74hOg4I0DDBtHQ4S8oIMrZoIt9hGpnA,1559
openpyxl/chart/series.py,sha256=_Fo54wbhKseHZ8QyYKZ_p01odJVTDU-_i2EPRhCtlAE,5908
openpyxl/chart/series_factory.py,sha256=PTWxPZYdkZxDZZCkblxxUoKVumbDFtj3r3ZqEercdlc,1368
openpyxl/chart/shapes.py,sha256=rgTSDxEzGjZqCPNLWSLBSoSSC2N7llwJSEVKwlYvX0s,2815
openpyxl/chart/stock_chart.py,sha256=qHNjyvI36ZVyZ81Vu6FfBR7EvCBWbYsEFeDZopROm9s,1620
openpyxl/chart/surface_chart.py,sha256=jxYrjOaJ11joRSUFeH0NO4uy5OyPZI78KeBAECgnZKQ,2955
openpyxl/chart/text.py,sha256=fba-LTfVB6AtIgpFKliWgIk6tQ7HNYL4JOLNJeTg3x8,1857
openpyxl/chart/title.py,sha256=QX_OPzjF8JLyou9WY7V7jtBZImGpCfbf4nssM0nifRQ,1973
openpyxl/chart/trendline.py,sha256=LEZS8QABT9tFv9-kZS0mAoop6_yRVo2nNXks_WTMGGM,3053
openpyxl/chart/updown_bars.py,sha256=IKN86TcUsVkzNaavvlSftHUg1-j458qqBmEzjQ0FAfs,897
openpyxl/chartsheet/__init__.py,sha256=myQp-ZuyMgRDVI9Qk69Wm9DV94MRtnraap70zf4FJUo,71
openpyxl/chartsheet/__pycache__/__init__.cpython-39.pyc,,
openpyxl/chartsheet/__pycache__/chartsheet.cpython-39.pyc,,
openpyxl/chartsheet/__pycache__/custom.cpython-39.pyc,,
openpyxl/chartsheet/__pycache__/properties.cpython-39.pyc,,
openpyxl/chartsheet/__pycache__/protection.cpython-39.pyc,,
openpyxl/chartsheet/__pycache__/publish.cpython-39.pyc,,
openpyxl/chartsheet/__pycache__/relation.cpython-39.pyc,,
openpyxl/chartsheet/__pycache__/views.cpython-39.pyc,,
openpyxl/chartsheet/chartsheet.py,sha256=2c6SlJXQwPaJ-wkfbe1P8_J9bZz1l8VoleEHosiAatw,4042
openpyxl/chartsheet/custom.py,sha256=SPLIS-hgBwvPCnkL5ShRmObvCLECgs_CJ9eNB2aKnFY,1691
openpyxl/chartsheet/properties.py,sha256=g8TGLCIj90WVPWVzHI_whqm7Mrb3B-avBUx5I6KCjRA,679
openpyxl/chartsheet/protection.py,sha256=eJixEBmdoTDO2_0h6g51sdSdfSdCaP8UUNsbEqHds6U,1265
openpyxl/chartsheet/publish.py,sha256=a7elqmA6cqRTKvQSbIIwbDS4xKU6bVjsFsiGSK-Dbg0,1587
openpyxl/chartsheet/relation.py,sha256=qTKpAWyYIH_UMRYiHKd_xlZ4nD2F3a6PmyduFgj1_1M,2731
openpyxl/chartsheet/views.py,sha256=cyLt6jsuSO7Yix_hFz-ZmZdSReVqCIIhgv-Xd6-oen4,1341
openpyxl/comments/__init__.py,sha256=QcxwWmrCTsmEL7cL9FCtKO9SQhbaoCsyVs_9zpZU8us,67
openpyxl/comments/__pycache__/__init__.cpython-39.pyc,,
openpyxl/comments/__pycache__/author.cpython-39.pyc,,
openpyxl/comments/__pycache__/comment_sheet.cpython-39.pyc,,
openpyxl/comments/__pycache__/comments.cpython-39.pyc,,
openpyxl/comments/__pycache__/shape_writer.cpython-39.pyc,,
openpyxl/comments/author.py,sha256=5DjOW6-SJsuQoRQ8y7IB3r1NVmD6rGzvuH7e0f1IbyI,388
openpyxl/comments/comment_sheet.py,sha256=kP94CQHhB78R_tvfv2kYdaMXA_r5vtyPFhRD8xDvq2U,5874
openpyxl/comments/comments.py,sha256=qwBDd1wv0PEKuQ6XO1ysMk57xUZweXy_93BxyYV7Hak,1474
openpyxl/comments/shape_writer.py,sha256=PZ9mp2Qc-p0c4Xa6q_S2drMsfHOOX39FzlupX5FbTk0,3868
openpyxl/compat/__init__.py,sha256=kA10fld-rDc2G78_o3DfL8hJ2g87kVKCc_9quMmasIo,1592
openpyxl/compat/__pycache__/__init__.cpython-39.pyc,,
openpyxl/compat/__pycache__/abc.cpython-39.pyc,,
openpyxl/compat/__pycache__/numbers.cpython-39.pyc,,
openpyxl/compat/__pycache__/product.cpython-39.pyc,,
openpyxl/compat/__pycache__/singleton.cpython-39.pyc,,
openpyxl/compat/__pycache__/strings.cpython-39.pyc,,
openpyxl/compat/abc.py,sha256=oZ1qLqqHcdL6RB4YfD1mny3MYNxwIgf9edtGniukZP8,155
openpyxl/compat/numbers.py,sha256=Rqr8gY47XjdwiDRlSl8QJ5nwMr7RTJolXKy1oB_vTts,1617
openpyxl/compat/product.py,sha256=gyp89bpR4jeJjr4uNvQMcHfx-1VohyUhiF_r4Sm4msY,264
openpyxl/compat/singleton.py,sha256=faYZiBq_k8gDeKbOtvHm-SVb0-4uYTUwtQI7G2XJIrc,1083
openpyxl/compat/strings.py,sha256=Bty1sXQiiW2etuQXRfy-pqqXQ5GgADJx1ewZID7s_e0,604
openpyxl/descriptors/__init__.py,sha256=ySMQq3DVAZjV3IMwyAs3rYsYQOn2qqy5AltpjNVvXGs,1816
openpyxl/descriptors/__pycache__/__init__.cpython-39.pyc,,
openpyxl/descriptors/__pycache__/base.cpython-39.pyc,,
openpyxl/descriptors/__pycache__/excel.cpython-39.pyc,,
openpyxl/descriptors/__pycache__/namespace.cpython-39.pyc,,
openpyxl/descriptors/__pycache__/nested.cpython-39.pyc,,
openpyxl/descriptors/__pycache__/sequence.cpython-39.pyc,,
openpyxl/descriptors/__pycache__/serialisable.cpython-39.pyc,,
openpyxl/descriptors/__pycache__/slots.cpython-39.pyc,,
openpyxl/descriptors/base.py,sha256=0Q4psdmTQs3oYxY7VikwItnfM_0srgitB7eCv0wm040,7110
openpyxl/descriptors/excel.py,sha256=TPYzzf0x5uyCyXC3USjO8AZhzD83J0T08OaUOfqCyhs,2438
openpyxl/descriptors/namespace.py,sha256=ZvQcYT_aLJIsdc5LjlmRPZQ7UZp-1OdWkPrD7hG2Jmc,309
openpyxl/descriptors/nested.py,sha256=lkmVD1zG_VPAbukFpk8jnj5MjPkDaVRzVKKJfBRCWqc,2651
openpyxl/descriptors/sequence.py,sha256=DJjJ8RyFaiuPSfNvEVevMii5uzUoZe2hjOESaS4kHig,3324
openpyxl/descriptors/serialisable.py,sha256=cfRFFSAMbTM0GCPY5Lqy_UrmJABbKf-Klesw8pitTRo,7343
openpyxl/descriptors/slots.py,sha256=xNj5vLWWoounpYqbP2JDnnhlTiTLRn-uTfQxncpFfn0,824
openpyxl/drawing/__init__.py,sha256=oP2zHU2hnNw8Iq5oAlUejZ3zxyGjAd7fpbtHR2mhVcc,66
openpyxl/drawing/__pycache__/__init__.cpython-39.pyc,,
openpyxl/drawing/__pycache__/colors.cpython-39.pyc,,
openpyxl/drawing/__pycache__/connector.cpython-39.pyc,,
openpyxl/drawing/__pycache__/drawing.cpython-39.pyc,,
openpyxl/drawing/__pycache__/effect.cpython-39.pyc,,
openpyxl/drawing/__pycache__/fill.cpython-39.pyc,,
openpyxl/drawing/__pycache__/geometry.cpython-39.pyc,,
openpyxl/drawing/__pycache__/graphic.cpython-39.pyc,,
openpyxl/drawing/__pycache__/image.cpython-39.pyc,,
openpyxl/drawing/__pycache__/line.cpython-39.pyc,,
openpyxl/drawing/__pycache__/picture.cpython-39.pyc,,
openpyxl/drawing/__pycache__/properties.cpython-39.pyc,,
openpyxl/drawing/__pycache__/relation.cpython-39.pyc,,
openpyxl/drawing/__pycache__/spreadsheet_drawing.cpython-39.pyc,,
openpyxl/drawing/__pycache__/text.cpython-39.pyc,,
openpyxl/drawing/__pycache__/xdr.cpython-39.pyc,,
openpyxl/drawing/colors.py,sha256=qiCOIvoETNtYJ1Sdzi6bD-mTidUqeLvYk3txBKjpM1w,15278
openpyxl/drawing/connector.py,sha256=K3_RiZI0g9q6CfGGWm-R5y1lip56qnzdX5u8hHeI2g0,3863
openpyxl/drawing/drawing.py,sha256=FqPCzLScbKSgHzT4GKiEcgKrleGIkYvTRbLPrbzNz5Y,2785
openpyxl/drawing/effect.py,sha256=-eVp0TnnTE9qSWndoaer__sWMgC3BYDvm1k15W3eoRQ,9529
openpyxl/drawing/fill.py,sha256=Yg3kTFWtsmIDTfNxNshOMT7QwkkplDpwt0umoZ7s9VU,12701
openpyxl/drawing/geometry.py,sha256=l9VQKibbVOKIXEaZANMA1d46HcMPspsc42LLIjegz4A,17733
openpyxl/drawing/graphic.py,sha256=QlfuEt8OiL6d24jXx3FF7TabOBxB8K8Ou_9n-hNAzGg,5127
openpyxl/drawing/image.py,sha256=Homv8y1OgvKwruDQ5t59U-46cMdh3uen8PyundZuqrQ,1424
openpyxl/drawing/line.py,sha256=Ml4QPvOT4hHUyRYss3TNUeX77UXWTpe-G9j2irdFiuM,4105
openpyxl/drawing/picture.py,sha256=Byum7rekO_gFujozHcQ3v1pYCarEhpFpuJjPwutq_aQ,4287
openpyxl/drawing/properties.py,sha256=whzCZhq7EU6wpyj4j-ZYYrb1M9x-KfXHIbmgV7jFKTU,4948
openpyxl/drawing/relation.py,sha256=1U3pSBA6NAuJdD0YCSFGTUJ_pMeexWgbX29BZaKtxnc,344
openpyxl/drawing/spreadsheet_drawing.py,sha256=euiEVY2pslbznlMkRl5wlF99WHRrDZfJ4ke0fMRPTbg,10762
openpyxl/drawing/text.py,sha256=i5mTpE7UcEZ1LfuAJ3_vjeDMTrbYx6UJD4_Qc7LJsNU,22345
openpyxl/drawing/xdr.py,sha256=2LXQIZUST4MNRZ1zSe-TKjSSioVBju2kbiL5riMvSQ4,626
openpyxl/formatting/__init__.py,sha256=g7jBykulaodAZuQl8W_qcI7aBR3sqtuAzEv9XnF6ZNM,59
openpyxl/formatting/__pycache__/__init__.cpython-39.pyc,,
openpyxl/formatting/__pycache__/formatting.cpython-39.pyc,,
openpyxl/formatting/__pycache__/rule.cpython-39.pyc,,
openpyxl/formatting/formatting.py,sha256=dlb9q-z-7yk1FUaVZwN7LDwGBwTCo_3SuA8X8yvwqiE,2805
openpyxl/formatting/rule.py,sha256=Ajl4HITXbeAnJv2gqlxIe6dnAS7NFn2UzVASo7Xg9c4,9308
openpyxl/formula/__init__.py,sha256=QC48KwwIjQQVRxkMQnaDxjtZxZfiF5XAX7K7qgTXnfk,69
openpyxl/formula/__pycache__/__init__.cpython-39.pyc,,
openpyxl/formula/__pycache__/tokenizer.cpython-39.pyc,,
openpyxl/formula/__pycache__/translate.cpython-39.pyc,,
openpyxl/formula/tokenizer.py,sha256=LYD7rjTds1kbKo_EeL22H4QtPgvzD04uAAh_XX_XQV0,15104
openpyxl/formula/translate.py,sha256=3yduwyIg71VUHquJFbFKYorfpfwSdC4QNXdM3HyqGug,6661
openpyxl/packaging/__init__.py,sha256=KcNtO2zoYizOgG-iZzayZffSL1WeZR98i1Q8QYTRhfI,90
openpyxl/packaging/__pycache__/__init__.cpython-39.pyc,,
openpyxl/packaging/__pycache__/core.cpython-39.pyc,,
openpyxl/packaging/__pycache__/extended.cpython-39.pyc,,
openpyxl/packaging/__pycache__/interface.cpython-39.pyc,,
openpyxl/packaging/__pycache__/manifest.cpython-39.pyc,,
openpyxl/packaging/__pycache__/relationship.cpython-39.pyc,,
openpyxl/packaging/__pycache__/workbook.cpython-39.pyc,,
openpyxl/packaging/core.py,sha256=OQmPubwaPH5g-fkOthCN8q_Z9n14Nf4q9iJMvpJPj84,4011
openpyxl/packaging/extended.py,sha256=Da8Xr9kn4gfZWSA5Qf3xXBCkT11uNUovv4uAVUG2l64,4755
openpyxl/packaging/interface.py,sha256=1QT67yOeMnthkLOdgS_7m7FO-WoSGfIsDPo6q61Xa-8,920
openpyxl/packaging/manifest.py,sha256=UYYsrPqMfGHCzkkV-G7HsSxVXTTFwha3cQkR_yxmR_k,5643
openpyxl/packaging/relationship.py,sha256=Pr3xtHVlvC6VenHqTBNVyeef0aocVbCHRw98iVynW4A,4356
openpyxl/packaging/workbook.py,sha256=MN_oSLd0kCLWKbgUNMfzGD57V427vW_NxMA8dUi-qYw,7024
openpyxl/pivot/__init__.py,sha256=C431i_Ek0iWxSP_jixBAabUFuCJ-3T3ESB-MEY21epw,35
openpyxl/pivot/__pycache__/__init__.cpython-39.pyc,,
openpyxl/pivot/__pycache__/cache.cpython-39.pyc,,
openpyxl/pivot/__pycache__/fields.cpython-39.pyc,,
openpyxl/pivot/__pycache__/record.cpython-39.pyc,,
openpyxl/pivot/__pycache__/table.cpython-39.pyc,,
openpyxl/pivot/cache.py,sha256=-QlTsZz0vEiOfgOdUwg7l0oUa-3bnQN9ilBqnwuSXls,30587
openpyxl/pivot/fields.py,sha256=_IiGKyBNyidZjKS7wtnRvSFG3nDBLo6hBYXffO9_KYw,6984
openpyxl/pivot/record.py,sha256=guO-qFdU2gPvAbunXIfL23LsSNUlJph7y4ABdz2ZwJg,2687
openpyxl/pivot/table.py,sha256=NmB0Ln37myAs3oRIZJWmPxusz7FAAxJPIMgUyblo4n4,37779
openpyxl/reader/__init__.py,sha256=C431i_Ek0iWxSP_jixBAabUFuCJ-3T3ESB-MEY21epw,35
openpyxl/reader/__pycache__/__init__.cpython-39.pyc,,
openpyxl/reader/__pycache__/drawings.cpython-39.pyc,,
openpyxl/reader/__pycache__/excel.cpython-39.pyc,,
openpyxl/reader/__pycache__/strings.cpython-39.pyc,,
openpyxl/reader/__pycache__/workbook.cpython-39.pyc,,
openpyxl/reader/drawings.py,sha256=8CbA_PRujCea9qBMHcTIlsyveG9LH5Zs6U1YZb2GmUc,2090
openpyxl/reader/excel.py,sha256=odJKl2KciJTobeSe0v9b5pzUgocs_DwBfGh2M1EJ0l0,10978
openpyxl/reader/strings.py,sha256=t6rTWWNkCIjj4lvnVXRi0wX1cyvl0MjVeBMLdyWTEzA,565
openpyxl/reader/workbook.py,sha256=_vPDSwNOlKVV3AM0NUx3jCNc8ihOfWtFdsNcqEv1CEU,3921
openpyxl/styles/__init__.py,sha256=drQyG97CRWfunkBvFNct9YGO_asNPwrmK8zya5RlYAY,363
openpyxl/styles/__pycache__/__init__.cpython-39.pyc,,
openpyxl/styles/__pycache__/alignment.cpython-39.pyc,,
openpyxl/styles/__pycache__/borders.cpython-39.pyc,,
openpyxl/styles/__pycache__/builtins.cpython-39.pyc,,
openpyxl/styles/__pycache__/cell_style.cpython-39.pyc,,
openpyxl/styles/__pycache__/colors.cpython-39.pyc,,
openpyxl/styles/__pycache__/differential.cpython-39.pyc,,
openpyxl/styles/__pycache__/fills.cpython-39.pyc,,
openpyxl/styles/__pycache__/fonts.cpython-39.pyc,,
openpyxl/styles/__pycache__/named_styles.cpython-39.pyc,,
openpyxl/styles/__pycache__/numbers.cpython-39.pyc,,
openpyxl/styles/__pycache__/protection.cpython-39.pyc,,
openpyxl/styles/__pycache__/proxy.cpython-39.pyc,,
openpyxl/styles/__pycache__/styleable.cpython-39.pyc,,
openpyxl/styles/__pycache__/stylesheet.cpython-39.pyc,,
openpyxl/styles/__pycache__/table.cpython-39.pyc,,
openpyxl/styles/alignment.py,sha256=ZuBWNhLBW4g_Q4TU0KBJ5my22FFqhdKB37TXwkRYrNQ,2512
openpyxl/styles/borders.py,sha256=dnt-7DHqO4QLjV2Sr-U4zQnF6ixzzaIsqRw4LMvIZ68,3594
openpyxl/styles/builtins.py,sha256=YGYBPgTNLbaAZHNUGTEr91FqaRCaL_4rY0dsKAVHpVY,31182
openpyxl/styles/cell_style.py,sha256=w5EqHsP2Y-tV2jLGdruxDnJpDVuW8vc5VJXW1t3wP_k,5304
openpyxl/styles/colors.py,sha256=kUlwq2k4xq6PJgAEqeDGbYMLaoXDPPy7YeFKVKMaols,4653
openpyxl/styles/differential.py,sha256=XG-vfPkpLuRXVkd3S5wbSJuPPV0u_o7cbEFqCtK5uzk,2267
openpyxl/styles/fills.py,sha256=_TJZBNSOKXDgX0t_4Z8om5Jn09BvNrTm0N3EVpsvucs,6443
openpyxl/styles/fonts.py,sha256=cowp6CGjDVB_OBvSHFhrlb1EQyKo_jA98s-9FkiKspU,3525
openpyxl/styles/named_styles.py,sha256=VJen65pr6LDo1GFeRMUQv8sYFIuaOVASZZhLyjV3a5M,7424
openpyxl/styles/numbers.py,sha256=frWSLxHhpD36wyOuKGeocURPC6IuhKwLf5Kykex2A8Y,5120
openpyxl/styles/protection.py,sha256=gXijc5Ns9CMOg6wMkCuxvfofAUWLmJmTkyaspuriDzA,394
openpyxl/styles/proxy.py,sha256=J2Wxdfme7B7WP8F31F_YhWChe8SWsW3zA5wtTHsSp5w,1456
openpyxl/styles/styleable.py,sha256=89EE07Dpzsc2LNZ9K5S39WYxY3Qh25am7Maqcf23VmM,4565
openpyxl/styles/stylesheet.py,sha256=xnKGb-nqzFeckXiUNuCa16KPW7kVrHwfPOvzjVh3jKw,8535
openpyxl/styles/table.py,sha256=pEcpnQqGSGHL3c7yX6diCoXgo0jXZmHE8sEgVk80Y70,2801
openpyxl/utils/__init__.py,sha256=9di7orVwjmoDs91vIIFG2905cRz6GSqcZGULCSVDdws,324
openpyxl/utils/__pycache__/__init__.cpython-39.pyc,,
openpyxl/utils/__pycache__/bound_dictionary.cpython-39.pyc,,
openpyxl/utils/__pycache__/cell.cpython-39.pyc,,
openpyxl/utils/__pycache__/dataframe.cpython-39.pyc,,
openpyxl/utils/__pycache__/datetime.cpython-39.pyc,,
openpyxl/utils/__pycache__/escape.cpython-39.pyc,,
openpyxl/utils/__pycache__/exceptions.cpython-39.pyc,,
openpyxl/utils/__pycache__/formulas.cpython-39.pyc,,
openpyxl/utils/__pycache__/indexed_list.cpython-39.pyc,,
openpyxl/utils/__pycache__/inference.cpython-39.pyc,,
openpyxl/utils/__pycache__/protection.cpython-39.pyc,,
openpyxl/utils/__pycache__/units.cpython-39.pyc,,
openpyxl/utils/bound_dictionary.py,sha256=M9CR0VGuA7ez3Gygakxi_LDM4eTHnaAfQZjqzwzMRg8,759
openpyxl/utils/cell.py,sha256=YyVEya6Sg7n1TruyH6KoCV-vf5HXn9dvrUhIO-42yMM,6535
openpyxl/utils/dataframe.py,sha256=9V6xPyszo2D1jTRzboOPCpt4h5MQKXd_336ayZT6mcw,2596
openpyxl/utils/datetime.py,sha256=KmETLpuUlIKa-PmATdqLF1dZb1gccCBxZyczHhf6h_8,4529
openpyxl/utils/escape.py,sha256=jGDj670JLnb2m6aaNNqZ_-FqfAj30gldsa_KkwNEivs,790
openpyxl/utils/exceptions.py,sha256=JOsAobMRZyID8Rdml9ZMy1rvi1zybK2jjm11qFNhqZg,889
openpyxl/utils/formulas.py,sha256=Punoz4y-nP5ZGS-sO6iOZ7YzLirB_oY-E7kvspLKIaE,3733
openpyxl/utils/indexed_list.py,sha256=wnQVqowfbz-3MiZA2nHT4OZOmxvtH_1cGQ4FTJwDfMw,1257
openpyxl/utils/inference.py,sha256=DKezUUNPWcHTwjsH34sGMPe70BPYKDyuc_tgO0zhVaw,1582
openpyxl/utils/protection.py,sha256=ICR82mHKJJIBCLX0h-MqyBpwdETL7hA4u4TvbDNyBlM,830
openpyxl/utils/units.py,sha256=EDSpkdD3O5aQcvhtHI4ocBA2Ur2RoYXdvjbnHNtSq0I,2674
openpyxl/workbook/__init__.py,sha256=gAI3oh1brO22ZBCWiiBm9tYm7fdPlT2toDExpCuTb5w,68
openpyxl/workbook/__pycache__/__init__.cpython-39.pyc,,
openpyxl/workbook/__pycache__/_writer.cpython-39.pyc,,
openpyxl/workbook/__pycache__/child.cpython-39.pyc,,
openpyxl/workbook/__pycache__/defined_name.cpython-39.pyc,,
openpyxl/workbook/__pycache__/external_reference.cpython-39.pyc,,
openpyxl/workbook/__pycache__/function_group.cpython-39.pyc,,
openpyxl/workbook/__pycache__/properties.cpython-39.pyc,,
openpyxl/workbook/__pycache__/protection.cpython-39.pyc,,
openpyxl/workbook/__pycache__/smart_tags.cpython-39.pyc,,
openpyxl/workbook/__pycache__/views.cpython-39.pyc,,
openpyxl/workbook/__pycache__/web.cpython-39.pyc,,
openpyxl/workbook/__pycache__/workbook.cpython-39.pyc,,
openpyxl/workbook/_writer.py,sha256=rddZuAmxptpRh4uhjQl-1jeJF07wO91oCt3pyvYoJZU,6537
openpyxl/workbook/child.py,sha256=HfXNppjnjsdlECfcNaiTyHrthjvHxVR9T1Aiv0ICx6A,4060
openpyxl/workbook/defined_name.py,sha256=rubtJsPddvQ0In8P0APjidpKqUfl2F60NOj8wnMIPi8,7444
openpyxl/workbook/external_link/__init__.py,sha256=EXiVYDdHsQc36QgNBUyMfoLEXzhc-uYNtU7M8I2rQOg,71
openpyxl/workbook/external_link/__pycache__/__init__.cpython-39.pyc,,
openpyxl/workbook/external_link/__pycache__/external.cpython-39.pyc,,
openpyxl/workbook/external_link/external.py,sha256=GOlUBsxdeXlzxS5ifcOijDqwFnxZhflwIsXEUWfSD1Y,4555
openpyxl/workbook/external_reference.py,sha256=ECt6-vqhJRCMpWiDkrjpPoLbrnTxTbDwXgaP2YasaDI,348
openpyxl/workbook/function_group.py,sha256=W_jJtIljy6u5Tdh6qnrQ-aXPpPfk_4X0fz34XOWZu0g,803
openpyxl/workbook/properties.py,sha256=j56RvVtYZr-jxs4VyBHtCIDTTQN5znjk9UhEYM2ObgQ,5261
openpyxl/workbook/protection.py,sha256=tr-9WBLU4XMw2Fbjnt2H2wSoZXRsWty9LUm-zrIP1rY,6031
openpyxl/workbook/smart_tags.py,sha256=280qvvXX5gaxpxNFIGPu2-v9GMWXZwmw7yqlbBfib0o,1181
openpyxl/workbook/views.py,sha256=n7L8Ca-ePuPmqUbqSG4LbiMz3lLKiOijngYA4Krwv74,5214
openpyxl/workbook/web.py,sha256=9aBRZJbzblD5X1ccys23n92zX2AnhA3S5SdUa6-0E7w,2642
openpyxl/workbook/workbook.py,sha256=7XRflZNTCU-oQ6YigaZYVts9jep0GUK4INf5GjXv-gQ,13948
openpyxl/worksheet/__init__.py,sha256=C431i_Ek0iWxSP_jixBAabUFuCJ-3T3ESB-MEY21epw,35
openpyxl/worksheet/__pycache__/__init__.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/_read_only.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/_reader.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/_write_only.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/_writer.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/cell_range.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/cell_watch.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/controls.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/copier.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/custom.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/datavalidation.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/dimensions.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/drawing.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/errors.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/filters.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/header_footer.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/hyperlink.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/merge.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/ole.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/page.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/pagebreak.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/picture.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/properties.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/protection.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/related.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/scenario.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/smart_tag.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/table.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/views.cpython-39.pyc,,
openpyxl/worksheet/__pycache__/worksheet.cpython-39.pyc,,
openpyxl/worksheet/_read_only.py,sha256=zT2SdyLb2ZQO5Mh5EWUsUCpuIkCGn786EmdbJ-ojyms,5439
openpyxl/worksheet/_reader.py,sha256=KADKaQLN1fle3chk8LKzYzlzLItIQnHEM29MHOtpQuI,15856
openpyxl/worksheet/_write_only.py,sha256=Fydke8dkCnGq3KJDxWHC3ZrbCOcV_WAkgTeN4R1saaw,4256
openpyxl/worksheet/_writer.py,sha256=3qxPExZWpdSzs5t-KICBNMxqfdV8usKrsp3sv-85K-o,10318
openpyxl/worksheet/cell_range.py,sha256=SkSDqISNDMpVTJWHifJZCeNxGcdzjpEcq_3AUayVe8c,14642
openpyxl/worksheet/cell_watch.py,sha256=LdxGcTmXbZ4sxm6inasFgZPld1ijdL5_ODSUvvz13DU,608
openpyxl/worksheet/controls.py,sha256=xw1ctipJCdjPDLhELRpJjh0aX5Q5KMMELKqLBABC0Gk,2735
openpyxl/worksheet/copier.py,sha256=b04yP2jHolt4qtVMwmCLEbJ1dq7X9bGb2UsJOMb6Y8s,2327
openpyxl/worksheet/custom.py,sha256=CRlQ98GwqqKmEDkv8gPUCa0ApNM2Vz-BLs_-RMu3jLA,639
openpyxl/worksheet/datavalidation.py,sha256=8h-Bg8Xbd_L2S-I8w5nBUU137S8tsjDTXuKywQ4Jo2I,6136
openpyxl/worksheet/dimensions.py,sha256=EZkNxkAwhDlcyJ2UL8My2Sarm54QPNHkUT2hfUYFDSE,8877
openpyxl/worksheet/drawing.py,sha256=wqz6I8g7DyZgd-K8JjuqUJYeRzVJCqcrROnFkNXW4K8,275
openpyxl/worksheet/errors.py,sha256=KkFC4bnckvCp74XsVXA7JUCi4MIimEFu3uAddcQpjo0,2435
openpyxl/worksheet/filters.py,sha256=zRo479MYRiSuTLYotZuAQKBUX7UL3SGlMYxZY_LUk10,10814
openpyxl/worksheet/header_footer.py,sha256=e8baJAetr9EDwc22iZ6Yw82BD0rQv61K4ldE_BEMRng,7886
openpyxl/worksheet/hyperlink.py,sha256=j4D98tw6TDEB-KsYRxlnCevaQg-zcNYDsCL8eRX11KY,1391
openpyxl/worksheet/merge.py,sha256=MuolhcXe5n3_ZoWa6lmDnhVJV-bSyI4QCJ7Q_pu220M,4140
openpyxl/worksheet/ole.py,sha256=7kJAf077bd_bAErjMxI_8SKBAESD9vgxOKojfEPBAaw,3530
openpyxl/worksheet/page.py,sha256=YEQSycU12rLi6r0B49NkzqOwrr8gmTd6lQ1EvnMslMc,4920
openpyxl/worksheet/pagebreak.py,sha256=Qc83q67o3mwkr3jIvPO_RjsVMkThXvf0ghNqa5QEYO8,1811
openpyxl/worksheet/picture.py,sha256=72TctCxzk2JU8uFfjiEbTBufEe5eQxIieSPBRhU6m1Q,185
openpyxl/worksheet/properties.py,sha256=KAL6M0PGdnYS1A7H3X-uuOV70tVwIYAjnOdH8HLJ00E,3087
openpyxl/worksheet/protection.py,sha256=hQGagSq3SmXEsSyMSuVCMl5jNmyJvxHXoU5rYjVZRX4,3787
openpyxl/worksheet/related.py,sha256=VMAfTmQ-Rv0S_eAFaG02hofoLrecuF9Wk4JSEPFmPsA,348
openpyxl/worksheet/scenario.py,sha256=bYh2uOE5yzTeTymNQNT8Box_PdMuHRccFOpAs6VyBdw,2401
openpyxl/worksheet/smart_tag.py,sha256=nLbt04IqeJllk7TmNS1eTNdb7On5jMf3llfyy3otDSk,1608
openpyxl/worksheet/table.py,sha256=z88TiQybtbjiKvNx4NL8Rm40c63g2zxjlwt4v8c6m78,11716
openpyxl/worksheet/views.py,sha256=TfgCdEMCNr8-qOTpJ-iRmt4MBWgni_OagqfzRUC-Stc,4632
openpyxl/worksheet/worksheet.py,sha256=J4YwSgqO-OQmik5f7nfQxezPIdW39kotT1NTqPy6VUU,27473
openpyxl/writer/__init__.py,sha256=C431i_Ek0iWxSP_jixBAabUFuCJ-3T3ESB-MEY21epw,35
openpyxl/writer/__pycache__/__init__.cpython-39.pyc,,
openpyxl/writer/__pycache__/excel.cpython-39.pyc,,
openpyxl/writer/__pycache__/theme.cpython-39.pyc,,
openpyxl/writer/excel.py,sha256=ZRrHP_eMSZ4PdRYW_nwruF-HH3heVe3uohQWMx4O-_E,9854
openpyxl/writer/theme.py,sha256=cPZepfx2NiU3ONndCaVwpXDSGWl-EKhgdLQtVq8VHvY,10320
openpyxl/xml/__init__.py,sha256=YGR_-Pq3vdU9VmItEzkOLfjCPO1BMivPWvPH0_uwuqw,1016
openpyxl/xml/__pycache__/__init__.cpython-39.pyc,,
openpyxl/xml/__pycache__/constants.cpython-39.pyc,,
openpyxl/xml/__pycache__/functions.cpython-39.pyc,,
openpyxl/xml/constants.py,sha256=lgyd3712Dsl5KutfUZywwl9bj1z2V3x917umj9N7cFw,4546
openpyxl/xml/functions.py,sha256=f3knJ6x0TRsF8YU6iVjnCLu9OdZLk7atyOSMT7dQIok,1929

View File

@ -0,0 +1,6 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.36.2)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

View File

@ -0,0 +1 @@
openpyxl

View File

@ -0,0 +1,18 @@
# Copyright (c) 2010-2021 openpyxl
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__

View File

@ -0,0 +1,13 @@
# Copyright (c) 2010-2021 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.0.9"
__python__ = "3.6"

View File

@ -0,0 +1,4 @@
# Copyright (c) 2010-2021 openpyxl
from .cell import Cell, WriteOnlyCell, MergedCell
from .read_only import ReadOnlyCell

View File

@ -0,0 +1,108 @@
# Copyright (c) 2010-2021 openpyxl
from openpyxl.compat import safe_string
from openpyxl.xml.functions import Element, SubElement, whitespace, XML_NS, REL_NS
from openpyxl import LXML
from openpyxl.utils.datetime import to_excel, to_ISO8601
from datetime import timedelta
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':
shared_formula = worksheet.formula_attributes.get(cell.coordinate, {})
formula = SubElement(el, 'f', shared_formula)
if value is not None:
formula.text = value[1:]
value = None
if cell.data_type == 's':
inline_string = SubElement(el, 'is')
text = SubElement(inline_string, 't')
text.text = value
whitespace(text)
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':
shared_formula = worksheet.formula_attributes.get(cell.coordinate, {})
with xf.element('f', shared_formula):
if value is not None:
xf.write(value[1:])
value = None
if cell.data_type == 's':
with xf.element("is"):
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)
#with xf.element("t", attrs):
#xf.write(value)
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

View File

@ -0,0 +1,329 @@
# Copyright (c) 2010-2021 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,
deprecated,
)
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
# 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)
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'
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(Cell, self).__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
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":
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(MergedCell, self).__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)

View File

@ -0,0 +1,136 @@
# Copyright (c) 2010-2021 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(object):
__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(object):
__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()

View File

@ -0,0 +1,184 @@
# Copyright (c) 2010-2021 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)

View File

@ -0,0 +1,105 @@
# Copyright (c) 2010-2021 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__()

View File

@ -0,0 +1,19 @@
# Copyright (c) 2010-2021 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

View File

@ -0,0 +1,196 @@
# Copyright (c) 2010-2021 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'])
_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)
__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
super(ChartBase, self).__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(ChartBase, self).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
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)

View File

@ -0,0 +1,106 @@
# Copyright (c) 2010-2021 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(_AreaChartBase, self).__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(AreaChart, self).__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()

View File

@ -0,0 +1,401 @@
# Copyright (c) 2010-2021 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(NumericAxis, self).__init__(**kw)
@classmethod
def from_tree(cls, node):
"""
Special case value axes with no gridlines
"""
self = super(NumericAxis, cls).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(TextAxis, self).__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(DateAxis, self).__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(SeriesAxis, self).__init__(**kw)

View File

@ -0,0 +1,144 @@
# Copyright (c) 2010-2021 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(_BarChartBase, self).__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(BarChart, self).__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)

View 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(BubbleChart, self).__init__(**kw)

View File

@ -0,0 +1,195 @@
from __future__ import absolute_import
# Copyright (c) 2010-2021 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)
graphicalProperties = 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(ChartSpace, self).to_tree()
tree.set("xmlns", CHART_NS)
return tree

View 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(NumberValueDescriptor, self).__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

View File

@ -0,0 +1,43 @@
# Copyright (c) 2010-2021 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(NumberFormatDescriptor, self).__set__(instance, value)

View File

@ -0,0 +1,62 @@
# Copyright (c) 2010-2021 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

View File

@ -0,0 +1,127 @@
# Copyright (c) 2010-2021 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(DataLabel, self).__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(DataLabelList, self).__init__(**kw)

View File

@ -0,0 +1,74 @@
# Copyright (c) 2010-2021 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

View File

@ -0,0 +1,75 @@
# Copyright (c) 2010-2021 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

View 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(_LineChartBase, self).__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(LineChart, self).__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)

View File

@ -0,0 +1,90 @@
# Copyright (c) 2010-2021 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

View File

@ -0,0 +1,35 @@
# Copyright (c) 2010-2021 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

View 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(_PieChartBase, self).__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(PieChart, self).__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(DoughnutChart, self).__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(ProjectedPieChart, self).__init__(**kw)

View File

@ -0,0 +1,65 @@
from __future__ import absolute_import
# Copyright (c) 2010-2021 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

View File

@ -0,0 +1,162 @@
# Copyright (c) 2010-2021 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(PlotArea, self).to_tree(tagname)
@classmethod
def from_tree(cls, node):
self = super(PlotArea, cls).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

View File

@ -0,0 +1,57 @@
# Copyright (c) 2010-2021 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

View File

@ -0,0 +1,55 @@
# Copyright (c) 2010-2021 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(RadarChart, self).__init__(**kw)

View File

@ -0,0 +1,29 @@
# Copyright (c) 2010-2021 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()
return chart

View File

@ -0,0 +1,124 @@
# Copyright (c) 2010-2021 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)

View File

@ -0,0 +1,53 @@
# Copyright (c) 2010-2021 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
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)
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(ScatterChart, self).__init__(**kw)

View File

@ -0,0 +1,197 @@
# Copyright (c) 2010-2021 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(Series, self).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

View File

@ -0,0 +1,41 @@
# Copyright (c) 2010-2021 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

View File

@ -0,0 +1,89 @@
# Copyright (c) 2010-2021 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

View File

@ -0,0 +1,54 @@
# Copyright (c) 2010-2021 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(StockChart, self).__init__(**kw)

View File

@ -0,0 +1,119 @@
# Copyright (c) 2010-2021 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(_SurfaceChartBase, self).__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(SurfaceChart, self).__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

View File

@ -0,0 +1,78 @@
# Copyright (c) 2010-2021 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(Text, self).to_tree(tagname, idx, namespace)

View File

@ -0,0 +1,76 @@
# Copyright (c) 2010-2021 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(TitleDescriptor, self).__set__(instance, value)

Some files were not shown because too many files have changed in this diff Show More