mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-07-02 06:22:25 +00:00
Version 0.1
Added sidebar, Dashboard, Line Graph
This commit is contained in:
4
.venv/Lib/site-packages/openpyxl/workbook/__init__.py
Normal file
4
.venv/Lib/site-packages/openpyxl/workbook/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
|
||||
from .workbook import Workbook
|
191
.venv/Lib/site-packages/openpyxl/workbook/_writer.py
Normal file
191
.venv/Lib/site-packages/openpyxl/workbook/_writer.py
Normal file
@ -0,0 +1,191 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
"""Write the workbook global settings to the archive."""
|
||||
|
||||
from copy import copy
|
||||
|
||||
from openpyxl.utils import absolute_coordinate, quote_sheetname
|
||||
from openpyxl.xml.constants import (
|
||||
ARC_APP,
|
||||
ARC_CORE,
|
||||
ARC_WORKBOOK,
|
||||
PKG_REL_NS,
|
||||
CUSTOMUI_NS,
|
||||
ARC_ROOT_RELS,
|
||||
)
|
||||
from openpyxl.xml.functions import tostring, fromstring
|
||||
|
||||
from openpyxl.packaging.relationship import Relationship, RelationshipList
|
||||
from openpyxl.workbook.defined_name import DefinedName
|
||||
from openpyxl.workbook.external_reference import ExternalReference
|
||||
from openpyxl.packaging.workbook import ChildSheet, WorkbookPackage, PivotCache
|
||||
from openpyxl.workbook.properties import WorkbookProperties
|
||||
from openpyxl.utils.datetime import CALENDAR_MAC_1904
|
||||
|
||||
|
||||
def get_active_sheet(wb):
|
||||
"""
|
||||
Return the index of the active sheet.
|
||||
If the sheet set to active is hidden return the next visible sheet or None
|
||||
"""
|
||||
visible_sheets = [idx for idx, sheet in enumerate(wb._sheets) if sheet.sheet_state == "visible"]
|
||||
if not visible_sheets:
|
||||
raise IndexError("At least one sheet must be visible")
|
||||
|
||||
idx = wb._active_sheet_index
|
||||
sheet = wb.active
|
||||
if sheet and sheet.sheet_state == "visible":
|
||||
return idx
|
||||
|
||||
for idx in visible_sheets[idx:]:
|
||||
wb.active = idx
|
||||
return idx
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class WorkbookWriter:
|
||||
|
||||
def __init__(self, wb):
|
||||
self.wb = wb
|
||||
self.rels = RelationshipList()
|
||||
self.package = WorkbookPackage()
|
||||
self.package.workbookProtection = wb.security
|
||||
self.package.calcPr = wb.calculation
|
||||
|
||||
|
||||
def write_properties(self):
|
||||
|
||||
props = WorkbookProperties() # needs a mapping to the workbook for preservation
|
||||
if self.wb.code_name is not None:
|
||||
props.codeName = self.wb.code_name
|
||||
if self.wb.excel_base_date == CALENDAR_MAC_1904:
|
||||
props.date1904 = True
|
||||
self.package.workbookPr = props
|
||||
|
||||
|
||||
def write_worksheets(self):
|
||||
for idx, sheet in enumerate(self.wb._sheets, 1):
|
||||
sheet_node = ChildSheet(name=sheet.title, sheetId=idx, id="rId{0}".format(idx))
|
||||
rel = Relationship(type=sheet._rel_type, Target=sheet.path)
|
||||
self.rels.append(rel)
|
||||
|
||||
if not sheet.sheet_state == 'visible':
|
||||
if len(self.wb._sheets) == 1:
|
||||
raise ValueError("The only worksheet of a workbook cannot be hidden")
|
||||
sheet_node.state = sheet.sheet_state
|
||||
self.package.sheets.append(sheet_node)
|
||||
|
||||
|
||||
def write_refs(self):
|
||||
for link in self.wb._external_links:
|
||||
# need to match a counter with a workbook's relations
|
||||
rId = len(self.wb.rels) + 1
|
||||
rel = Relationship(type=link._rel_type, Target=link.path)
|
||||
self.rels.append(rel)
|
||||
ext = ExternalReference(id=rel.id)
|
||||
self.package.externalReferences.append(ext)
|
||||
|
||||
|
||||
def write_names(self):
|
||||
defined_names = copy(self.wb.defined_names)
|
||||
|
||||
# Defined names -> autoFilter
|
||||
for idx, sheet in enumerate(self.wb.worksheets):
|
||||
auto_filter = sheet.auto_filter.ref
|
||||
|
||||
if auto_filter:
|
||||
name = DefinedName(name='_FilterDatabase', localSheetId=idx, hidden=True)
|
||||
name.value = u"{0}!{1}".format(quote_sheetname(sheet.title),
|
||||
absolute_coordinate(auto_filter)
|
||||
)
|
||||
defined_names.append(name)
|
||||
|
||||
# print titles
|
||||
if sheet.print_titles:
|
||||
name = DefinedName(name="Print_Titles", localSheetId=idx)
|
||||
name.value = ",".join([u"{0}!{1}".format(quote_sheetname(sheet.title), r)
|
||||
for r in sheet.print_titles.split(",")])
|
||||
defined_names.append(name)
|
||||
|
||||
# print areas
|
||||
if sheet.print_area:
|
||||
name = DefinedName(name="Print_Area", localSheetId=idx)
|
||||
name.value = ",".join([u"{0}!{1}".format(quote_sheetname(sheet.title), r)
|
||||
for r in sheet.print_area])
|
||||
defined_names.append(name)
|
||||
|
||||
self.package.definedNames = defined_names
|
||||
|
||||
|
||||
def write_pivots(self):
|
||||
pivot_caches = set()
|
||||
for pivot in self.wb._pivots:
|
||||
if pivot.cache not in pivot_caches:
|
||||
pivot_caches.add(pivot.cache)
|
||||
c = PivotCache(cacheId=pivot.cacheId)
|
||||
self.package.pivotCaches.append(c)
|
||||
rel = Relationship(Type=pivot.cache.rel_type, Target=pivot.cache.path)
|
||||
self.rels.append(rel)
|
||||
c.id = rel.id
|
||||
#self.wb._pivots = [] # reset
|
||||
|
||||
|
||||
def write_views(self):
|
||||
active = get_active_sheet(self.wb)
|
||||
if self.wb.views:
|
||||
self.wb.views[0].activeTab = active
|
||||
self.package.bookViews = self.wb.views
|
||||
|
||||
|
||||
def write(self):
|
||||
"""Write the core workbook xml."""
|
||||
|
||||
self.write_properties()
|
||||
self.write_worksheets()
|
||||
self.write_names()
|
||||
self.write_pivots()
|
||||
self.write_views()
|
||||
self.write_refs()
|
||||
|
||||
return tostring(self.package.to_tree())
|
||||
|
||||
|
||||
def write_rels(self):
|
||||
"""Write the workbook relationships xml."""
|
||||
|
||||
styles = Relationship(type='styles', Target='styles.xml')
|
||||
self.rels.append(styles)
|
||||
|
||||
theme = Relationship(type='theme', Target='theme/theme1.xml')
|
||||
self.rels.append(theme)
|
||||
|
||||
if self.wb.vba_archive:
|
||||
vba = Relationship(type='', Target='vbaProject.bin')
|
||||
vba.Type ='http://schemas.microsoft.com/office/2006/relationships/vbaProject'
|
||||
self.rels.append(vba)
|
||||
|
||||
return tostring(self.rels.to_tree())
|
||||
|
||||
|
||||
def write_root_rels(self):
|
||||
"""Write the package relationships"""
|
||||
|
||||
rels = RelationshipList()
|
||||
|
||||
rel = Relationship(type="officeDocument", Target=ARC_WORKBOOK)
|
||||
rels.append(rel)
|
||||
rel = Relationship(Type=f"{PKG_REL_NS}/metadata/core-properties", Target=ARC_CORE)
|
||||
rels.append(rel)
|
||||
|
||||
rel = Relationship(type="extended-properties", Target=ARC_APP)
|
||||
rels.append(rel)
|
||||
|
||||
if self.wb.vba_archive is not None:
|
||||
# See if there was a customUI relation and reuse it
|
||||
xml = fromstring(self.wb.vba_archive.read(ARC_ROOT_RELS))
|
||||
root_rels = RelationshipList.from_tree(xml)
|
||||
for rel in root_rels.find(CUSTOMUI_NS):
|
||||
rels.append(rel)
|
||||
|
||||
return tostring(rels.to_tree())
|
166
.venv/Lib/site-packages/openpyxl/workbook/child.py
Normal file
166
.venv/Lib/site-packages/openpyxl/workbook/child.py
Normal file
@ -0,0 +1,166 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
import re
|
||||
import warnings
|
||||
|
||||
from openpyxl.worksheet.header_footer import HeaderFooter
|
||||
|
||||
"""
|
||||
Base class for worksheets, chartsheets, etc. that can be added to workbooks
|
||||
"""
|
||||
|
||||
INVALID_TITLE_REGEX = re.compile(r'[\\*?:/\[\]]')
|
||||
|
||||
|
||||
def avoid_duplicate_name(names, value):
|
||||
"""
|
||||
Naive check to see whether name already exists.
|
||||
If name does exist suggest a name using an incrementer
|
||||
Duplicates are case insensitive
|
||||
"""
|
||||
# Check for an absolute match in which case we need to find an alternative
|
||||
match = [n for n in names if n.lower() == value.lower()]
|
||||
if match:
|
||||
names = u",".join(names)
|
||||
sheet_title_regex = re.compile(f'(?P<title>{re.escape(value)})(?P<count>\\d*),?', re.I)
|
||||
matches = sheet_title_regex.findall(names)
|
||||
if matches:
|
||||
# use name, but append with the next highest integer
|
||||
counts = [int(idx) for (t, idx) in matches if idx.isdigit()]
|
||||
highest = 0
|
||||
if counts:
|
||||
highest = max(counts)
|
||||
value = u"{0}{1}".format(value, highest + 1)
|
||||
return value
|
||||
|
||||
|
||||
class _WorkbookChild(object):
|
||||
|
||||
__title = ""
|
||||
_id = None
|
||||
_path = "{0}"
|
||||
_parent = None
|
||||
_default_title = "Sheet"
|
||||
|
||||
def __init__(self, parent=None, title=None):
|
||||
self._parent = parent
|
||||
self.title = title or self._default_title
|
||||
self.HeaderFooter = HeaderFooter()
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return '<{0} "{1}">'.format(self.__class__.__name__, self.title)
|
||||
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return self._parent
|
||||
|
||||
|
||||
@property
|
||||
def encoding(self):
|
||||
return self._parent.encoding
|
||||
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
return self.__title
|
||||
|
||||
|
||||
@title.setter
|
||||
def title(self, value):
|
||||
"""
|
||||
Set a sheet title, ensuring it is valid.
|
||||
Limited to 31 characters, no special characters.
|
||||
Duplicate titles will be incremented numerically
|
||||
"""
|
||||
if not self._parent:
|
||||
return
|
||||
|
||||
if not value:
|
||||
raise ValueError("Title must have at least one character")
|
||||
|
||||
if hasattr(value, "decode"):
|
||||
if not isinstance(value, str):
|
||||
try:
|
||||
value = value.decode("ascii")
|
||||
except UnicodeDecodeError:
|
||||
raise ValueError("Worksheet titles must be str")
|
||||
|
||||
m = INVALID_TITLE_REGEX.search(value)
|
||||
if m:
|
||||
msg = "Invalid character {0} found in sheet title".format(m.group(0))
|
||||
raise ValueError(msg)
|
||||
|
||||
if self.title is not None and self.title != value:
|
||||
value = avoid_duplicate_name(self.parent.sheetnames, value)
|
||||
|
||||
if len(value) > 31:
|
||||
warnings.warn("Title is more than 31 characters. Some applications may not be able to read the file")
|
||||
|
||||
self.__title = value
|
||||
|
||||
|
||||
@property
|
||||
def oddHeader(self):
|
||||
return self.HeaderFooter.oddHeader
|
||||
|
||||
|
||||
@oddHeader.setter
|
||||
def oddHeader(self, value):
|
||||
self.HeaderFooter.oddHeader = value
|
||||
|
||||
|
||||
@property
|
||||
def oddFooter(self):
|
||||
return self.HeaderFooter.oddFooter
|
||||
|
||||
|
||||
@oddFooter.setter
|
||||
def oddFooter(self, value):
|
||||
self.HeaderFooter.oddFooter = value
|
||||
|
||||
|
||||
@property
|
||||
def evenHeader(self):
|
||||
return self.HeaderFooter.evenHeader
|
||||
|
||||
|
||||
@evenHeader.setter
|
||||
def evenHeader(self, value):
|
||||
self.HeaderFooter.evenHeader = value
|
||||
|
||||
|
||||
@property
|
||||
def evenFooter(self):
|
||||
return self.HeaderFooter.evenFooter
|
||||
|
||||
|
||||
@evenFooter.setter
|
||||
def evenFooter(self, value):
|
||||
self.HeaderFooter.evenFooter = value
|
||||
|
||||
|
||||
@property
|
||||
def firstHeader(self):
|
||||
return self.HeaderFooter.firstHeader
|
||||
|
||||
|
||||
@firstHeader.setter
|
||||
def firstHeader(self, value):
|
||||
self.HeaderFooter.firstHeader = value
|
||||
|
||||
|
||||
@property
|
||||
def firstFooter(self):
|
||||
return self.HeaderFooter.firstFooter
|
||||
|
||||
|
||||
@firstFooter.setter
|
||||
def firstFooter(self, value):
|
||||
self.HeaderFooter.firstFooter = value
|
||||
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return self._path.format(self._id)
|
266
.venv/Lib/site-packages/openpyxl/workbook/defined_name.py
Normal file
266
.venv/Lib/site-packages/openpyxl/workbook/defined_name.py
Normal file
@ -0,0 +1,266 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
import re
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Alias,
|
||||
Typed,
|
||||
String,
|
||||
Float,
|
||||
Integer,
|
||||
Bool,
|
||||
NoneSet,
|
||||
Set,
|
||||
Sequence,
|
||||
Descriptor,
|
||||
)
|
||||
from openpyxl.compat import safe_string
|
||||
from openpyxl.formula import Tokenizer
|
||||
from openpyxl.utils.cell import (
|
||||
SHEETRANGE_RE,
|
||||
SHEET_TITLE,
|
||||
)
|
||||
|
||||
RESERVED = frozenset(["Print_Area", "Print_Titles", "Criteria",
|
||||
"_FilterDatabase", "Extract", "Consolidate_Area",
|
||||
"Sheet_Title"])
|
||||
|
||||
_names = "|".join(RESERVED)
|
||||
RESERVED_REGEX = re.compile(r"^_xlnm\.(?P<name>{0})".format(_names))
|
||||
COL_RANGE = r"""(?P<cols>[$]?[a-zA-Z]{1,3}:[$]?[a-zA-Z]{1,3})"""
|
||||
COL_RANGE_RE = re.compile(COL_RANGE)
|
||||
ROW_RANGE = r"""(?P<rows>[$]?\d+:[$]?\d+)"""
|
||||
ROW_RANGE_RE = re.compile(ROW_RANGE)
|
||||
TITLES_REGEX = re.compile("""{0}{1}?,?{2}?""".format(SHEET_TITLE, ROW_RANGE, COL_RANGE),
|
||||
re.VERBOSE)
|
||||
|
||||
|
||||
### utilities
|
||||
|
||||
def _unpack_print_titles(defn):
|
||||
"""
|
||||
Extract rows and or columns from print titles so that they can be
|
||||
assigned to a worksheet
|
||||
"""
|
||||
scanner = TITLES_REGEX.finditer(defn.value)
|
||||
kw = dict((k, v) for match in scanner
|
||||
for k, v in match.groupdict().items() if v)
|
||||
|
||||
return kw.get('rows'), kw.get('cols')
|
||||
|
||||
|
||||
def _unpack_print_area(defn):
|
||||
"""
|
||||
Extract print area
|
||||
"""
|
||||
new = []
|
||||
for m in SHEETRANGE_RE.finditer(defn.value): # can be multiple
|
||||
coord = m.group("cells")
|
||||
if coord:
|
||||
new.append(coord)
|
||||
return new
|
||||
|
||||
|
||||
class DefinedName(Serialisable):
|
||||
|
||||
tagname = "definedName"
|
||||
|
||||
name = String() # unique per workbook/worksheet
|
||||
comment = String(allow_none=True)
|
||||
customMenu = String(allow_none=True)
|
||||
description = String(allow_none=True)
|
||||
help = String(allow_none=True)
|
||||
statusBar = String(allow_none=True)
|
||||
localSheetId = Integer(allow_none=True)
|
||||
hidden = Bool(allow_none=True)
|
||||
function = Bool(allow_none=True)
|
||||
vbProcedure = Bool(allow_none=True)
|
||||
xlm = Bool(allow_none=True)
|
||||
functionGroupId = Integer(allow_none=True)
|
||||
shortcutKey = String(allow_none=True)
|
||||
publishToServer = Bool(allow_none=True)
|
||||
workbookParameter = Bool(allow_none=True)
|
||||
attr_text = Descriptor()
|
||||
value = Alias("attr_text")
|
||||
|
||||
|
||||
def __init__(self,
|
||||
name=None,
|
||||
comment=None,
|
||||
customMenu=None,
|
||||
description=None,
|
||||
help=None,
|
||||
statusBar=None,
|
||||
localSheetId=None,
|
||||
hidden=None,
|
||||
function=None,
|
||||
vbProcedure=None,
|
||||
xlm=None,
|
||||
functionGroupId=None,
|
||||
shortcutKey=None,
|
||||
publishToServer=None,
|
||||
workbookParameter=None,
|
||||
attr_text=None
|
||||
):
|
||||
self.name = name
|
||||
self.comment = comment
|
||||
self.customMenu = customMenu
|
||||
self.description = description
|
||||
self.help = help
|
||||
self.statusBar = statusBar
|
||||
self.localSheetId = localSheetId
|
||||
self.hidden = hidden
|
||||
self.function = function
|
||||
self.vbProcedure = vbProcedure
|
||||
self.xlm = xlm
|
||||
self.functionGroupId = functionGroupId
|
||||
self.shortcutKey = shortcutKey
|
||||
self.publishToServer = publishToServer
|
||||
self.workbookParameter = workbookParameter
|
||||
self.attr_text = attr_text
|
||||
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
tok = Tokenizer("=" + self.value)
|
||||
parsed = tok.items[0]
|
||||
if parsed.type == "OPERAND":
|
||||
return parsed.subtype
|
||||
return parsed.type
|
||||
|
||||
|
||||
@property
|
||||
def destinations(self):
|
||||
if self.type == "RANGE":
|
||||
tok = Tokenizer("=" + self.value)
|
||||
for part in tok.items:
|
||||
if part.subtype == "RANGE":
|
||||
m = SHEETRANGE_RE.match(part.value)
|
||||
sheetname = m.group('notquoted') or m.group('quoted')
|
||||
yield sheetname, m.group('cells')
|
||||
|
||||
|
||||
@property
|
||||
def is_reserved(self):
|
||||
m = RESERVED_REGEX.match(self.name)
|
||||
if m:
|
||||
return m.group("name")
|
||||
|
||||
|
||||
@property
|
||||
def is_external(self):
|
||||
return re.compile(r"^\[\d+\].*").match(self.value) is not None
|
||||
|
||||
|
||||
def __iter__(self):
|
||||
for key in self.__attrs__:
|
||||
if key == "attr_text":
|
||||
continue
|
||||
v = getattr(self, key)
|
||||
if v is not None:
|
||||
if v in RESERVED:
|
||||
v = "_xlnm." + v
|
||||
yield key, safe_string(v)
|
||||
|
||||
|
||||
class DefinedNameList(Serialisable):
|
||||
|
||||
tagname = "definedNames"
|
||||
|
||||
definedName = Sequence(expected_type=DefinedName)
|
||||
|
||||
|
||||
def __init__(self, definedName=()):
|
||||
self.definedName = definedName
|
||||
|
||||
|
||||
def _cleanup(self):
|
||||
"""
|
||||
Strip invalid definitions and remove special hidden ones
|
||||
"""
|
||||
valid_names = []
|
||||
for n in self.definedName:
|
||||
if n.name in ("_xlnm.Print_Titles", "_xlnm.Print_Area") and n.localSheetId is None:
|
||||
continue
|
||||
elif n.name == "_xlnm._FilterDatabase":
|
||||
continue
|
||||
valid_names.append(n)
|
||||
self.definedName = valid_names
|
||||
|
||||
|
||||
def _duplicate(self, defn):
|
||||
"""
|
||||
Check for whether DefinedName with the same name and scope already
|
||||
exists
|
||||
"""
|
||||
for d in self.definedName:
|
||||
if d.name == defn.name and d.localSheetId == defn.localSheetId:
|
||||
return True
|
||||
|
||||
|
||||
def append(self, defn):
|
||||
if not isinstance(defn, DefinedName):
|
||||
raise TypeError("""You can only append DefinedNames""")
|
||||
if self._duplicate(defn):
|
||||
raise ValueError("""DefinedName with the same name and scope already exists""")
|
||||
names = self.definedName[:]
|
||||
names.append(defn)
|
||||
self.definedName = names
|
||||
|
||||
|
||||
def __len__(self):
|
||||
return len(self.definedName)
|
||||
|
||||
|
||||
def __contains__(self, name):
|
||||
"""
|
||||
See if a globaly defined name exists
|
||||
"""
|
||||
for defn in self.definedName:
|
||||
if defn.name == name and defn.localSheetId is None:
|
||||
return True
|
||||
|
||||
|
||||
def __getitem__(self, name):
|
||||
"""
|
||||
Get globally defined name
|
||||
"""
|
||||
defn = self.get(name)
|
||||
if not defn:
|
||||
raise KeyError("No definition called {0}".format(name))
|
||||
return defn
|
||||
|
||||
|
||||
def get(self, name, scope=None):
|
||||
"""
|
||||
Get the name assigned to a specicic sheet or global
|
||||
"""
|
||||
for defn in self.definedName:
|
||||
if defn.name == name and defn.localSheetId == scope:
|
||||
return defn
|
||||
|
||||
|
||||
def __delitem__(self, name):
|
||||
"""
|
||||
Delete a globally defined name
|
||||
"""
|
||||
if not self.delete(name):
|
||||
raise KeyError("No globally defined name {0}".format(name))
|
||||
|
||||
|
||||
def delete(self, name, scope=None):
|
||||
"""
|
||||
Delete a name assigned to a specific or global
|
||||
"""
|
||||
for idx, defn in enumerate(self.definedName):
|
||||
if defn.name == name and defn.localSheetId == scope:
|
||||
del self.definedName[idx]
|
||||
return True
|
||||
|
||||
|
||||
def localnames(self, scope):
|
||||
"""
|
||||
Provide a list of all names for a particular worksheet
|
||||
"""
|
||||
return [defn.name for defn in self.definedName if defn.localSheetId == scope]
|
@ -0,0 +1,3 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
from .external import ExternalLink
|
@ -0,0 +1,190 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
String,
|
||||
Bool,
|
||||
Integer,
|
||||
NoneSet,
|
||||
Sequence,
|
||||
)
|
||||
from openpyxl.descriptors.excel import Relation, ExtensionList
|
||||
from openpyxl.descriptors.nested import NestedText
|
||||
from openpyxl.descriptors.sequence import NestedSequence, ValueSequence
|
||||
|
||||
from openpyxl.packaging.relationship import (
|
||||
Relationship,
|
||||
get_rels_path,
|
||||
get_dependents
|
||||
)
|
||||
from openpyxl.xml.constants import SHEET_MAIN_NS
|
||||
from openpyxl.xml.functions import fromstring
|
||||
|
||||
|
||||
"""Manage links to external Workbooks"""
|
||||
|
||||
|
||||
class ExternalCell(Serialisable):
|
||||
|
||||
r = String()
|
||||
t = NoneSet(values=(['b', 'd', 'n', 'e', 's', 'str', 'inlineStr']))
|
||||
vm = Integer(allow_none=True)
|
||||
v = NestedText(allow_none=True, expected_type=str)
|
||||
|
||||
def __init__(self,
|
||||
r=None,
|
||||
t=None,
|
||||
vm=None,
|
||||
v=None,
|
||||
):
|
||||
self.r = r
|
||||
self.t = t
|
||||
self.vm = vm
|
||||
self.v = v
|
||||
|
||||
|
||||
class ExternalRow(Serialisable):
|
||||
|
||||
r = Integer()
|
||||
cell = Sequence(expected_type=ExternalCell)
|
||||
|
||||
__elements__ = ('cell',)
|
||||
|
||||
def __init__(self,
|
||||
r=(),
|
||||
cell=None,
|
||||
):
|
||||
self.r = r
|
||||
self.cell = cell
|
||||
|
||||
|
||||
class ExternalSheetData(Serialisable):
|
||||
|
||||
sheetId = Integer()
|
||||
refreshError = Bool(allow_none=True)
|
||||
row = Sequence(expected_type=ExternalRow)
|
||||
|
||||
__elements__ = ('row',)
|
||||
|
||||
def __init__(self,
|
||||
sheetId=None,
|
||||
refreshError=None,
|
||||
row=(),
|
||||
):
|
||||
self.sheetId = sheetId
|
||||
self.refreshError = refreshError
|
||||
self.row = row
|
||||
|
||||
|
||||
class ExternalSheetDataSet(Serialisable):
|
||||
|
||||
sheetData = Sequence(expected_type=ExternalSheetData, )
|
||||
|
||||
__elements__ = ('sheetData',)
|
||||
|
||||
def __init__(self,
|
||||
sheetData=None,
|
||||
):
|
||||
self.sheetData = sheetData
|
||||
|
||||
|
||||
class ExternalSheetNames(Serialisable):
|
||||
|
||||
sheetName = ValueSequence(expected_type=str)
|
||||
|
||||
__elements__ = ('sheetName',)
|
||||
|
||||
def __init__(self,
|
||||
sheetName=(),
|
||||
):
|
||||
self.sheetName = sheetName
|
||||
|
||||
|
||||
class ExternalDefinedName(Serialisable):
|
||||
|
||||
tagname = "definedName"
|
||||
|
||||
name = String()
|
||||
refersTo = String(allow_none=True)
|
||||
sheetId = Integer(allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
name=None,
|
||||
refersTo=None,
|
||||
sheetId=None,
|
||||
):
|
||||
self.name = name
|
||||
self.refersTo = refersTo
|
||||
self.sheetId = sheetId
|
||||
|
||||
|
||||
class ExternalBook(Serialisable):
|
||||
|
||||
tagname = "externalBook"
|
||||
|
||||
sheetNames = Typed(expected_type=ExternalSheetNames, allow_none=True)
|
||||
definedNames = NestedSequence(expected_type=ExternalDefinedName)
|
||||
sheetDataSet = Typed(expected_type=ExternalSheetDataSet, allow_none=True)
|
||||
id = Relation()
|
||||
|
||||
__elements__ = ('sheetNames', 'definedNames', 'sheetDataSet')
|
||||
|
||||
def __init__(self,
|
||||
sheetNames=None,
|
||||
definedNames=(),
|
||||
sheetDataSet=None,
|
||||
id=None,
|
||||
):
|
||||
self.sheetNames = sheetNames
|
||||
self.definedNames = definedNames
|
||||
self.sheetDataSet = sheetDataSet
|
||||
self.id = id
|
||||
|
||||
|
||||
class ExternalLink(Serialisable):
|
||||
|
||||
tagname = "externalLink"
|
||||
|
||||
_id = None
|
||||
_path = "/xl/externalLinks/externalLink{0}.xml"
|
||||
_rel_type = "externalLink"
|
||||
mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml"
|
||||
|
||||
externalBook = Typed(expected_type=ExternalBook, allow_none=True)
|
||||
file_link = Typed(expected_type=Relationship, allow_none=True) # link to external file
|
||||
|
||||
__elements__ = ('externalBook', )
|
||||
|
||||
def __init__(self,
|
||||
externalBook=None,
|
||||
ddeLink=None,
|
||||
oleLink=None,
|
||||
extLst=None,
|
||||
):
|
||||
self.externalBook = externalBook
|
||||
# ignore other items for the moment.
|
||||
|
||||
|
||||
def to_tree(self):
|
||||
node = super(ExternalLink, self).to_tree()
|
||||
node.set("xmlns", SHEET_MAIN_NS)
|
||||
return node
|
||||
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return self._path.format(self._id)
|
||||
|
||||
|
||||
def read_external_link(archive, book_path):
|
||||
src = archive.read(book_path)
|
||||
node = fromstring(src)
|
||||
book = ExternalLink.from_tree(node)
|
||||
|
||||
link_path = get_rels_path(book_path)
|
||||
deps = get_dependents(archive, link_path)
|
||||
book.file_link = deps.Relationship[0]
|
||||
|
||||
return book
|
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Sequence
|
||||
)
|
||||
from openpyxl.descriptors.excel import (
|
||||
Relation,
|
||||
)
|
||||
|
||||
class ExternalReference(Serialisable):
|
||||
|
||||
tagname = "externalReference"
|
||||
|
||||
id = Relation()
|
||||
|
||||
def __init__(self, id):
|
||||
self.id = id
|
36
.venv/Lib/site-packages/openpyxl/workbook/function_group.py
Normal file
36
.venv/Lib/site-packages/openpyxl/workbook/function_group.py
Normal file
@ -0,0 +1,36 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Sequence,
|
||||
String,
|
||||
Integer,
|
||||
)
|
||||
|
||||
class FunctionGroup(Serialisable):
|
||||
|
||||
tagname = "functionGroup"
|
||||
|
||||
name = String()
|
||||
|
||||
def __init__(self,
|
||||
name=None,
|
||||
):
|
||||
self.name = name
|
||||
|
||||
|
||||
class FunctionGroupList(Serialisable):
|
||||
|
||||
tagname = "functionGroups"
|
||||
|
||||
builtInGroupCount = Integer(allow_none=True)
|
||||
functionGroup = Sequence(expected_type=FunctionGroup, allow_none=True)
|
||||
|
||||
__elements__ = ('functionGroup',)
|
||||
|
||||
def __init__(self,
|
||||
builtInGroupCount=16,
|
||||
functionGroup=(),
|
||||
):
|
||||
self.builtInGroupCount = builtInGroupCount
|
||||
self.functionGroup = functionGroup
|
151
.venv/Lib/site-packages/openpyxl/workbook/properties.py
Normal file
151
.venv/Lib/site-packages/openpyxl/workbook/properties.py
Normal file
@ -0,0 +1,151 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
String,
|
||||
Float,
|
||||
Integer,
|
||||
Bool,
|
||||
NoneSet,
|
||||
Set,
|
||||
)
|
||||
|
||||
from openpyxl.descriptors.excel import Guid
|
||||
|
||||
|
||||
class WorkbookProperties(Serialisable):
|
||||
|
||||
tagname = "workbookPr"
|
||||
|
||||
date1904 = Bool(allow_none=True)
|
||||
dateCompatibility = Bool(allow_none=True)
|
||||
showObjects = NoneSet(values=(['all', 'placeholders']))
|
||||
showBorderUnselectedTables = Bool(allow_none=True)
|
||||
filterPrivacy = Bool(allow_none=True)
|
||||
promptedSolutions = Bool(allow_none=True)
|
||||
showInkAnnotation = Bool(allow_none=True)
|
||||
backupFile = Bool(allow_none=True)
|
||||
saveExternalLinkValues = Bool(allow_none=True)
|
||||
updateLinks = NoneSet(values=(['userSet', 'never', 'always']))
|
||||
codeName = String(allow_none=True)
|
||||
hidePivotFieldList = Bool(allow_none=True)
|
||||
showPivotChartFilter = Bool(allow_none=True)
|
||||
allowRefreshQuery = Bool(allow_none=True)
|
||||
publishItems = Bool(allow_none=True)
|
||||
checkCompatibility = Bool(allow_none=True)
|
||||
autoCompressPictures = Bool(allow_none=True)
|
||||
refreshAllConnections = Bool(allow_none=True)
|
||||
defaultThemeVersion = Integer(allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
date1904=None,
|
||||
dateCompatibility=None,
|
||||
showObjects=None,
|
||||
showBorderUnselectedTables=None,
|
||||
filterPrivacy=None,
|
||||
promptedSolutions=None,
|
||||
showInkAnnotation=None,
|
||||
backupFile=None,
|
||||
saveExternalLinkValues=None,
|
||||
updateLinks=None,
|
||||
codeName=None,
|
||||
hidePivotFieldList=None,
|
||||
showPivotChartFilter=None,
|
||||
allowRefreshQuery=None,
|
||||
publishItems=None,
|
||||
checkCompatibility=None,
|
||||
autoCompressPictures=None,
|
||||
refreshAllConnections=None,
|
||||
defaultThemeVersion=None,
|
||||
):
|
||||
self.date1904 = date1904
|
||||
self.dateCompatibility = dateCompatibility
|
||||
self.showObjects = showObjects
|
||||
self.showBorderUnselectedTables = showBorderUnselectedTables
|
||||
self.filterPrivacy = filterPrivacy
|
||||
self.promptedSolutions = promptedSolutions
|
||||
self.showInkAnnotation = showInkAnnotation
|
||||
self.backupFile = backupFile
|
||||
self.saveExternalLinkValues = saveExternalLinkValues
|
||||
self.updateLinks = updateLinks
|
||||
self.codeName = codeName
|
||||
self.hidePivotFieldList = hidePivotFieldList
|
||||
self.showPivotChartFilter = showPivotChartFilter
|
||||
self.allowRefreshQuery = allowRefreshQuery
|
||||
self.publishItems = publishItems
|
||||
self.checkCompatibility = checkCompatibility
|
||||
self.autoCompressPictures = autoCompressPictures
|
||||
self.refreshAllConnections = refreshAllConnections
|
||||
self.defaultThemeVersion = defaultThemeVersion
|
||||
|
||||
|
||||
class CalcProperties(Serialisable):
|
||||
|
||||
tagname = "calcPr"
|
||||
|
||||
calcId = Integer()
|
||||
calcMode = NoneSet(values=(['manual', 'auto', 'autoNoTable']))
|
||||
fullCalcOnLoad = Bool(allow_none=True)
|
||||
refMode = NoneSet(values=(['A1', 'R1C1']))
|
||||
iterate = Bool(allow_none=True)
|
||||
iterateCount = Integer(allow_none=True)
|
||||
iterateDelta = Float(allow_none=True)
|
||||
fullPrecision = Bool(allow_none=True)
|
||||
calcCompleted = Bool(allow_none=True)
|
||||
calcOnSave = Bool(allow_none=True)
|
||||
concurrentCalc = Bool(allow_none=True)
|
||||
concurrentManualCount = Integer(allow_none=True)
|
||||
forceFullCalc = Bool(allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
calcId=124519,
|
||||
calcMode=None,
|
||||
fullCalcOnLoad=True,
|
||||
refMode=None,
|
||||
iterate=None,
|
||||
iterateCount=None,
|
||||
iterateDelta=None,
|
||||
fullPrecision=None,
|
||||
calcCompleted=None,
|
||||
calcOnSave=None,
|
||||
concurrentCalc=None,
|
||||
concurrentManualCount=None,
|
||||
forceFullCalc=None,
|
||||
):
|
||||
self.calcId = calcId
|
||||
self.calcMode = calcMode
|
||||
self.fullCalcOnLoad = fullCalcOnLoad
|
||||
self.refMode = refMode
|
||||
self.iterate = iterate
|
||||
self.iterateCount = iterateCount
|
||||
self.iterateDelta = iterateDelta
|
||||
self.fullPrecision = fullPrecision
|
||||
self.calcCompleted = calcCompleted
|
||||
self.calcOnSave = calcOnSave
|
||||
self.concurrentCalc = concurrentCalc
|
||||
self.concurrentManualCount = concurrentManualCount
|
||||
self.forceFullCalc = forceFullCalc
|
||||
|
||||
|
||||
class FileVersion(Serialisable):
|
||||
|
||||
tagname = "fileVersion"
|
||||
|
||||
appName = String(allow_none=True)
|
||||
lastEdited = String(allow_none=True)
|
||||
lowestEdited = String(allow_none=True)
|
||||
rupBuild = String(allow_none=True)
|
||||
codeName = Guid(allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
appName=None,
|
||||
lastEdited=None,
|
||||
lowestEdited=None,
|
||||
rupBuild=None,
|
||||
codeName=None,
|
||||
):
|
||||
self.appName = appName
|
||||
self.lastEdited = lastEdited
|
||||
self.lowestEdited = lowestEdited
|
||||
self.rupBuild = rupBuild
|
||||
self.codeName = codeName
|
163
.venv/Lib/site-packages/openpyxl/workbook/protection.py
Normal file
163
.venv/Lib/site-packages/openpyxl/workbook/protection.py
Normal file
@ -0,0 +1,163 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Alias,
|
||||
Typed,
|
||||
String,
|
||||
Float,
|
||||
Integer,
|
||||
Bool,
|
||||
NoneSet,
|
||||
Set,
|
||||
)
|
||||
from openpyxl.descriptors.excel import (
|
||||
ExtensionList,
|
||||
HexBinary,
|
||||
Guid,
|
||||
Relation,
|
||||
Base64Binary,
|
||||
)
|
||||
from openpyxl.utils.protection import hash_password
|
||||
|
||||
|
||||
class WorkbookProtection(Serialisable):
|
||||
|
||||
_workbook_password, _revisions_password = None, None
|
||||
|
||||
tagname = "workbookPr"
|
||||
|
||||
workbook_password = Alias("workbookPassword")
|
||||
workbookPasswordCharacterSet = String(allow_none=True)
|
||||
revision_password = Alias("revisionsPassword")
|
||||
revisionsPasswordCharacterSet = String(allow_none=True)
|
||||
lockStructure = Bool(allow_none=True)
|
||||
lock_structure = Alias("lockStructure")
|
||||
lockWindows = Bool(allow_none=True)
|
||||
lock_windows = Alias("lockWindows")
|
||||
lockRevision = Bool(allow_none=True)
|
||||
lock_revision = Alias("lockRevision")
|
||||
revisionsAlgorithmName = String(allow_none=True)
|
||||
revisionsHashValue = Base64Binary(allow_none=True)
|
||||
revisionsSaltValue = Base64Binary(allow_none=True)
|
||||
revisionsSpinCount = Integer(allow_none=True)
|
||||
workbookAlgorithmName = String(allow_none=True)
|
||||
workbookHashValue = Base64Binary(allow_none=True)
|
||||
workbookSaltValue = Base64Binary(allow_none=True)
|
||||
workbookSpinCount = Integer(allow_none=True)
|
||||
|
||||
__attrs__ = ('workbookPassword', 'workbookPasswordCharacterSet', 'revisionsPassword',
|
||||
'revisionsPasswordCharacterSet', 'lockStructure', 'lockWindows', 'lockRevision',
|
||||
'revisionsAlgorithmName', 'revisionsHashValue', 'revisionsSaltValue',
|
||||
'revisionsSpinCount', 'workbookAlgorithmName', 'workbookHashValue',
|
||||
'workbookSaltValue', 'workbookSpinCount')
|
||||
|
||||
def __init__(self,
|
||||
workbookPassword=None,
|
||||
workbookPasswordCharacterSet=None,
|
||||
revisionsPassword=None,
|
||||
revisionsPasswordCharacterSet=None,
|
||||
lockStructure=None,
|
||||
lockWindows=None,
|
||||
lockRevision=None,
|
||||
revisionsAlgorithmName=None,
|
||||
revisionsHashValue=None,
|
||||
revisionsSaltValue=None,
|
||||
revisionsSpinCount=None,
|
||||
workbookAlgorithmName=None,
|
||||
workbookHashValue=None,
|
||||
workbookSaltValue=None,
|
||||
workbookSpinCount=None,
|
||||
):
|
||||
if workbookPassword is not None:
|
||||
self.workbookPassword = workbookPassword
|
||||
self.workbookPasswordCharacterSet = workbookPasswordCharacterSet
|
||||
if revisionsPassword is not None:
|
||||
self.revisionsPassword = revisionsPassword
|
||||
self.revisionsPasswordCharacterSet = revisionsPasswordCharacterSet
|
||||
self.lockStructure = lockStructure
|
||||
self.lockWindows = lockWindows
|
||||
self.lockRevision = lockRevision
|
||||
self.revisionsAlgorithmName = revisionsAlgorithmName
|
||||
self.revisionsHashValue = revisionsHashValue
|
||||
self.revisionsSaltValue = revisionsSaltValue
|
||||
self.revisionsSpinCount = revisionsSpinCount
|
||||
self.workbookAlgorithmName = workbookAlgorithmName
|
||||
self.workbookHashValue = workbookHashValue
|
||||
self.workbookSaltValue = workbookSaltValue
|
||||
self.workbookSpinCount = workbookSpinCount
|
||||
|
||||
def set_workbook_password(self, value='', already_hashed=False):
|
||||
"""Set a password on this workbook."""
|
||||
if not already_hashed:
|
||||
value = hash_password(value)
|
||||
self._workbook_password = value
|
||||
|
||||
@property
|
||||
def workbookPassword(self):
|
||||
"""Return the workbook password value, regardless of hash."""
|
||||
return self._workbook_password
|
||||
|
||||
@workbookPassword.setter
|
||||
def workbookPassword(self, value):
|
||||
"""Set a workbook password directly, forcing a hash step."""
|
||||
self.set_workbook_password(value)
|
||||
|
||||
def set_revisions_password(self, value='', already_hashed=False):
|
||||
"""Set a revision password on this workbook."""
|
||||
if not already_hashed:
|
||||
value = hash_password(value)
|
||||
self._revisions_password = value
|
||||
|
||||
@property
|
||||
def revisionsPassword(self):
|
||||
"""Return the revisions password value, regardless of hash."""
|
||||
return self._revisions_password
|
||||
|
||||
@revisionsPassword.setter
|
||||
def revisionsPassword(self, value):
|
||||
"""Set a revisions password directly, forcing a hash step."""
|
||||
self.set_revisions_password(value)
|
||||
|
||||
@classmethod
|
||||
def from_tree(cls, node):
|
||||
"""Don't hash passwords when deserialising from XML"""
|
||||
self = super(WorkbookProtection, cls).from_tree(node)
|
||||
if self.workbookPassword:
|
||||
self.set_workbook_password(node.get('workbookPassword'), already_hashed=True)
|
||||
if self.revisionsPassword:
|
||||
self.set_revisions_password(node.get('revisionsPassword'), already_hashed=True)
|
||||
return self
|
||||
|
||||
# Backwards compatibility
|
||||
DocumentSecurity = WorkbookProtection
|
||||
|
||||
|
||||
class FileSharing(Serialisable):
|
||||
|
||||
tagname = "fileSharing"
|
||||
|
||||
readOnlyRecommended = Bool(allow_none=True)
|
||||
userName = String(allow_none=True)
|
||||
reservationPassword = HexBinary(allow_none=True)
|
||||
algorithmName = String(allow_none=True)
|
||||
hashValue = Base64Binary(allow_none=True)
|
||||
saltValue = Base64Binary(allow_none=True)
|
||||
spinCount = Integer(allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
readOnlyRecommended=None,
|
||||
userName=None,
|
||||
reservationPassword=None,
|
||||
algorithmName=None,
|
||||
hashValue=None,
|
||||
saltValue=None,
|
||||
spinCount=None,
|
||||
):
|
||||
self.readOnlyRecommended = readOnlyRecommended
|
||||
self.userName = userName
|
||||
self.reservationPassword = reservationPassword
|
||||
self.algorithmName = algorithmName
|
||||
self.hashValue = hashValue
|
||||
self.saltValue = saltValue
|
||||
self.spinCount = spinCount
|
56
.venv/Lib/site-packages/openpyxl/workbook/smart_tags.py
Normal file
56
.venv/Lib/site-packages/openpyxl/workbook/smart_tags.py
Normal file
@ -0,0 +1,56 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Sequence,
|
||||
String,
|
||||
Bool,
|
||||
NoneSet,
|
||||
|
||||
)
|
||||
|
||||
class SmartTag(Serialisable):
|
||||
|
||||
tagname = "smartTagType"
|
||||
|
||||
namespaceUri = String(allow_none=True)
|
||||
name = String(allow_none=True)
|
||||
url = String(allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
namespaceUri=None,
|
||||
name=None,
|
||||
url=None,
|
||||
):
|
||||
self.namespaceUri = namespaceUri
|
||||
self.name = name
|
||||
self.url = url
|
||||
|
||||
|
||||
class SmartTagList(Serialisable):
|
||||
|
||||
tagname = "smartTagTypes"
|
||||
|
||||
smartTagType = Sequence(expected_type=SmartTag, allow_none=True)
|
||||
|
||||
__elements__ = ('smartTagType',)
|
||||
|
||||
def __init__(self,
|
||||
smartTagType=(),
|
||||
):
|
||||
self.smartTagType = smartTagType
|
||||
|
||||
|
||||
class SmartTagProperties(Serialisable):
|
||||
|
||||
tagname = "smartTagPr"
|
||||
|
||||
embed = Bool(allow_none=True)
|
||||
show = NoneSet(values=(['all', 'noIndicator']))
|
||||
|
||||
def __init__(self,
|
||||
embed=None,
|
||||
show=None,
|
||||
):
|
||||
self.embed = embed
|
||||
self.show = show
|
155
.venv/Lib/site-packages/openpyxl/workbook/views.py
Normal file
155
.venv/Lib/site-packages/openpyxl/workbook/views.py
Normal file
@ -0,0 +1,155 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Sequence,
|
||||
String,
|
||||
Float,
|
||||
Integer,
|
||||
Bool,
|
||||
NoneSet,
|
||||
Set,
|
||||
)
|
||||
from openpyxl.descriptors.excel import (
|
||||
ExtensionList,
|
||||
Guid,
|
||||
)
|
||||
|
||||
|
||||
class BookView(Serialisable):
|
||||
|
||||
tagname = "workbookView"
|
||||
|
||||
visibility = NoneSet(values=(['visible', 'hidden', 'veryHidden']))
|
||||
minimized = Bool(allow_none=True)
|
||||
showHorizontalScroll = Bool(allow_none=True)
|
||||
showVerticalScroll = Bool(allow_none=True)
|
||||
showSheetTabs = Bool(allow_none=True)
|
||||
xWindow = Integer(allow_none=True)
|
||||
yWindow = Integer(allow_none=True)
|
||||
windowWidth = Integer(allow_none=True)
|
||||
windowHeight = Integer(allow_none=True)
|
||||
tabRatio = Integer(allow_none=True)
|
||||
firstSheet = Integer(allow_none=True)
|
||||
activeTab = Integer(allow_none=True)
|
||||
autoFilterDateGrouping = Bool(allow_none=True)
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ()
|
||||
|
||||
def __init__(self,
|
||||
visibility="visible",
|
||||
minimized=False,
|
||||
showHorizontalScroll=True,
|
||||
showVerticalScroll=True,
|
||||
showSheetTabs=True,
|
||||
xWindow=None,
|
||||
yWindow=None,
|
||||
windowWidth=None,
|
||||
windowHeight=None,
|
||||
tabRatio=600,
|
||||
firstSheet=0,
|
||||
activeTab=0,
|
||||
autoFilterDateGrouping=True,
|
||||
extLst=None,
|
||||
):
|
||||
self.visibility = visibility
|
||||
self.minimized = minimized
|
||||
self.showHorizontalScroll = showHorizontalScroll
|
||||
self.showVerticalScroll = showVerticalScroll
|
||||
self.showSheetTabs = showSheetTabs
|
||||
self.xWindow = xWindow
|
||||
self.yWindow = yWindow
|
||||
self.windowWidth = windowWidth
|
||||
self.windowHeight = windowHeight
|
||||
self.tabRatio = tabRatio
|
||||
self.firstSheet = firstSheet
|
||||
self.activeTab = activeTab
|
||||
self.autoFilterDateGrouping = autoFilterDateGrouping
|
||||
|
||||
|
||||
class CustomWorkbookView(Serialisable):
|
||||
|
||||
tagname = "customWorkbookView"
|
||||
|
||||
name = String()
|
||||
guid = Guid()
|
||||
autoUpdate = Bool(allow_none=True)
|
||||
mergeInterval = Integer(allow_none=True)
|
||||
changesSavedWin = Bool(allow_none=True)
|
||||
onlySync = Bool(allow_none=True)
|
||||
personalView = Bool(allow_none=True)
|
||||
includePrintSettings = Bool(allow_none=True)
|
||||
includeHiddenRowCol = Bool(allow_none=True)
|
||||
maximized = Bool(allow_none=True)
|
||||
minimized = Bool(allow_none=True)
|
||||
showHorizontalScroll = Bool(allow_none=True)
|
||||
showVerticalScroll = Bool(allow_none=True)
|
||||
showSheetTabs = Bool(allow_none=True)
|
||||
xWindow = Integer(allow_none=True)
|
||||
yWindow = Integer(allow_none=True)
|
||||
windowWidth = Integer()
|
||||
windowHeight = Integer()
|
||||
tabRatio = Integer(allow_none=True)
|
||||
activeSheetId = Integer()
|
||||
showFormulaBar = Bool(allow_none=True)
|
||||
showStatusbar = Bool(allow_none=True)
|
||||
showComments = NoneSet(values=(['commNone', 'commIndicator',
|
||||
'commIndAndComment']))
|
||||
showObjects = NoneSet(values=(['all', 'placeholders']))
|
||||
extLst = Typed(expected_type=ExtensionList, allow_none=True)
|
||||
|
||||
__elements__ = ()
|
||||
|
||||
def __init__(self,
|
||||
name=None,
|
||||
guid=None,
|
||||
autoUpdate=None,
|
||||
mergeInterval=None,
|
||||
changesSavedWin=None,
|
||||
onlySync=None,
|
||||
personalView=None,
|
||||
includePrintSettings=None,
|
||||
includeHiddenRowCol=None,
|
||||
maximized=None,
|
||||
minimized=None,
|
||||
showHorizontalScroll=None,
|
||||
showVerticalScroll=None,
|
||||
showSheetTabs=None,
|
||||
xWindow=None,
|
||||
yWindow=None,
|
||||
windowWidth=None,
|
||||
windowHeight=None,
|
||||
tabRatio=None,
|
||||
activeSheetId=None,
|
||||
showFormulaBar=None,
|
||||
showStatusbar=None,
|
||||
showComments="commIndicator",
|
||||
showObjects="all",
|
||||
extLst=None,
|
||||
):
|
||||
self.name = name
|
||||
self.guid = guid
|
||||
self.autoUpdate = autoUpdate
|
||||
self.mergeInterval = mergeInterval
|
||||
self.changesSavedWin = changesSavedWin
|
||||
self.onlySync = onlySync
|
||||
self.personalView = personalView
|
||||
self.includePrintSettings = includePrintSettings
|
||||
self.includeHiddenRowCol = includeHiddenRowCol
|
||||
self.maximized = maximized
|
||||
self.minimized = minimized
|
||||
self.showHorizontalScroll = showHorizontalScroll
|
||||
self.showVerticalScroll = showVerticalScroll
|
||||
self.showSheetTabs = showSheetTabs
|
||||
self.xWindow = xWindow
|
||||
self.yWindow = yWindow
|
||||
self.windowWidth = windowWidth
|
||||
self.windowHeight = windowHeight
|
||||
self.tabRatio = tabRatio
|
||||
self.activeSheetId = activeSheetId
|
||||
self.showFormulaBar = showFormulaBar
|
||||
self.showStatusbar = showStatusbar
|
||||
self.showComments = showComments
|
||||
self.showObjects = showObjects
|
98
.venv/Lib/site-packages/openpyxl/workbook/web.py
Normal file
98
.venv/Lib/site-packages/openpyxl/workbook/web.py
Normal file
@ -0,0 +1,98 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
from openpyxl.descriptors.serialisable import Serialisable
|
||||
from openpyxl.descriptors import (
|
||||
Typed,
|
||||
Sequence,
|
||||
String,
|
||||
Float,
|
||||
Integer,
|
||||
Bool,
|
||||
NoneSet,
|
||||
)
|
||||
|
||||
|
||||
class WebPublishObject(Serialisable):
|
||||
|
||||
tagname = "webPublishingObject"
|
||||
|
||||
id = Integer()
|
||||
divId = String()
|
||||
sourceObject = String(allow_none=True)
|
||||
destinationFile = String()
|
||||
title = String(allow_none=True)
|
||||
autoRepublish = Bool(allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
id=None,
|
||||
divId=None,
|
||||
sourceObject=None,
|
||||
destinationFile=None,
|
||||
title=None,
|
||||
autoRepublish=None,
|
||||
):
|
||||
self.id = id
|
||||
self.divId = divId
|
||||
self.sourceObject = sourceObject
|
||||
self.destinationFile = destinationFile
|
||||
self.title = title
|
||||
self.autoRepublish = autoRepublish
|
||||
|
||||
|
||||
class WebPublishObjectList(Serialisable):
|
||||
|
||||
tagname ="webPublishingObjects"
|
||||
|
||||
count = Integer(allow_none=True)
|
||||
webPublishObject = Sequence(expected_type=WebPublishObject)
|
||||
|
||||
__elements__ = ('webPublishObject',)
|
||||
|
||||
def __init__(self,
|
||||
count=None,
|
||||
webPublishObject=(),
|
||||
):
|
||||
self.webPublishObject = webPublishObject
|
||||
|
||||
|
||||
@property
|
||||
def count(self):
|
||||
return len(self.webPublishObject)
|
||||
|
||||
|
||||
class WebPublishing(Serialisable):
|
||||
|
||||
tagname = "webPublishing"
|
||||
|
||||
css = Bool(allow_none=True)
|
||||
thicket = Bool(allow_none=True)
|
||||
longFileNames = Bool(allow_none=True)
|
||||
vml = Bool(allow_none=True)
|
||||
allowPng = Bool(allow_none=True)
|
||||
targetScreenSize = NoneSet(values=(['544x376', '640x480', '720x512', '800x600',
|
||||
'1024x768', '1152x882', '1152x900', '1280x1024', '1600x1200',
|
||||
'1800x1440', '1920x1200']))
|
||||
dpi = Integer(allow_none=True)
|
||||
codePage = Integer(allow_none=True)
|
||||
characterSet = String(allow_none=True)
|
||||
|
||||
def __init__(self,
|
||||
css=None,
|
||||
thicket=None,
|
||||
longFileNames=None,
|
||||
vml=None,
|
||||
allowPng=None,
|
||||
targetScreenSize='800x600',
|
||||
dpi=None,
|
||||
codePage=None,
|
||||
characterSet=None,
|
||||
):
|
||||
self.css = css
|
||||
self.thicket = thicket
|
||||
self.longFileNames = longFileNames
|
||||
self.vml = vml
|
||||
self.allowPng = allowPng
|
||||
self.targetScreenSize = targetScreenSize
|
||||
self.dpi = dpi
|
||||
self.codePage = codePage
|
||||
self.characterSet = characterSet
|
459
.venv/Lib/site-packages/openpyxl/workbook/workbook.py
Normal file
459
.venv/Lib/site-packages/openpyxl/workbook/workbook.py
Normal file
@ -0,0 +1,459 @@
|
||||
# Copyright (c) 2010-2022 openpyxl
|
||||
|
||||
"""Workbook is the top-level container for all document information."""
|
||||
from copy import copy
|
||||
|
||||
from openpyxl.compat import deprecated
|
||||
from openpyxl.worksheet.worksheet import Worksheet
|
||||
from openpyxl.worksheet._read_only import ReadOnlyWorksheet
|
||||
from openpyxl.worksheet._write_only import WriteOnlyWorksheet
|
||||
from openpyxl.worksheet.copier import WorksheetCopy
|
||||
|
||||
from openpyxl.utils import quote_sheetname
|
||||
from openpyxl.utils.indexed_list import IndexedList
|
||||
from openpyxl.utils.datetime import WINDOWS_EPOCH, MAC_EPOCH
|
||||
from openpyxl.utils.exceptions import ReadOnlyWorkbookException
|
||||
|
||||
from openpyxl.writer.excel import save_workbook
|
||||
|
||||
from openpyxl.styles.cell_style import StyleArray
|
||||
from openpyxl.styles.named_styles import NamedStyle
|
||||
from openpyxl.styles.differential import DifferentialStyleList
|
||||
from openpyxl.styles.alignment import Alignment
|
||||
from openpyxl.styles.borders import DEFAULT_BORDER
|
||||
from openpyxl.styles.fills import DEFAULT_EMPTY_FILL, DEFAULT_GRAY_FILL
|
||||
from openpyxl.styles.fonts import DEFAULT_FONT
|
||||
from openpyxl.styles.protection import Protection
|
||||
from openpyxl.styles.colors import COLOR_INDEX
|
||||
from openpyxl.styles.named_styles import NamedStyleList
|
||||
from openpyxl.styles.table import TableStyleList
|
||||
|
||||
from openpyxl.chartsheet import Chartsheet
|
||||
from .defined_name import DefinedName, DefinedNameList
|
||||
from openpyxl.packaging.core import DocumentProperties
|
||||
from openpyxl.packaging.relationship import RelationshipList
|
||||
from .child import _WorkbookChild
|
||||
from .protection import DocumentSecurity
|
||||
from .properties import CalcProperties
|
||||
from .views import BookView
|
||||
|
||||
|
||||
from openpyxl.xml.constants import (
|
||||
XLSM,
|
||||
XLSX,
|
||||
XLTM,
|
||||
XLTX
|
||||
)
|
||||
|
||||
INTEGER_TYPES = (int,)
|
||||
|
||||
class Workbook(object):
|
||||
"""Workbook is the container for all other parts of the document."""
|
||||
|
||||
_read_only = False
|
||||
_data_only = False
|
||||
template = False
|
||||
path = "/xl/workbook.xml"
|
||||
|
||||
def __init__(self,
|
||||
write_only=False,
|
||||
iso_dates=False,
|
||||
):
|
||||
self._sheets = []
|
||||
self._pivots = []
|
||||
self._active_sheet_index = 0
|
||||
self.defined_names = DefinedNameList()
|
||||
self._external_links = []
|
||||
self.properties = DocumentProperties()
|
||||
self.security = DocumentSecurity()
|
||||
self.__write_only = write_only
|
||||
self.shared_strings = IndexedList()
|
||||
|
||||
self._setup_styles()
|
||||
|
||||
self.loaded_theme = None
|
||||
self.vba_archive = None
|
||||
self.is_template = False
|
||||
self.code_name = None
|
||||
self.epoch = WINDOWS_EPOCH
|
||||
self.encoding = "utf-8"
|
||||
self.iso_dates = iso_dates
|
||||
|
||||
if not self.write_only:
|
||||
self._sheets.append(Worksheet(self))
|
||||
|
||||
self.rels = RelationshipList()
|
||||
self.calculation = CalcProperties()
|
||||
self.views = [BookView()]
|
||||
|
||||
|
||||
def _setup_styles(self):
|
||||
"""Bootstrap styles"""
|
||||
|
||||
self._fonts = IndexedList()
|
||||
self._fonts.add(DEFAULT_FONT)
|
||||
|
||||
self._alignments = IndexedList([Alignment()])
|
||||
|
||||
self._borders = IndexedList()
|
||||
self._borders.add(DEFAULT_BORDER)
|
||||
|
||||
self._fills = IndexedList()
|
||||
self._fills.add(DEFAULT_EMPTY_FILL)
|
||||
self._fills.add(DEFAULT_GRAY_FILL)
|
||||
|
||||
self._number_formats = IndexedList()
|
||||
self._date_formats = {}
|
||||
self._timedelta_formats = {}
|
||||
|
||||
self._protections = IndexedList([Protection()])
|
||||
|
||||
self._colors = COLOR_INDEX
|
||||
self._cell_styles = IndexedList([StyleArray()])
|
||||
self._named_styles = NamedStyleList()
|
||||
self.add_named_style(NamedStyle(font=copy(DEFAULT_FONT), border=copy(DEFAULT_BORDER), builtinId=0))
|
||||
self._table_styles = TableStyleList()
|
||||
self._differential_styles = DifferentialStyleList()
|
||||
|
||||
|
||||
@property
|
||||
def epoch(self):
|
||||
if self._epoch == WINDOWS_EPOCH:
|
||||
return WINDOWS_EPOCH
|
||||
return MAC_EPOCH
|
||||
|
||||
|
||||
@epoch.setter
|
||||
def epoch(self, value):
|
||||
if value not in (WINDOWS_EPOCH, MAC_EPOCH):
|
||||
raise ValueError("The epoch must be either 1900 or 1904")
|
||||
self._epoch = value
|
||||
|
||||
|
||||
@property
|
||||
def read_only(self):
|
||||
return self._read_only
|
||||
|
||||
@property
|
||||
def data_only(self):
|
||||
return self._data_only
|
||||
|
||||
@property
|
||||
def write_only(self):
|
||||
return self.__write_only
|
||||
|
||||
|
||||
@property
|
||||
def excel_base_date(self):
|
||||
return self.epoch
|
||||
|
||||
@property
|
||||
def active(self):
|
||||
"""Get the currently active sheet or None
|
||||
|
||||
:type: :class:`openpyxl.worksheet.worksheet.Worksheet`
|
||||
"""
|
||||
try:
|
||||
return self._sheets[self._active_sheet_index]
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
@active.setter
|
||||
def active(self, value):
|
||||
"""Set the active sheet"""
|
||||
if not isinstance(value, (_WorkbookChild, INTEGER_TYPES)):
|
||||
raise TypeError("Value must be either a worksheet, chartsheet or numerical index")
|
||||
if isinstance(value, INTEGER_TYPES):
|
||||
self._active_sheet_index = value
|
||||
return
|
||||
#if self._sheets and 0 <= value < len(self._sheets):
|
||||
#value = self._sheets[value]
|
||||
#else:
|
||||
#raise ValueError("Sheet index is outside the range of possible values", value)
|
||||
if value not in self._sheets:
|
||||
raise ValueError("Worksheet is not in the workbook")
|
||||
if value.sheet_state != "visible":
|
||||
raise ValueError("Only visible sheets can be made active")
|
||||
|
||||
idx = self._sheets.index(value)
|
||||
self._active_sheet_index = idx
|
||||
|
||||
|
||||
def create_sheet(self, title=None, index=None):
|
||||
"""Create a worksheet (at an optional index).
|
||||
|
||||
:param title: optional title of the sheet
|
||||
:type title: str
|
||||
:param index: optional position at which the sheet will be inserted
|
||||
:type index: int
|
||||
|
||||
"""
|
||||
if self.read_only:
|
||||
raise ReadOnlyWorkbookException('Cannot create new sheet in a read-only workbook')
|
||||
|
||||
if self.write_only :
|
||||
new_ws = WriteOnlyWorksheet(parent=self, title=title)
|
||||
else:
|
||||
new_ws = Worksheet(parent=self, title=title)
|
||||
|
||||
self._add_sheet(sheet=new_ws, index=index)
|
||||
return new_ws
|
||||
|
||||
|
||||
def _add_sheet(self, sheet, index=None):
|
||||
"""Add an worksheet (at an optional index)."""
|
||||
|
||||
if not isinstance(sheet, (Worksheet, WriteOnlyWorksheet, Chartsheet)):
|
||||
raise TypeError("Cannot be added to a workbook")
|
||||
|
||||
if sheet.parent != self:
|
||||
raise ValueError("You cannot add worksheets from another workbook.")
|
||||
|
||||
if index is None:
|
||||
self._sheets.append(sheet)
|
||||
else:
|
||||
self._sheets.insert(index, sheet)
|
||||
|
||||
|
||||
def move_sheet(self, sheet, offset=0):
|
||||
"""
|
||||
Move a sheet or sheetname
|
||||
"""
|
||||
if not isinstance(sheet, Worksheet):
|
||||
sheet = self[sheet]
|
||||
idx = self._sheets.index(sheet)
|
||||
del self._sheets[idx]
|
||||
new_pos = idx + offset
|
||||
self._sheets.insert(new_pos, sheet)
|
||||
|
||||
|
||||
def remove(self, worksheet):
|
||||
"""Remove `worksheet` from this workbook."""
|
||||
idx = self._sheets.index(worksheet)
|
||||
localnames = self.defined_names.localnames(scope=idx)
|
||||
for name in localnames:
|
||||
self.defined_names.delete(name, scope=idx)
|
||||
self._sheets.remove(worksheet)
|
||||
|
||||
|
||||
@deprecated("Use wb.remove(worksheet) or del wb[sheetname]")
|
||||
def remove_sheet(self, worksheet):
|
||||
"""Remove `worksheet` from this workbook."""
|
||||
self.remove(worksheet)
|
||||
|
||||
|
||||
def create_chartsheet(self, title=None, index=None):
|
||||
if self.read_only:
|
||||
raise ReadOnlyWorkbookException("Cannot create new sheet in a read-only workbook")
|
||||
cs = Chartsheet(parent=self, title=title)
|
||||
|
||||
self._add_sheet(cs, index)
|
||||
return cs
|
||||
|
||||
|
||||
@deprecated("Use wb[sheetname]")
|
||||
def get_sheet_by_name(self, name):
|
||||
"""Returns a worksheet by its name.
|
||||
|
||||
:param name: the name of the worksheet to look for
|
||||
:type name: string
|
||||
|
||||
"""
|
||||
return self[name]
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self.sheetnames
|
||||
|
||||
|
||||
def index(self, worksheet):
|
||||
"""Return the index of a worksheet."""
|
||||
return self.worksheets.index(worksheet)
|
||||
|
||||
|
||||
@deprecated("Use wb.index(worksheet)")
|
||||
def get_index(self, worksheet):
|
||||
"""Return the index of the worksheet."""
|
||||
return self.index(worksheet)
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""Returns a worksheet by its name.
|
||||
|
||||
:param name: the name of the worksheet to look for
|
||||
:type name: string
|
||||
|
||||
"""
|
||||
for sheet in self.worksheets + self.chartsheets:
|
||||
if sheet.title == key:
|
||||
return sheet
|
||||
raise KeyError("Worksheet {0} does not exist.".format(key))
|
||||
|
||||
def __delitem__(self, key):
|
||||
sheet = self[key]
|
||||
self.remove(sheet)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.worksheets)
|
||||
|
||||
|
||||
@deprecated("Use wb.sheetnames")
|
||||
def get_sheet_names(self):
|
||||
return self.sheetnames
|
||||
|
||||
@property
|
||||
def worksheets(self):
|
||||
"""A list of sheets in this workbook
|
||||
|
||||
:type: list of :class:`openpyxl.worksheet.worksheet.Worksheet`
|
||||
"""
|
||||
return [s for s in self._sheets if isinstance(s, (Worksheet, ReadOnlyWorksheet, WriteOnlyWorksheet))]
|
||||
|
||||
@property
|
||||
def chartsheets(self):
|
||||
"""A list of Chartsheets in this workbook
|
||||
|
||||
:type: list of :class:`openpyxl.chartsheet.chartsheet.Chartsheet`
|
||||
"""
|
||||
return [s for s in self._sheets if isinstance(s, Chartsheet)]
|
||||
|
||||
@property
|
||||
def sheetnames(self):
|
||||
"""Returns the list of the names of worksheets in this workbook.
|
||||
|
||||
Names are returned in the worksheets order.
|
||||
|
||||
:type: list of strings
|
||||
|
||||
"""
|
||||
return [s.title for s in self._sheets]
|
||||
|
||||
def create_named_range(self, name, worksheet=None, value=None, scope=None):
|
||||
"""Create a new named_range on a worksheet"""
|
||||
defn = DefinedName(name=name, localSheetId=scope)
|
||||
if worksheet is not None:
|
||||
defn.value = "{0}!{1}".format(quote_sheetname(worksheet.title), value)
|
||||
else:
|
||||
defn.value = value
|
||||
|
||||
self.defined_names.append(defn)
|
||||
|
||||
|
||||
def add_named_style(self, style):
|
||||
"""
|
||||
Add a named style
|
||||
"""
|
||||
self._named_styles.append(style)
|
||||
style.bind(self)
|
||||
|
||||
|
||||
@property
|
||||
def named_styles(self):
|
||||
"""
|
||||
List available named styles
|
||||
"""
|
||||
return self._named_styles.names
|
||||
|
||||
|
||||
@deprecated("Use workbook.defined_names.definedName")
|
||||
def get_named_ranges(self):
|
||||
"""Return all named ranges"""
|
||||
return self.defined_names.definedName
|
||||
|
||||
|
||||
@deprecated("Use workbook.defined_names.append")
|
||||
def add_named_range(self, named_range):
|
||||
"""Add an existing named_range to the list of named_ranges."""
|
||||
self.defined_names.append(named_range)
|
||||
|
||||
|
||||
@deprecated("Use workbook.defined_names[name]")
|
||||
def get_named_range(self, name):
|
||||
"""Return the range specified by name."""
|
||||
return self.defined_names[name]
|
||||
|
||||
|
||||
@deprecated("Use del workbook.defined_names[name]")
|
||||
def remove_named_range(self, named_range):
|
||||
"""Remove a named_range from this workbook."""
|
||||
del self.defined_names[named_range]
|
||||
|
||||
|
||||
@property
|
||||
def mime_type(self):
|
||||
"""
|
||||
The mime type is determined by whether a workbook is a template or
|
||||
not and whether it contains macros or not. Excel requires the file
|
||||
extension to match but openpyxl does not enforce this.
|
||||
|
||||
"""
|
||||
ct = self.template and XLTX or XLSX
|
||||
if self.vba_archive:
|
||||
ct = self.template and XLTM or XLSM
|
||||
return ct
|
||||
|
||||
|
||||
def save(self, filename):
|
||||
"""Save the current workbook under the given `filename`.
|
||||
Use this function instead of using an `ExcelWriter`.
|
||||
|
||||
.. warning::
|
||||
When creating your workbook using `write_only` set to True,
|
||||
you will only be able to call this function once. Subsequents attempts to
|
||||
modify or save the file will raise an :class:`openpyxl.shared.exc.WorkbookAlreadySaved` exception.
|
||||
"""
|
||||
if self.read_only:
|
||||
raise TypeError("""Workbook is read-only""")
|
||||
if self.write_only and not self.worksheets:
|
||||
self.create_sheet()
|
||||
save_workbook(self, filename)
|
||||
|
||||
|
||||
@property
|
||||
def style_names(self):
|
||||
"""
|
||||
List of named styles
|
||||
"""
|
||||
return [s.name for s in self._named_styles]
|
||||
|
||||
|
||||
def copy_worksheet(self, from_worksheet):
|
||||
"""Copy an existing worksheet in the current workbook
|
||||
|
||||
.. warning::
|
||||
This function cannot copy worksheets between workbooks.
|
||||
worksheets can only be copied within the workbook that they belong
|
||||
|
||||
:param from_worksheet: the worksheet to be copied from
|
||||
:return: copy of the initial worksheet
|
||||
"""
|
||||
if self.__write_only or self._read_only:
|
||||
raise ValueError("Cannot copy worksheets in read-only or write-only mode")
|
||||
|
||||
new_title = u"{0} Copy".format(from_worksheet.title)
|
||||
to_worksheet = self.create_sheet(title=new_title)
|
||||
cp = WorksheetCopy(source_worksheet=from_worksheet, target_worksheet=to_worksheet)
|
||||
cp.copy_worksheet()
|
||||
return to_worksheet
|
||||
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close workbook file if open. Only affects read-only and write-only modes.
|
||||
"""
|
||||
if hasattr(self, '_archive'):
|
||||
self._archive.close()
|
||||
|
||||
|
||||
def _duplicate_name(self, name):
|
||||
"""
|
||||
Check for duplicate name in defined name list and table list of each worksheet.
|
||||
Names are not case sensitive.
|
||||
"""
|
||||
name = name.lower()
|
||||
for sheet in self.worksheets:
|
||||
for t in sheet.tables:
|
||||
if name == t.lower():
|
||||
return True
|
||||
|
||||
if name in self.defined_names:
|
||||
return True
|
||||
|
Reference in New Issue
Block a user