excel.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. from __future__ import absolute_import
  2. # Copyright (c) 2010-2019 openpyxl
  3. """
  4. Excel specific descriptors
  5. """
  6. from openpyxl.xml.constants import REL_NS
  7. from openpyxl.compat import safe_string, unicode
  8. from openpyxl.xml.functions import Element
  9. from . import (
  10. MatchPattern,
  11. MinMax,
  12. Integer,
  13. String,
  14. Typed,
  15. Sequence,
  16. )
  17. from .serialisable import Serialisable
  18. from openpyxl.utils.cell import RANGE_EXPR
  19. class HexBinary(MatchPattern):
  20. pattern = "[0-9a-fA-F]+$"
  21. class UniversalMeasure(MatchPattern):
  22. pattern = r"[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"
  23. class TextPoint(MinMax):
  24. """
  25. Size in hundredths of points.
  26. In theory other units of measurement can be used but these are unbounded
  27. """
  28. expected_type = int
  29. min = -400000
  30. max = 400000
  31. Coordinate = Integer
  32. class Percentage(MinMax):
  33. pattern = r"((100)|([0-9][0-9]?))(\.[0-9][0-9]?)?%" # strict
  34. min = -1000000
  35. max = 1000000
  36. def __set__(self, instance, value):
  37. if isinstance(value, unicode) and "%" in value:
  38. value = value.replace("%", "")
  39. value = int(float(value) * 1000)
  40. super(Percentage, self).__set__(instance, value)
  41. class Extension(Serialisable):
  42. uri = String()
  43. def __init__(self,
  44. uri=None,
  45. ):
  46. self.uri = uri
  47. class ExtensionList(Serialisable):
  48. ext = Sequence(expected_type=Extension)
  49. def __init__(self,
  50. ext=(),
  51. ):
  52. self.ext = ext
  53. class Relation(String):
  54. namespace = REL_NS
  55. allow_none = True
  56. class Base64Binary(MatchPattern):
  57. # http://www.w3.org/TR/xmlschema11-2/#nt-Base64Binary
  58. pattern = "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$"
  59. class Guid(MatchPattern):
  60. # https://msdn.microsoft.com/en-us/library/dd946381(v=office.12).aspx
  61. pattern = r"{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}"
  62. class CellRange(MatchPattern):
  63. pattern = r"^[$]?([A-Za-z]{1,3})[$]?(\d+)(:[$]?([A-Za-z]{1,3})[$]?(\d+)?)?$|^[A-Za-z]{1,3}:[A-Za-z]{1,3}$"
  64. allow_none = True
  65. def __set__(self, instance, value):
  66. if value is not None:
  67. value = value.upper()
  68. super(CellRange, self).__set__(instance, value)
  69. def _explicit_none(tagname, value, namespace=None):
  70. """
  71. Override serialisation because explicit none required
  72. """
  73. if namespace is not None:
  74. tagname = "{%s}%s" % (namespace, tagname)
  75. return Element(tagname, val=safe_string(value))