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