Updated script that can be controled by Nodejs web app

This commit is contained in:
mac OS
2024-11-25 12:24:18 +07:00
parent c440eda1f4
commit 8b0ab2bd3a
8662 changed files with 1803808 additions and 34 deletions

View File

@ -0,0 +1,3 @@
"""
Stuff related to Office OpenXML packaging: relationships, archive, content types.
"""

View File

@ -0,0 +1,115 @@
# Copyright (c) 2010-2024 openpyxl
import datetime
from openpyxl.descriptors import (
DateTime,
Alias,
)
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors.nested import NestedText
from openpyxl.xml.functions import (
Element,
QName,
)
from openpyxl.xml.constants import (
COREPROPS_NS,
DCORE_NS,
XSI_NS,
DCTERMS_NS,
)
class NestedDateTime(DateTime, NestedText):
expected_type = datetime.datetime
def to_tree(self, tagname=None, value=None, namespace=None):
namespace = getattr(self, "namespace", namespace)
if namespace is not None:
tagname = "{%s}%s" % (namespace, tagname)
el = Element(tagname)
if value is not None:
value = value.replace(tzinfo=None)
el.text = value.isoformat(timespec="seconds") + 'Z'
return el
class QualifiedDateTime(NestedDateTime):
"""In certain situations Excel will complain if the additional type
attribute isn't set"""
def to_tree(self, tagname=None, value=None, namespace=None):
el = super().to_tree(tagname, value, namespace)
el.set("{%s}type" % XSI_NS, QName(DCTERMS_NS, "W3CDTF"))
return el
class DocumentProperties(Serialisable):
"""High-level properties of the document.
Defined in ECMA-376 Par2 Annex D
"""
tagname = "coreProperties"
namespace = COREPROPS_NS
category = NestedText(expected_type=str, allow_none=True)
contentStatus = NestedText(expected_type=str, allow_none=True)
keywords = NestedText(expected_type=str, allow_none=True)
lastModifiedBy = NestedText(expected_type=str, allow_none=True)
lastPrinted = NestedDateTime(allow_none=True)
revision = NestedText(expected_type=str, allow_none=True)
version = NestedText(expected_type=str, allow_none=True)
last_modified_by = Alias("lastModifiedBy")
# Dublin Core Properties
subject = NestedText(expected_type=str, allow_none=True, namespace=DCORE_NS)
title = NestedText(expected_type=str, allow_none=True, namespace=DCORE_NS)
creator = NestedText(expected_type=str, allow_none=True, namespace=DCORE_NS)
description = NestedText(expected_type=str, allow_none=True, namespace=DCORE_NS)
identifier = NestedText(expected_type=str, allow_none=True, namespace=DCORE_NS)
language = NestedText(expected_type=str, allow_none=True, namespace=DCORE_NS)
# Dublin Core Terms
created = QualifiedDateTime(allow_none=True, namespace=DCTERMS_NS) # assumed to be UTC
modified = QualifiedDateTime(allow_none=True, namespace=DCTERMS_NS) # assumed to be UTC
__elements__ = ("creator", "title", "description", "subject","identifier",
"language", "created", "modified", "lastModifiedBy", "category",
"contentStatus", "version", "revision", "keywords", "lastPrinted",
)
def __init__(self,
category=None,
contentStatus=None,
keywords=None,
lastModifiedBy=None,
lastPrinted=None,
revision=None,
version=None,
created=None,
creator="openpyxl",
description=None,
identifier=None,
language=None,
modified=None,
subject=None,
title=None,
):
now = datetime.datetime.now(tz=datetime.timezone.utc).replace(tzinfo=None)
self.contentStatus = contentStatus
self.lastPrinted = lastPrinted
self.revision = revision
self.version = version
self.creator = creator
self.lastModifiedBy = lastModifiedBy
self.modified = modified or now
self.created = created or now
self.title = title
self.subject = subject
self.description = description
self.identifier = identifier
self.language = language
self.keywords = keywords
self.category = category

View File

