123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- from __future__ import absolute_import
- # Copyright (c) 2010-2019 openpyxl
- import re
- import warnings
- from openpyxl.compat import unicode, safe_repr
- 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(r"(?P<title>%s)(?P<count>\d*),?" % re.escape(value), 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__, safe_repr(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, unicode):
- try:
- value = value.decode("ascii")
- except UnicodeDecodeError:
- raise ValueError("Worksheet titles must be unicode")
- 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)
|