borders.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. from __future__ import absolute_import
  2. # Copyright (c) 2010-2019 openpyxl
  3. from openpyxl.compat import safe_string
  4. from openpyxl.descriptors import (
  5. NoneSet,
  6. Typed,
  7. Bool,
  8. Alias,
  9. Sequence,
  10. Integer,
  11. )
  12. from openpyxl.descriptors.serialisable import Serialisable
  13. from .colors import ColorDescriptor
  14. BORDER_NONE = None
  15. BORDER_DASHDOT = 'dashDot'
  16. BORDER_DASHDOTDOT = 'dashDotDot'
  17. BORDER_DASHED = 'dashed'
  18. BORDER_DOTTED = 'dotted'
  19. BORDER_DOUBLE = 'double'
  20. BORDER_HAIR = 'hair'
  21. BORDER_MEDIUM = 'medium'
  22. BORDER_MEDIUMDASHDOT = 'mediumDashDot'
  23. BORDER_MEDIUMDASHDOTDOT = 'mediumDashDotDot'
  24. BORDER_MEDIUMDASHED = 'mediumDashed'
  25. BORDER_SLANTDASHDOT = 'slantDashDot'
  26. BORDER_THICK = 'thick'
  27. BORDER_THIN = 'thin'
  28. class Side(Serialisable):
  29. """Border options for use in styles.
  30. Caution: if you do not specify a border_style, other attributes will
  31. have no effect !"""
  32. __fields__ = ('style',
  33. 'color')
  34. color = ColorDescriptor(allow_none=True)
  35. style = NoneSet(values=('dashDot','dashDotDot', 'dashed','dotted',
  36. 'double','hair', 'medium', 'mediumDashDot', 'mediumDashDotDot',
  37. 'mediumDashed', 'slantDashDot', 'thick', 'thin')
  38. )
  39. border_style = Alias('style')
  40. def __init__(self, style=None, color=None, border_style=None):
  41. if border_style is not None:
  42. style = border_style
  43. self.style = style
  44. self.color = color
  45. class Border(Serialisable):
  46. """Border positioning for use in styles."""
  47. tagname = "border"
  48. __fields__ = ('left',
  49. 'right',
  50. 'top',
  51. 'bottom',
  52. 'diagonal',
  53. 'diagonal_direction',
  54. 'vertical',
  55. 'horizontal')
  56. __elements__ = ('start', 'end', 'left', 'right', 'top', 'bottom',
  57. 'diagonal', 'vertical', 'horizontal')
  58. # child elements
  59. start = Typed(expected_type=Side, allow_none=True)
  60. end = Typed(expected_type=Side, allow_none=True)
  61. left = Typed(expected_type=Side, allow_none=True)
  62. right = Typed(expected_type=Side, allow_none=True)
  63. top = Typed(expected_type=Side, allow_none=True)
  64. bottom = Typed(expected_type=Side)
  65. diagonal = Typed(expected_type=Side, allow_none=True)
  66. vertical = Typed(expected_type=Side, allow_none=True)
  67. horizontal = Typed(expected_type=Side, allow_none=True)
  68. # attributes
  69. outline = Bool()
  70. diagonalUp = Bool()
  71. diagonalDown = Bool()
  72. def __init__(self, left=Side(), right=Side(), top=Side(),
  73. bottom=Side(), diagonal=Side(), diagonal_direction=None,
  74. vertical=None, horizontal=None, diagonalUp=False, diagonalDown=False,
  75. outline=True, start=None, end=None):
  76. self.left = left
  77. self.right = right
  78. self.top = top
  79. self.bottom = bottom
  80. self.diagonal = diagonal
  81. self.vertical = vertical
  82. self.horizontal = horizontal
  83. self.diagonal_direction = diagonal_direction
  84. self.diagonalUp = diagonalUp
  85. self.diagonalDown = diagonalDown
  86. self.outline = outline
  87. self.start = start
  88. self.end = end
  89. def __iter__(self):
  90. for attr in self.__attrs__:
  91. value = getattr(self, attr)
  92. if value and attr != "outline":
  93. yield attr, safe_string(value)
  94. elif attr == "outline" and not value:
  95. yield attr, safe_string(value)
  96. DEFAULT_BORDER = Border()