@ -0,0 +1,289 @@
# Copyright (c) 2010-2024 openpyxl
"""Implementation of custom properties see § 22.3 in the specification"""
from warnings import warn
from openpyxl.descriptors import Strict
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors.sequence import Sequence
from openpyxl.descriptors import (
Alias,
String,
Integer,
Float,
DateTime,
Bool,
)
from openpyxl.descriptors.nested import (
NestedText,
)
from openpyxl.xml.constants import (
CUSTPROPS_NS,
VTYPES_NS,
CPROPS_FMTID,
)
from .core import NestedDateTime
class NestedBoolText(Bool, NestedText):
"""
Descriptor for handling nested elements with the value stored in the text part
"""
pass
class _CustomDocumentProperty(Serialisable):
"""
Low-level representation of a Custom Document Property.
Not used directly
Must always contain a child element, even if this is empty
"""
tagname = "property"
_typ = None
name = String(allow_none=True)
lpwstr = NestedText(expected_type=str, allow_none=True, namespace=VTYPES_NS)
i4 = NestedText(expected_type=int, allow_none=True, namespace=VTYPES_NS)
r8 = NestedText(expected_type=float, allow_none=True, namespace=VTYPES_NS)
filetime = NestedDateTime(allow_none=True, namespace=VTYPES_NS)
bool = NestedBoolText(expected_type=bool, allow_none=True, namespace=VTYPES_NS)
linkTarget = String(expected_type=str, allow_none=True)
fmtid = String()
pid = Integer()
def __init__(self,
name=None,
pid=0,
fmtid=CPROPS_FMTID,
linkTarget=None,
**kw):
self.fmtid = fmtid
self.pid = pid
self.name = name
self._typ = None
self.linkTarget = linkTarget
for k, v in kw.items():
setattr(self, k, v)
setattr(self, "_typ", k) # ugh!
for e in self.__elements__:
if e not in kw:
setattr(self, e, None)
@property
def type(self):
if self._typ is not None:
return self._typ
for a in self.__elements__:
if getattr(self, a) is not None:
return a
if self.linkTarget is not None:
return "linkTarget"
def to_tree(self, tagname=None, idx=None, namespace=None):
child = getattr(self, self._typ, None)
if child is None:
setattr(self, self._typ, "")
return super().to_tree(tagname=None, idx=None, namespace=None)
class _CustomDocumentPropertyList(Serialisable):
"""
Parses and seriliases property lists but is not used directly
"""
tagname = "Properties"
property = Sequence(expected_type=_CustomDocumentProperty, namespace=CUSTPROPS_NS)
customProps = Alias("property")
def __init__(self, property=()):
self.property = property
def __len__(self):
return len(self.property)
def to_tree(self, tagname=None, idx=None, namespace=None):
for idx, p in enumerate(self.property, 2):
p.pid = idx
tree = super().to_tree(tagname, idx, namespace)
tree.set("xmlns", CUSTPROPS_NS)
return tree
class _TypedProperty(Strict):
name = String()
def __init__(self,
name,
value):
self.name = name
self.value = value
def __eq__(self, other):
return self.name == other.name and self.value == other.value
def __repr__(self):
return f"{self.__class__.__name__}, name={self.name}, value={self.value}"
class IntProperty(_TypedProperty):
value = Integer()
class FloatProperty(_TypedProperty):
value = Float()
class StringProperty(_TypedProperty):
value = String(allow_none=True)
class DateTimeProperty(_TypedProperty):
value = DateTime()
class BoolProperty(_TypedProperty):
value = Bool()
class LinkProperty(_TypedProperty):
value = String()
# from Python
CLASS_MAPPING = {
StringProperty: "lpwstr",
IntProperty: "i4",
FloatProperty: "r8",
DateTimeProperty: "filetime",
BoolProperty: "bool",
LinkProperty: "linkTarget"
}
XML_MAPPING = {v:k for k,v in CLASS_MAPPING.items()}
class CustomPropertyList(Strict):
props = Sequence(expected_type=_TypedProperty)
def __init__(self):
self.props = []
@classmethod
def from_tree(cls, tree):
"""
Create list from OOXML element
"""
prop_list = _CustomDocumentPropertyList.from_tree(tree)
props = []
for prop in prop_list.property:
attr = prop.type
typ = XML_MAPPING.get(attr, None)
if not typ:
warn(f"Unknown type for {prop.name}")
continue
value = getattr(prop, attr)
link = prop.linkTarget
if link is not None:
typ = LinkProperty
value = prop.linkTarget
new_prop = typ(name=prop.name, value=value)
props.append(new_prop)
new_prop_list = cls()
new_prop_list.props = props
return new_prop_list
def append(self, prop):
if prop.name in self.names:
raise ValueError(f"Property with name {prop.name} already exists")
self.props.append(prop)
def to_tree(self):
props = []
for p in self.props:
attr = CLASS_MAPPING.get(p.__class__, None)
if not attr:
raise TypeError("Unknown adapter for {p}")
np = _CustomDocumentProperty(name=p.name, **{attr:p.value})
if isinstance(p, LinkProperty):
np._typ = "lpwstr"
#np.lpwstr = ""
props.append(np)
prop_list = _CustomDocumentPropertyList(property=props)
return prop_list.to_tree()
def __len__(self):
return len(self.props)
@property
def names(self):
"""List of property names"""
return [p.name for p in self.props]
def __getitem__(self, name):
"""
Get property by name
"""
for p in self.props:
if p.name == name:
return p
raise KeyError(f"Property with name {name} not found")
def __delitem__(self, name):
"""
Delete a propery by name
"""
for idx, p in enumerate(self.props):
if p.name == name:
self.props.pop(idx)
return
raise KeyError(f"Property with name {name} not found")
def __repr__(self):
return f"{self.__class__.__name__} containing {self.props}"
def __iter__(self):
return iter(self.props)

