Formatting.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. '''
  2. Formatting
  3. ==========
  4. The XF record is able to store explicit cell formatting attributes or the
  5. attributes of a cell style. Explicit formatting includes the reference to
  6. a cell style XF record. This allows to extend a defined cell style with
  7. some explicit attributes. The formatting attributes are divided into
  8. 6 groups:
  9. ============= ==========================================================
  10. Group Attributes
  11. ============= ==========================================================
  12. Number format Number format index (index to FORMAT record)
  13. Font Font index (index to FONT record)
  14. Alignment Horizontal and vertical alignment, text wrap, indentation,
  15. orientation/rotation, text direction
  16. Border Border line styles and colours
  17. Background Background area style and colours
  18. Protection Cell locked, formula hidden
  19. ============= ==========================================================
  20. For each group a flag in the cell XF record specifies whether to use the
  21. attributes contained in that XF record or in the referenced style
  22. XF record. In style XF records, these flags specify whether the attributes
  23. will overwrite explicit cell formatting when the style is applied to
  24. a cell. Changing a cell style (without applying this style to a cell) will
  25. change all cells which already use that style and do not contain explicit
  26. cell attributes for the changed style attributes. If a cell XF record does
  27. not contain explicit attributes in a group (if the attribute group flag
  28. is not set), it repeats the attributes of its style XF record.
  29. '''
  30. from . import BIFFRecords
  31. class Font(object):
  32. ESCAPEMENT_NONE = 0x00
  33. ESCAPEMENT_SUPERSCRIPT = 0x01
  34. ESCAPEMENT_SUBSCRIPT = 0x02
  35. UNDERLINE_NONE = 0x00
  36. UNDERLINE_SINGLE = 0x01
  37. UNDERLINE_SINGLE_ACC = 0x21
  38. UNDERLINE_DOUBLE = 0x02
  39. UNDERLINE_DOUBLE_ACC = 0x22
  40. FAMILY_NONE = 0x00
  41. FAMILY_ROMAN = 0x01
  42. FAMILY_SWISS = 0x02
  43. FAMILY_MODERN = 0x03
  44. FAMILY_SCRIPT = 0x04
  45. FAMILY_DECORATIVE = 0x05
  46. CHARSET_ANSI_LATIN = 0x00
  47. CHARSET_SYS_DEFAULT = 0x01
  48. CHARSET_SYMBOL = 0x02
  49. CHARSET_APPLE_ROMAN = 0x4D
  50. CHARSET_ANSI_JAP_SHIFT_JIS = 0x80
  51. CHARSET_ANSI_KOR_HANGUL = 0x81
  52. CHARSET_ANSI_KOR_JOHAB = 0x82
  53. CHARSET_ANSI_CHINESE_GBK = 0x86
  54. CHARSET_ANSI_CHINESE_BIG5 = 0x88
  55. CHARSET_ANSI_GREEK = 0xA1
  56. CHARSET_ANSI_TURKISH = 0xA2
  57. CHARSET_ANSI_VIETNAMESE = 0xA3
  58. CHARSET_ANSI_HEBREW = 0xB1
  59. CHARSET_ANSI_ARABIC = 0xB2
  60. CHARSET_ANSI_BALTIC = 0xBA
  61. CHARSET_ANSI_CYRILLIC = 0xCC
  62. CHARSET_ANSI_THAI = 0xDE
  63. CHARSET_ANSI_LATIN_II = 0xEE
  64. CHARSET_OEM_LATIN_I = 0xFF
  65. def __init__(self):
  66. # twip = 1/20 of a point = 1/1440 of a inch
  67. # usually resolution == 96 pixels per 1 inch
  68. # (rarely 120 pixels per 1 inch or another one)
  69. self.height = 0x00C8 # 200: this is font with height 10 points
  70. self.italic = False
  71. self.struck_out = False
  72. self.outline = False
  73. self.shadow = False
  74. self.colour_index = 0x7FFF
  75. self.bold = False
  76. self._weight = 0x0190 # 0x02BC gives bold font
  77. self.escapement = self.ESCAPEMENT_NONE
  78. self.underline = self.UNDERLINE_NONE
  79. self.family = self.FAMILY_NONE
  80. self.charset = self.CHARSET_SYS_DEFAULT
  81. self.name = 'Arial'
  82. def get_biff_record(self):
  83. height = self.height
  84. options = 0x00
  85. if self.bold:
  86. options |= 0x01
  87. self._weight = 0x02BC
  88. if self.italic:
  89. options |= 0x02
  90. if self.underline != self.UNDERLINE_NONE:
  91. options |= 0x04
  92. if self.struck_out:
  93. options |= 0x08
  94. if self.outline:
  95. options |= 0x010
  96. if self.shadow:
  97. options |= 0x020
  98. colour_index = self.colour_index
  99. weight = self._weight
  100. escapement = self.escapement
  101. underline = self.underline
  102. family = self.family
  103. charset = self.charset
  104. name = self.name
  105. return BIFFRecords.FontRecord(height, options, colour_index, weight, escapement,
  106. underline, family, charset,
  107. name)
  108. def _search_key(self):
  109. return (
  110. self.height,
  111. self.italic,
  112. self.struck_out,
  113. self.outline,
  114. self.shadow,
  115. self.colour_index,
  116. self.bold,
  117. self._weight,
  118. self.escapement,
  119. self.underline,
  120. self.family,
  121. self.charset,
  122. self.name,
  123. )
  124. class Alignment(object):
  125. HORZ_GENERAL = 0x00
  126. HORZ_LEFT = 0x01
  127. HORZ_CENTER = 0x02
  128. HORZ_RIGHT = 0x03
  129. HORZ_FILLED = 0x04
  130. HORZ_JUSTIFIED = 0x05 # BIFF4-BIFF8X
  131. HORZ_CENTER_ACROSS_SEL = 0x06 # Centred across selection (BIFF4-BIFF8X)
  132. HORZ_DISTRIBUTED = 0x07 # Distributed (BIFF8X)
  133. VERT_TOP = 0x00
  134. VERT_CENTER = 0x01
  135. VERT_BOTTOM = 0x02
  136. VERT_JUSTIFIED = 0x03 # Justified (BIFF5-BIFF8X)
  137. VERT_DISTRIBUTED = 0x04 # Distributed (BIFF8X)
  138. DIRECTION_GENERAL = 0x00 # BIFF8X
  139. DIRECTION_LR = 0x01
  140. DIRECTION_RL = 0x02
  141. ORIENTATION_NOT_ROTATED = 0x00
  142. ORIENTATION_STACKED = 0x01
  143. ORIENTATION_90_CC = 0x02
  144. ORIENTATION_90_CW = 0x03
  145. ROTATION_0_ANGLE = 0x00
  146. ROTATION_STACKED = 0xFF
  147. WRAP_AT_RIGHT = 0x01
  148. NOT_WRAP_AT_RIGHT = 0x00
  149. SHRINK_TO_FIT = 0x01
  150. NOT_SHRINK_TO_FIT = 0x00
  151. def __init__(self):
  152. self.horz = self.HORZ_GENERAL
  153. self.vert = self.VERT_BOTTOM
  154. self.dire = self.DIRECTION_GENERAL
  155. self.orie = self.ORIENTATION_NOT_ROTATED
  156. self.rota = self.ROTATION_0_ANGLE
  157. self.wrap = self.NOT_WRAP_AT_RIGHT
  158. self.shri = self.NOT_SHRINK_TO_FIT
  159. self.inde = 0
  160. self.merg = 0
  161. def _search_key(self):
  162. return (
  163. self.horz, self.vert, self.dire, self.orie, self.rota,
  164. self.wrap, self.shri, self.inde, self.merg,
  165. )
  166. class Borders(object):
  167. NO_LINE = 0x00
  168. THIN = 0x01
  169. MEDIUM = 0x02
  170. DASHED = 0x03
  171. DOTTED = 0x04
  172. THICK = 0x05
  173. DOUBLE = 0x06
  174. HAIR = 0x07
  175. #The following for BIFF8
  176. MEDIUM_DASHED = 0x08
  177. THIN_DASH_DOTTED = 0x09
  178. MEDIUM_DASH_DOTTED = 0x0A
  179. THIN_DASH_DOT_DOTTED = 0x0B
  180. MEDIUM_DASH_DOT_DOTTED = 0x0C
  181. SLANTED_MEDIUM_DASH_DOTTED = 0x0D
  182. NEED_DIAG1 = 0x01
  183. NEED_DIAG2 = 0x01
  184. NO_NEED_DIAG1 = 0x00
  185. NO_NEED_DIAG2 = 0x00
  186. def __init__(self):
  187. self.left = self.NO_LINE
  188. self.right = self.NO_LINE
  189. self.top = self.NO_LINE
  190. self.bottom = self.NO_LINE
  191. self.diag = self.NO_LINE
  192. self.left_colour = 0x40
  193. self.right_colour = 0x40
  194. self.top_colour = 0x40
  195. self.bottom_colour = 0x40
  196. self.diag_colour = 0x40
  197. self.need_diag1 = self.NO_NEED_DIAG1
  198. self.need_diag2 = self.NO_NEED_DIAG2
  199. def _search_key(self):
  200. return (
  201. self.left, self.right, self.top, self.bottom, self.diag,
  202. self.left_colour, self.right_colour, self.top_colour,
  203. self.bottom_colour, self.diag_colour,
  204. self.need_diag1, self.need_diag2,
  205. )
  206. class Pattern(object):
  207. # patterns 0x00 - 0x12
  208. NO_PATTERN = 0x00
  209. SOLID_PATTERN = 0x01
  210. def __init__(self):
  211. self.pattern = self.NO_PATTERN
  212. self.pattern_fore_colour = 0x40
  213. self.pattern_back_colour = 0x41
  214. def _search_key(self):
  215. return (
  216. self.pattern,
  217. self.pattern_fore_colour,
  218. self.pattern_back_colour,
  219. )
  220. class Protection(object):
  221. def __init__(self):
  222. self.cell_locked = 1
  223. self.formula_hidden = 0
  224. def _search_key(self):
  225. return (
  226. self.cell_locked,
  227. self.formula_hidden,
  228. )