View File

@ -0,0 +1,137 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Typed,
)
from openpyxl.descriptors.nested import (
NestedText,
)
from openpyxl.xml.constants import XPROPS_NS
from openpyxl import __version__
class DigSigBlob(Serialisable):
__elements__ = __attrs__ = ()
class VectorLpstr(Serialisable):
__elements__ = __attrs__ = ()
class VectorVariant(Serialisable):
__elements__ = __attrs__ = ()
class ExtendedProperties(Serialisable):
"""
See 22.2
Most of this is irrelevant but Excel is very picky about the version number
It uses XX.YYYY (Version.Build) and expects everyone else to
We provide Major.Minor and the full version in the application name
"""
tagname = "Properties"
Template = NestedText(expected_type=str, allow_none=True)
Manager = NestedText(expected_type=str, allow_none=True)
Company = NestedText(expected_type=str, allow_none=True)
Pages = NestedText(expected_type=int, allow_none=True)
Words = NestedText(expected_type=int,allow_none=True)
Characters = NestedText(expected_type=int, allow_none=True)
PresentationFormat = NestedText(expected_type=str, allow_none=True)
Lines = NestedText(expected_type=int, allow_none=True)
Paragraphs = NestedText(expected_type=int, allow_none=True)
Slides = NestedText(expected_type=int, allow_none=True)
Notes = NestedText(expected_type=int, allow_none=True)
TotalTime = NestedText(expected_type=int, allow_none=True)
HiddenSlides = NestedText(expected_type=int, allow_none=True)
MMClips = NestedText(expected_type=int, allow_none=True)
ScaleCrop = NestedText(expected_type=bool, allow_none=True)
HeadingPairs = Typed(expected_type=VectorVariant, allow_none=True)
TitlesOfParts = Typed(expected_type=VectorLpstr, allow_none=True)
LinksUpToDate = NestedText(expected_type=bool, allow_none=True)
CharactersWithSpaces = NestedText(expected_type=int, allow_none=True)
SharedDoc = NestedText(expected_type=bool, allow_none=True)
HyperlinkBase = NestedText(expected_type=str, allow_none=True)
HLinks = Typed(expected_type=VectorVariant, allow_none=True)
HyperlinksChanged = NestedText(expected_type=bool, allow_none=True)
DigSig = Typed(expected_type=DigSigBlob, allow_none=True)
Application = NestedText(expected_type=str, allow_none=True)
AppVersion = NestedText(expected_type=str, allow_none=True)
DocSecurity = NestedText(expected_type=int, allow_none=True)
__elements__ = ('Application', 'AppVersion', 'DocSecurity', 'ScaleCrop',
'LinksUpToDate', 'SharedDoc', 'HyperlinksChanged')
def __init__(self,
Template=None,
Manager=None,
Company=None,
Pages=None,
Words=None,
Characters=None,
PresentationFormat=None,
Lines=None,
Paragraphs=None,
Slides=None,
Notes=None,
TotalTime=None,
HiddenSlides=None,
MMClips=None,
ScaleCrop=None,
HeadingPairs=None,
TitlesOfParts=None,
LinksUpToDate=None,
CharactersWithSpaces=None,
SharedDoc=None,
HyperlinkBase=None,
HLinks=None,
HyperlinksChanged=None,
DigSig=None,
Application=None,
AppVersion=None,
DocSecurity=None,
):
self.Template = Template
self.Manager = Manager
self.Company = Company
self.Pages = Pages
self.Words = Words
self.Characters = Characters
self.PresentationFormat = PresentationFormat
self.Lines = Lines
self.Paragraphs = Paragraphs
self.Slides = Slides
self.Notes = Notes
self.TotalTime = TotalTime
self.HiddenSlides = HiddenSlides
self.MMClips = MMClips
self.ScaleCrop = ScaleCrop
self.HeadingPairs = None
self.TitlesOfParts = None
self.LinksUpToDate = LinksUpToDate
self.CharactersWithSpaces = CharactersWithSpaces
self.SharedDoc = SharedDoc
self.HyperlinkBase = HyperlinkBase
self.HLinks = None
self.HyperlinksChanged = HyperlinksChanged
self.DigSig = None
self.Application = f"Microsoft Excel Compatible / Openpyxl {__version__}"
self.AppVersion = ".".join(__version__.split(".")[:-1])
self.DocSecurity = DocSecurity
def to_tree(self):
tree = super().to_tree()
tree.set("xmlns", XPROPS_NS)
return tree

View File

@ -0,0 +1,56 @@
# Copyright (c) 2010-2024 openpyxl
from abc import abstractproperty
from openpyxl.compat.abc import ABC
class ISerialisableFile(ABC):
"""
Interface for Serialisable classes that represent files in the archive
"""
@abstractproperty
def id(self):
"""
Object id making it unique
"""
pass
@abstractproperty
def _path(self):
"""
File path in the archive
"""
pass
@abstractproperty
def _namespace(self):
"""
Qualified namespace when serialised
"""
pass
@abstractproperty
def _type(self):
"""
The content type for the manifest
"""
@abstractproperty
def _rel_type(self):
"""
The content type for relationships
"""
@abstractproperty
def _rel_id(self):
"""
Links object with parent
"""

View File

@ -0,0 +1,194 @@
# Copyright (c) 2010-2024 openpyxl
"""
File manifest
"""
from mimetypes import MimeTypes
import os.path
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import String, Sequence
from openpyxl.xml.functions import fromstring
from openpyxl.xml.constants import (
ARC_CONTENT_TYPES,
ARC_THEME,
ARC_STYLE,
THEME_TYPE,
STYLES_TYPE,
CONTYPES_NS,
ACTIVEX,
CTRL,
VBA,
)
from openpyxl.xml.functions import tostring
# initialise mime-types
mimetypes = MimeTypes()
mimetypes.add_type('application/xml', ".xml")
mimetypes.add_type('application/vnd.openxmlformats-package.relationships+xml', ".rels")
mimetypes.add_type("application/vnd.ms-office.vbaProject", ".bin")
mimetypes.add_type("application/vnd.openxmlformats-officedocument.vmlDrawing", ".vml")
mimetypes.add_type("image/x-emf", ".emf")
class FileExtension(Serialisable):
tagname = "Default"
Extension = String()
ContentType = String()
def __init__(self, Extension, ContentType):
self.Extension = Extension
self.ContentType = ContentType
class Override(Serialisable):
tagname = "Override"
PartName = String()
ContentType = String()
def __init__(self, PartName, ContentType):
self.PartName = PartName
self.ContentType = ContentType
DEFAULT_TYPES = [
FileExtension("rels", "application/vnd.openxmlformats-package.relationships+xml"),
FileExtension("xml", "application/xml"),
]
DEFAULT_OVERRIDE = [
Override("/" + ARC_STYLE, STYLES_TYPE), # Styles
Override("/" + ARC_THEME, THEME_TYPE), # Theme
Override("/docProps/core.xml", "application/vnd.openxmlformats-package.core-properties+xml"),
Override("/docProps/app.xml", "application/vnd.openxmlformats-officedocument.extended-properties+xml")
]
class Manifest(Serialisable):
tagname = "Types"
Default = Sequence(expected_type=FileExtension, unique=True)
Override = Sequence(expected_type=Override, unique=True)
path = "[Content_Types].xml"
__elements__ = ("Default", "Override")
def __init__(self,
Default=(),
Override=(),
):
if not Default:
Default = DEFAULT_TYPES
self.Default = Default
if not Override:
Override = DEFAULT_OVERRIDE
self.Override = Override
@property
def filenames(self):
return [part.PartName for part in self.Override]
@property
def extensions(self):
"""
Map content types to file extensions
Skip parts without extensions
"""
exts = {os.path.splitext(part.PartName)[-1] for part in self.Override}
return [(ext[1:], mimetypes.types_map[True][ext]) for ext in sorted(exts) if ext]
def to_tree(self):
"""
Custom serialisation method to allow setting a default namespace
"""
defaults = [t.Extension for t in self.Default]
for ext, mime in self.extensions:
if ext not in defaults:
mime = FileExtension(ext, mime)
self.Default.append(mime)
tree = super().to_tree()
tree.set("xmlns", CONTYPES_NS)
return tree
def __contains__(self, content_type):
"""
Check whether a particular content type is contained
"""
for t in self.Override:
if t.ContentType == content_type:
return True
def find(self, content_type):
"""
Find specific content-type
"""
try:
return next(self.findall(content_type))
except StopIteration:
return
def findall(self, content_type):
"""
Find all elements of a specific content-type
"""
for t in self.Override:
if t.ContentType == content_type:
yield t
def append(self, obj):
"""
Add content object to the package manifest
# needs a contract...
"""
ct = Override(PartName=obj.path, ContentType=obj.mime_type)
self.Override.append(ct)
def _write(self, archive, workbook):
"""
Write manifest to the archive
"""
self.append(workbook)
self._write_vba(workbook)
self._register_mimetypes(filenames=archive.namelist())
archive.writestr(self.path, tostring(self.to_tree()))
def _register_mimetypes(self, filenames):
"""
Make sure that the mime type for all file extensions is registered
"""
for fn in filenames:
ext = os.path.splitext(fn)[-1]
if not ext:
continue
mime = mimetypes.types_map[True][ext]
fe = FileExtension(ext[1:], mime)
self.Default.append(fe)
def _write_vba(self, workbook):
"""
Add content types from cached workbook when keeping VBA
"""
if workbook.vba_archive:
node = fromstring(workbook.vba_archive.read(ARC_CONTENT_TYPES))
mf = Manifest.from_tree(node)
filenames = self.filenames
for override in mf.Override:
if override.PartName not in (ACTIVEX, CTRL, VBA):
continue
if override.PartName not in filenames:
self.Override.append(override)

View File

@ -0,0 +1,158 @@
# Copyright (c) 2010-2024 openpyxl
import posixpath
from warnings import warn
from openpyxl.descriptors import (
String,
Alias,
Sequence,
)
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors.container import ElementList
from openpyxl.xml.constants import REL_NS, PKG_REL_NS
from openpyxl.xml.functions import (
Element,
fromstring,
)
class Relationship(Serialisable):
"""Represents many kinds of relationships."""
tagname = "Relationship"
Type = String()
Target = String()
target = Alias("Target")
TargetMode = String(allow_none=True)
Id = String(allow_none=True)
id = Alias("Id")
def __init__(self,
Id=None,
Type=None,
type=None,
Target=None,
TargetMode=None
):
"""
`type` can be used as a shorthand with the default relationships namespace
otherwise the `Type` must be a fully qualified URL
"""
if type is not None:
Type = "{0}/{1}".format(REL_NS, type)
self.Type = Type
self.Target = Target
self.TargetMode = TargetMode
self.Id = Id
class RelationshipList(ElementList):
tagname = "Relationships"
expected_type = Relationship
def append(self, value):
super().append(value)
if not value.Id:
value.Id = f"rId{len(self)}"
def find(self, content_type):
"""
Find relationships by content-type
NB. these content-types namespaced objects and different to the MIME-types
in the package manifest :-(
"""
for r in self:
if r.Type == content_type:
yield r
def get(self, key):
for r in self:
if r.Id == key:
return r
raise KeyError("Unknown relationship: {0}".format(key))
def to_dict(self):
"""Return a dictionary of relations keyed by id"""
return {r.id:r for r in self}
def to_tree(self):
tree = super().to_tree()
tree.set("xmlns", PKG_REL_NS)
return tree
def get_rels_path(path):
"""
Convert relative path to absolutes that can be loaded from a zip
archive.
The path to be passed in is that of containing object (workbook,
worksheet, etc.)
"""
folder, obj = posixpath.split(path)
filename = posixpath.join(folder, '_rels', '{0}.rels'.format(obj))
return filename
def get_dependents(archive, filename):
"""
Normalise dependency file paths to absolute ones
Relative paths are relative to parent object
"""
src = archive.read(filename)
node = fromstring(src)
try:
rels = RelationshipList.from_tree(node)
except TypeError:
msg = "{0} contains invalid dependency definitions".format(filename)
warn(msg)
rels = RelationshipList()
folder = posixpath.dirname(filename)
parent = posixpath.split(folder)[0]
for r in rels:
if r.TargetMode == "External":
continue
elif r.target.startswith("/"):
r.target = r.target[1:]
else:
pth = posixpath.join(parent, r.target)
r.target = posixpath.normpath(pth)
return rels
def get_rel(archive, deps, id=None, cls=None):
"""
Get related object based on id or rel_type
"""
if not any([id, cls]):
raise ValueError("Either the id or the content type are required")
if id is not None:
rel = deps.get(id)
else:
try:
rel = next(deps.find(cls.rel_type))
except StopIteration: # no known dependency
return
path = rel.target
src = archive.read(path)
tree = fromstring(src)
obj = cls.from_tree(tree)
rels_path = get_rels_path(path)
try:
obj.deps = get_dependents(archive, rels_path)
except KeyError:
obj.deps = []
return obj

View File

@ -0,0 +1,185 @@
# Copyright (c) 2010-2024 openpyxl
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Alias,
Typed,
String,
Integer,
Bool,
NoneSet,
)
from openpyxl.descriptors.excel import ExtensionList, Relation
from openpyxl.descriptors.sequence import NestedSequence
from openpyxl.descriptors.nested import NestedString
from openpyxl.xml.constants import SHEET_MAIN_NS
from openpyxl.workbook.defined_name import DefinedNameList
from openpyxl.workbook.external_reference import ExternalReference
from openpyxl.workbook.function_group import FunctionGroupList
from openpyxl.workbook.properties import WorkbookProperties, CalcProperties, FileVersion
from openpyxl.workbook.protection import WorkbookProtection, FileSharing
from openpyxl.workbook.smart_tags import SmartTagList, SmartTagProperties
from openpyxl.workbook.views import CustomWorkbookView, BookView
from openpyxl.workbook.web import WebPublishing, WebPublishObjectList
class FileRecoveryProperties(Serialisable):
tagname = "fileRecoveryPr"
autoRecover = Bool(allow_none=True)
crashSave = Bool(allow_none=True)
dataExtractLoad = Bool(allow_none=True)
repairLoad = Bool(allow_none=True)
def __init__(self,
autoRecover=None,
crashSave=None,
dataExtractLoad=None,
repairLoad=None,
):
self.autoRecover = autoRecover
self.crashSave = crashSave
self.dataExtractLoad = dataExtractLoad
self.repairLoad = repairLoad
class ChildSheet(Serialisable):
"""
Represents a reference to a worksheet or chartsheet in workbook.xml
It contains the title, order and state but only an indirect reference to
the objects themselves.
"""
tagname = "sheet"
name = String()
sheetId = Integer()
state = NoneSet(values=(['visible', 'hidden', 'veryHidden']))
id = Relation()
def __init__(self,
name=None,
sheetId=None,
state="visible",
id=None,
):
self.name = name
self.sheetId = sheetId
self.state = state
self.id = id
class PivotCache(Serialisable):
tagname = "pivotCache"
cacheId = Integer()
id = Relation()
def __init__(self,
cacheId=None,
id=None
):
self.cacheId = cacheId
self.id = id
class WorkbookPackage(Serialisable):
"""
Represent the workbook file in the archive
"""
tagname = "workbook"
conformance = NoneSet(values=['strict', 'transitional'])
fileVersion = Typed(expected_type=FileVersion, allow_none=True)
fileSharing = Typed(expected_type=FileSharing, allow_none=True)
workbookPr = Typed(expected_type=WorkbookProperties, allow_none=True)
properties = Alias("workbookPr")
workbookProtection = Typed(expected_type=WorkbookProtection, allow_none=True)
bookViews = NestedSequence(expected_type=BookView)
sheets = NestedSequence(expected_type=ChildSheet)
functionGroups = Typed(expected_type=FunctionGroupList, allow_none=True)
externalReferences = NestedSequence(expected_type=ExternalReference)
definedNames = Typed(expected_type=DefinedNameList, allow_none=True)
calcPr = Typed(expected_type=CalcProperties, allow_none=True)
oleSize = NestedString(allow_none=True, attribute="ref")
customWorkbookViews = NestedSequence(expected_type=CustomWorkbookView)
pivotCaches = NestedSequence(expected_type=PivotCache, allow_none=True)
smartTagPr = Typed(expected_type=SmartTagProperties, allow_none=True)
smartTagTypes = Typed(expected_type=SmartTagList, allow_none=True)
webPublishing = Typed(expected_type=WebPublishing, allow_none=True)
fileRecoveryPr = Typed(expected_type=FileRecoveryProperties, allow_none=True)
webPublishObjects = Typed(expected_type=WebPublishObjectList, allow_none=True)
extLst = Typed(expected_type=ExtensionList, allow_none=True)
Ignorable = NestedString(namespace="http://schemas.openxmlformats.org/markup-compatibility/2006", allow_none=True)
__elements__ = ('fileVersion', 'fileSharing', 'workbookPr',
'workbookProtection', 'bookViews', 'sheets', 'functionGroups',
'externalReferences', 'definedNames', 'calcPr', 'oleSize',
'customWorkbookViews', 'pivotCaches', 'smartTagPr', 'smartTagTypes',
'webPublishing', 'fileRecoveryPr', 'webPublishObjects')
def __init__(self,
conformance=None,
fileVersion=None,
fileSharing=None,
workbookPr=None,
workbookProtection=None,
bookViews=(),
sheets=(),
functionGroups=None,
externalReferences=(),
definedNames=None,
calcPr=None,
oleSize=None,
customWorkbookViews=(),
pivotCaches=(),
smartTagPr=None,
smartTagTypes=None,
webPublishing=None,
fileRecoveryPr=None,
webPublishObjects=None,
extLst=None,
Ignorable=None,
):
self.conformance = conformance
self.fileVersion = fileVersion
self.fileSharing = fileSharing
if workbookPr is None:
workbookPr = WorkbookProperties()
self.workbookPr = workbookPr
self.workbookProtection = workbookProtection
self.bookViews = bookViews
self.sheets = sheets
self.functionGroups = functionGroups
self.externalReferences = externalReferences
self.definedNames = definedNames
self.calcPr = calcPr
self.oleSize = oleSize
self.customWorkbookViews = customWorkbookViews
self.pivotCaches = pivotCaches
self.smartTagPr = smartTagPr
self.smartTagTypes = smartTagTypes
self.webPublishing = webPublishing
self.fileRecoveryPr = fileRecoveryPr
self.webPublishObjects = webPublishObjects
def to_tree(self):
tree = super().to_tree()
tree.set("xmlns", SHEET_MAIN_NS)
return tree
@property
def active(self):
for view in self.bookViews:
if view.activeTab is not None:
return view.activeTab
return 0