formatting.py 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
  1. # -*- coding: cp1252 -*-
  2. ##
  3. # Module for formatting information.
  4. #
  5. # <p>Copyright © 2005-2012 Stephen John Machin, Lingfo Pty Ltd</p>
  6. # <p>This module is part of the xlrd package, which is released under
  7. # a BSD-style licence.</p>
  8. ##
  9. # No part of the content of this file was derived from the works of David Giffin.
  10. from __future__ import print_function
  11. DEBUG = 0
  12. import re
  13. from struct import unpack
  14. from .timemachine import *
  15. from .biffh import BaseObject, unpack_unicode, unpack_string, \
  16. upkbits, upkbitsL, fprintf, \
  17. FUN, FDT, FNU, FGE, FTX, XL_CELL_NUMBER, XL_CELL_DATE, XL_CELL_TEXT, \
  18. XL_FORMAT, XL_FORMAT2, \
  19. XLRDError
  20. _cellty_from_fmtty = {
  21. FNU: XL_CELL_NUMBER,
  22. FUN: XL_CELL_NUMBER,
  23. FGE: XL_CELL_NUMBER,
  24. FDT: XL_CELL_DATE,
  25. FTX: XL_CELL_NUMBER, # Yes, a number can be formatted as text.
  26. }
  27. excel_default_palette_b5 = (
  28. ( 0, 0, 0), (255, 255, 255), (255, 0, 0), ( 0, 255, 0),
  29. ( 0, 0, 255), (255, 255, 0), (255, 0, 255), ( 0, 255, 255),
  30. (128, 0, 0), ( 0, 128, 0), ( 0, 0, 128), (128, 128, 0),
  31. (128, 0, 128), ( 0, 128, 128), (192, 192, 192), (128, 128, 128),
  32. (153, 153, 255), (153, 51, 102), (255, 255, 204), (204, 255, 255),
  33. (102, 0, 102), (255, 128, 128), ( 0, 102, 204), (204, 204, 255),
  34. ( 0, 0, 128), (255, 0, 255), (255, 255, 0), ( 0, 255, 255),
  35. (128, 0, 128), (128, 0, 0), ( 0, 128, 128), ( 0, 0, 255),
  36. ( 0, 204, 255), (204, 255, 255), (204, 255, 204), (255, 255, 153),
  37. (153, 204, 255), (255, 153, 204), (204, 153, 255), (227, 227, 227),
  38. ( 51, 102, 255), ( 51, 204, 204), (153, 204, 0), (255, 204, 0),
  39. (255, 153, 0), (255, 102, 0), (102, 102, 153), (150, 150, 150),
  40. ( 0, 51, 102), ( 51, 153, 102), ( 0, 51, 0), ( 51, 51, 0),
  41. (153, 51, 0), (153, 51, 102), ( 51, 51, 153), ( 51, 51, 51),
  42. )
  43. excel_default_palette_b2 = excel_default_palette_b5[:16]
  44. # Following table borrowed from Gnumeric 1.4 source.
  45. # Checked against OOo docs and MS docs.
  46. excel_default_palette_b8 = ( # (red, green, blue)
  47. ( 0, 0, 0), (255,255,255), (255, 0, 0), ( 0,255, 0), # 0
  48. ( 0, 0,255), (255,255, 0), (255, 0,255), ( 0,255,255), # 4
  49. (128, 0, 0), ( 0,128, 0), ( 0, 0,128), (128,128, 0), # 8
  50. (128, 0,128), ( 0,128,128), (192,192,192), (128,128,128), # 12
  51. (153,153,255), (153, 51,102), (255,255,204), (204,255,255), # 16
  52. (102, 0,102), (255,128,128), ( 0,102,204), (204,204,255), # 20
  53. ( 0, 0,128), (255, 0,255), (255,255, 0), ( 0,255,255), # 24
  54. (128, 0,128), (128, 0, 0), ( 0,128,128), ( 0, 0,255), # 28
  55. ( 0,204,255), (204,255,255), (204,255,204), (255,255,153), # 32
  56. (153,204,255), (255,153,204), (204,153,255), (255,204,153), # 36
  57. ( 51,102,255), ( 51,204,204), (153,204, 0), (255,204, 0), # 40
  58. (255,153, 0), (255,102, 0), (102,102,153), (150,150,150), # 44
  59. ( 0, 51,102), ( 51,153,102), ( 0, 51, 0), ( 51, 51, 0), # 48
  60. (153, 51, 0), (153, 51,102), ( 51, 51,153), ( 51, 51, 51), # 52
  61. )
  62. default_palette = {
  63. 80: excel_default_palette_b8,
  64. 70: excel_default_palette_b5,
  65. 50: excel_default_palette_b5,
  66. 45: excel_default_palette_b2,
  67. 40: excel_default_palette_b2,
  68. 30: excel_default_palette_b2,
  69. 21: excel_default_palette_b2,
  70. 20: excel_default_palette_b2,
  71. }
  72. """
  73. 00H = Normal
  74. 01H = RowLevel_lv (see next field)
  75. 02H = ColLevel_lv (see next field)
  76. 03H = Comma
  77. 04H = Currency
  78. 05H = Percent
  79. 06H = Comma [0] (BIFF4-BIFF8)
  80. 07H = Currency [0] (BIFF4-BIFF8)
  81. 08H = Hyperlink (BIFF8)
  82. 09H = Followed Hyperlink (BIFF8)
  83. """
  84. built_in_style_names = [
  85. "Normal",
  86. "RowLevel_",
  87. "ColLevel_",
  88. "Comma",
  89. "Currency",
  90. "Percent",
  91. "Comma [0]",
  92. "Currency [0]",
  93. "Hyperlink",
  94. "Followed Hyperlink",
  95. ]
  96. def initialise_colour_map(book):
  97. book.colour_map = {}
  98. book.colour_indexes_used = {}
  99. if not book.formatting_info:
  100. return
  101. # Add the 8 invariant colours
  102. for i in xrange(8):
  103. book.colour_map[i] = excel_default_palette_b8[i]
  104. # Add the default palette depending on the version
  105. dpal = default_palette[book.biff_version]
  106. ndpal = len(dpal)
  107. for i in xrange(ndpal):
  108. book.colour_map[i+8] = dpal[i]
  109. # Add the specials -- None means the RGB value is not known
  110. # System window text colour for border lines
  111. book.colour_map[ndpal+8] = None
  112. # System window background colour for pattern background
  113. book.colour_map[ndpal+8+1] = None #
  114. for ci in (
  115. 0x51, # System ToolTip text colour (used in note objects)
  116. 0x7FFF, # 32767, system window text colour for fonts
  117. ):
  118. book.colour_map[ci] = None
  119. def nearest_colour_index(colour_map, rgb, debug=0):
  120. # General purpose function. Uses Euclidean distance.
  121. # So far used only for pre-BIFF8 WINDOW2 record.
  122. # Doesn't have to be fast.
  123. # Doesn't have to be fancy.
  124. best_metric = 3 * 256 * 256
  125. best_colourx = 0
  126. for colourx, cand_rgb in colour_map.items():
  127. if cand_rgb is None:
  128. continue
  129. metric = 0
  130. for v1, v2 in zip(rgb, cand_rgb):
  131. metric += (v1 - v2) * (v1 - v2)
  132. if metric < best_metric:
  133. best_metric = metric
  134. best_colourx = colourx
  135. if metric == 0:
  136. break
  137. if 0 and debug:
  138. print("nearest_colour_index for %r is %r -> %r; best_metric is %d" \
  139. % (rgb, best_colourx, colour_map[best_colourx], best_metric))
  140. return best_colourx
  141. ##
  142. # This mixin class exists solely so that Format, Font, and XF.... objects
  143. # can be compared by value of their attributes.
  144. class EqNeAttrs(object):
  145. def __eq__(self, other):
  146. return self.__dict__ == other.__dict__
  147. def __ne__(self, other):
  148. return self.__dict__ != other.__dict__
  149. ##
  150. # An Excel "font" contains the details of not only what is normally
  151. # considered a font, but also several other display attributes.
  152. # Items correspond to those in the Excel UI's Format/Cells/Font tab.
  153. # <br /> -- New in version 0.6.1
  154. class Font(BaseObject, EqNeAttrs):
  155. ##
  156. # 1 = Characters are bold. Redundant; see "weight" attribute.
  157. bold = 0
  158. ##
  159. # Values: 0 = ANSI Latin, 1 = System default, 2 = Symbol,
  160. # 77 = Apple Roman,
  161. # 128 = ANSI Japanese Shift-JIS,
  162. # 129 = ANSI Korean (Hangul),
  163. # 130 = ANSI Korean (Johab),
  164. # 134 = ANSI Chinese Simplified GBK,
  165. # 136 = ANSI Chinese Traditional BIG5,
  166. # 161 = ANSI Greek,
  167. # 162 = ANSI Turkish,
  168. # 163 = ANSI Vietnamese,
  169. # 177 = ANSI Hebrew,
  170. # 178 = ANSI Arabic,
  171. # 186 = ANSI Baltic,
  172. # 204 = ANSI Cyrillic,
  173. # 222 = ANSI Thai,
  174. # 238 = ANSI Latin II (Central European),
  175. # 255 = OEM Latin I
  176. character_set = 0
  177. ##
  178. # An explanation of "colour index" is given in the Formatting
  179. # section at the start of this document.
  180. colour_index = 0
  181. ##
  182. # 1 = Superscript, 2 = Subscript.
  183. escapement = 0
  184. ##
  185. # 0 = None (unknown or don't care)<br />
  186. # 1 = Roman (variable width, serifed)<br />
  187. # 2 = Swiss (variable width, sans-serifed)<br />
  188. # 3 = Modern (fixed width, serifed or sans-serifed)<br />
  189. # 4 = Script (cursive)<br />
  190. # 5 = Decorative (specialised, for example Old English, Fraktur)
  191. family = 0
  192. ##
  193. # The 0-based index used to refer to this Font() instance.
  194. # Note that index 4 is never used; xlrd supplies a dummy place-holder.
  195. font_index = 0
  196. ##
  197. # Height of the font (in twips). A twip = 1/20 of a point.
  198. height = 0
  199. ##
  200. # 1 = Characters are italic.
  201. italic = 0
  202. ##
  203. # The name of the font. Example: u"Arial"
  204. name = UNICODE_LITERAL("")
  205. ##
  206. # 1 = Characters are struck out.
  207. struck_out = 0
  208. ##
  209. # 0 = None<br />
  210. # 1 = Single; 0x21 (33) = Single accounting<br />
  211. # 2 = Double; 0x22 (34) = Double accounting
  212. underline_type = 0
  213. ##
  214. # 1 = Characters are underlined. Redundant; see "underline_type" attribute.
  215. underlined = 0
  216. ##
  217. # Font weight (100-1000). Standard values are 400 for normal text
  218. # and 700 for bold text.
  219. weight = 400
  220. ##
  221. # 1 = Font is outline style (Macintosh only)
  222. outline = 0
  223. ##
  224. # 1 = Font is shadow style (Macintosh only)
  225. shadow = 0
  226. # No methods ...
  227. def handle_efont(book, data): # BIFF2 only
  228. if not book.formatting_info:
  229. return
  230. book.font_list[-1].colour_index = unpack('<H', data)[0]
  231. def handle_font(book, data):
  232. if not book.formatting_info:
  233. return
  234. if not book.encoding:
  235. book.derive_encoding()
  236. blah = DEBUG or book.verbosity >= 2
  237. bv = book.biff_version
  238. k = len(book.font_list)
  239. if k == 4:
  240. f = Font()
  241. f.name = UNICODE_LITERAL('Dummy Font')
  242. f.font_index = k
  243. book.font_list.append(f)
  244. k += 1
  245. f = Font()
  246. f.font_index = k
  247. book.font_list.append(f)
  248. if bv >= 50:
  249. (
  250. f.height, option_flags, f.colour_index, f.weight,
  251. f.escapement, f.underline_type, f.family,
  252. f.character_set,
  253. ) = unpack('<HHHHHBBB', data[0:13])
  254. f.bold = option_flags & 1
  255. f.italic = (option_flags & 2) >> 1
  256. f.underlined = (option_flags & 4) >> 2
  257. f.struck_out = (option_flags & 8) >> 3
  258. f.outline = (option_flags & 16) >> 4
  259. f.shadow = (option_flags & 32) >> 5
  260. if bv >= 80:
  261. f.name = unpack_unicode(data, 14, lenlen=1)
  262. else:
  263. f.name = unpack_string(data, 14, book.encoding, lenlen=1)
  264. elif bv >= 30:
  265. f.height, option_flags, f.colour_index = unpack('<HHH', data[0:6])
  266. f.bold = option_flags & 1
  267. f.italic = (option_flags & 2) >> 1
  268. f.underlined = (option_flags & 4) >> 2
  269. f.struck_out = (option_flags & 8) >> 3
  270. f.outline = (option_flags & 16) >> 4
  271. f.shadow = (option_flags & 32) >> 5
  272. f.name = unpack_string(data, 6, book.encoding, lenlen=1)
  273. # Now cook up the remaining attributes ...
  274. f.weight = [400, 700][f.bold]
  275. f.escapement = 0 # None
  276. f.underline_type = f.underlined # None or Single
  277. f.family = 0 # Unknown / don't care
  278. f.character_set = 1 # System default (0 means "ANSI Latin")
  279. else: # BIFF2
  280. f.height, option_flags = unpack('<HH', data[0:4])
  281. f.colour_index = 0x7FFF # "system window text colour"
  282. f.bold = option_flags & 1
  283. f.italic = (option_flags & 2) >> 1
  284. f.underlined = (option_flags & 4) >> 2
  285. f.struck_out = (option_flags & 8) >> 3
  286. f.outline = 0
  287. f.shadow = 0
  288. f.name = unpack_string(data, 4, book.encoding, lenlen=1)
  289. # Now cook up the remaining attributes ...
  290. f.weight = [400, 700][f.bold]
  291. f.escapement = 0 # None
  292. f.underline_type = f.underlined # None or Single
  293. f.family = 0 # Unknown / don't care
  294. f.character_set = 1 # System default (0 means "ANSI Latin")
  295. if blah:
  296. f.dump(
  297. book.logfile,
  298. header="--- handle_font: font[%d] ---" % f.font_index,
  299. footer="-------------------",
  300. )
  301. # === "Number formats" ===
  302. ##
  303. # "Number format" information from a FORMAT record.
  304. # <br /> -- New in version 0.6.1
  305. class Format(BaseObject, EqNeAttrs):
  306. ##
  307. # The key into Book.format_map
  308. format_key = 0
  309. ##
  310. # A classification that has been inferred from the format string.
  311. # Currently, this is used only to distinguish between numbers and dates.
  312. # <br />Values:
  313. # <br />FUN = 0 # unknown
  314. # <br />FDT = 1 # date
  315. # <br />FNU = 2 # number
  316. # <br />FGE = 3 # general
  317. # <br />FTX = 4 # text
  318. type = FUN
  319. ##
  320. # The format string
  321. format_str = UNICODE_LITERAL('')
  322. def __init__(self, format_key, ty, format_str):
  323. self.format_key = format_key
  324. self.type = ty
  325. self.format_str = format_str
  326. std_format_strings = {
  327. # "std" == "standard for US English locale"
  328. # #### TODO ... a lot of work to tailor these to the user's locale.
  329. # See e.g. gnumeric-1.x.y/src/formats.c
  330. 0x00: "General",
  331. 0x01: "0",
  332. 0x02: "0.00",
  333. 0x03: "#,##0",
  334. 0x04: "#,##0.00",
  335. 0x05: "$#,##0_);($#,##0)",
  336. 0x06: "$#,##0_);[Red]($#,##0)",
  337. 0x07: "$#,##0.00_);($#,##0.00)",
  338. 0x08: "$#,##0.00_);[Red]($#,##0.00)",
  339. 0x09: "0%",
  340. 0x0a: "0.00%",
  341. 0x0b: "0.00E+00",
  342. 0x0c: "# ?/?",
  343. 0x0d: "# ??/??",
  344. 0x0e: "m/d/yy",
  345. 0x0f: "d-mmm-yy",
  346. 0x10: "d-mmm",
  347. 0x11: "mmm-yy",
  348. 0x12: "h:mm AM/PM",
  349. 0x13: "h:mm:ss AM/PM",
  350. 0x14: "h:mm",
  351. 0x15: "h:mm:ss",
  352. 0x16: "m/d/yy h:mm",
  353. 0x25: "#,##0_);(#,##0)",
  354. 0x26: "#,##0_);[Red](#,##0)",
  355. 0x27: "#,##0.00_);(#,##0.00)",
  356. 0x28: "#,##0.00_);[Red](#,##0.00)",
  357. 0x29: "_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)",
  358. 0x2a: "_($* #,##0_);_($* (#,##0);_($* \"-\"_);_(@_)",
  359. 0x2b: "_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)",
  360. 0x2c: "_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);_(@_)",
  361. 0x2d: "mm:ss",
  362. 0x2e: "[h]:mm:ss",
  363. 0x2f: "mm:ss.0",
  364. 0x30: "##0.0E+0",
  365. 0x31: "@",
  366. }
  367. fmt_code_ranges = [ # both-inclusive ranges of "standard" format codes
  368. # Source: the openoffice.org doc't
  369. # and the OOXML spec Part 4, section 3.8.30
  370. ( 0, 0, FGE),
  371. ( 1, 13, FNU),
  372. (14, 22, FDT),
  373. (27, 36, FDT), # CJK date formats
  374. (37, 44, FNU),
  375. (45, 47, FDT),
  376. (48, 48, FNU),
  377. (49, 49, FTX),
  378. # Gnumeric assumes (or assumed) that built-in formats finish at 49, not at 163
  379. (50, 58, FDT), # CJK date formats
  380. (59, 62, FNU), # Thai number (currency?) formats
  381. (67, 70, FNU), # Thai number (currency?) formats
  382. (71, 81, FDT), # Thai date formats
  383. ]
  384. std_format_code_types = {}
  385. for lo, hi, ty in fmt_code_ranges:
  386. for x in xrange(lo, hi+1):
  387. std_format_code_types[x] = ty
  388. del lo, hi, ty, x
  389. date_chars = UNICODE_LITERAL('ymdhs') # year, month/minute, day, hour, second
  390. date_char_dict = {}
  391. for _c in date_chars + date_chars.upper():
  392. date_char_dict[_c] = 5
  393. del _c, date_chars
  394. skip_char_dict = {}
  395. for _c in UNICODE_LITERAL('$-+/(): '):
  396. skip_char_dict[_c] = 1
  397. num_char_dict = {
  398. UNICODE_LITERAL('0'): 5,
  399. UNICODE_LITERAL('#'): 5,
  400. UNICODE_LITERAL('?'): 5,
  401. }
  402. non_date_formats = {
  403. UNICODE_LITERAL('0.00E+00'):1,
  404. UNICODE_LITERAL('##0.0E+0'):1,
  405. UNICODE_LITERAL('General') :1,
  406. UNICODE_LITERAL('GENERAL') :1, # OOo Calc 1.1.4 does this.
  407. UNICODE_LITERAL('general') :1, # pyExcelerator 0.6.3 does this.
  408. UNICODE_LITERAL('@') :1,
  409. }
  410. fmt_bracketed_sub = re.compile(r'\[[^]]*\]').sub
  411. # Boolean format strings (actual cases)
  412. # u'"Yes";"Yes";"No"'
  413. # u'"True";"True";"False"'
  414. # u'"On";"On";"Off"'
  415. def is_date_format_string(book, fmt):
  416. # Heuristics:
  417. # Ignore "text" and [stuff in square brackets (aarrgghh -- see below)].
  418. # Handle backslashed-escaped chars properly.
  419. # E.g. hh\hmm\mss\s should produce a display like 23h59m59s
  420. # Date formats have one or more of ymdhs (caseless) in them.
  421. # Numeric formats have # and 0.
  422. # N.B. u'General"."' hence get rid of "text" first.
  423. # TODO: Find where formats are interpreted in Gnumeric
  424. # TODO: u'[h]\\ \\h\\o\\u\\r\\s' ([h] means don't care about hours > 23)
  425. state = 0
  426. s = ''
  427. for c in fmt:
  428. if state == 0:
  429. if c == UNICODE_LITERAL('"'):
  430. state = 1
  431. elif c in UNICODE_LITERAL(r"\_*"):
  432. state = 2
  433. elif c in skip_char_dict:
  434. pass
  435. else:
  436. s += c
  437. elif state == 1:
  438. if c == UNICODE_LITERAL('"'):
  439. state = 0
  440. elif state == 2:
  441. # Ignore char after backslash, underscore or asterisk
  442. state = 0
  443. assert 0 <= state <= 2
  444. if book.verbosity >= 4:
  445. print("is_date_format_string: reduced format is %s" % REPR(s), file=book.logfile)
  446. s = fmt_bracketed_sub('', s)
  447. if s in non_date_formats:
  448. return False
  449. state = 0
  450. separator = ";"
  451. got_sep = 0
  452. date_count = num_count = 0
  453. for c in s:
  454. if c in date_char_dict:
  455. date_count += date_char_dict[c]
  456. elif c in num_char_dict:
  457. num_count += num_char_dict[c]
  458. elif c == separator:
  459. got_sep = 1
  460. # print num_count, date_count, repr(fmt)
  461. if date_count and not num_count:
  462. return True
  463. if num_count and not date_count:
  464. return False
  465. if date_count:
  466. if book.verbosity:
  467. fprintf(book.logfile,
  468. 'WARNING *** is_date_format: ambiguous d=%d n=%d fmt=%r\n',
  469. date_count, num_count, fmt)
  470. elif not got_sep:
  471. if book.verbosity:
  472. fprintf(book.logfile,
  473. "WARNING *** format %r produces constant result\n",
  474. fmt)
  475. return date_count > num_count
  476. def handle_format(self, data, rectype=XL_FORMAT):
  477. DEBUG = 0
  478. bv = self.biff_version
  479. if rectype == XL_FORMAT2:
  480. bv = min(bv, 30)
  481. if not self.encoding:
  482. self.derive_encoding()
  483. strpos = 2
  484. if bv >= 50:
  485. fmtkey = unpack('<H', data[0:2])[0]
  486. else:
  487. fmtkey = self.actualfmtcount
  488. if bv <= 30:
  489. strpos = 0
  490. self.actualfmtcount += 1
  491. if bv >= 80:
  492. unistrg = unpack_unicode(data, 2)
  493. else:
  494. unistrg = unpack_string(data, strpos, self.encoding, lenlen=1)
  495. blah = DEBUG or self.verbosity >= 3
  496. if blah:
  497. fprintf(self.logfile,
  498. "FORMAT: count=%d fmtkey=0x%04x (%d) s=%r\n",
  499. self.actualfmtcount, fmtkey, fmtkey, unistrg)
  500. is_date_s = self.is_date_format_string(unistrg)
  501. ty = [FGE, FDT][is_date_s]
  502. if not(fmtkey > 163 or bv < 50):
  503. # user_defined if fmtkey > 163
  504. # N.B. Gnumeric incorrectly starts these at 50 instead of 164 :-(
  505. # if earlier than BIFF 5, standard info is useless
  506. std_ty = std_format_code_types.get(fmtkey, FUN)
  507. # print "std ty", std_ty
  508. is_date_c = std_ty == FDT
  509. if self.verbosity and 0 < fmtkey < 50 and (is_date_c ^ is_date_s):
  510. DEBUG = 2
  511. fprintf(self.logfile,
  512. "WARNING *** Conflict between "
  513. "std format key %d and its format string %r\n",
  514. fmtkey, unistrg)
  515. if DEBUG == 2:
  516. fprintf(self.logfile,
  517. "ty: %d; is_date_c: %r; is_date_s: %r; fmt_strg: %r",
  518. ty, is_date_c, is_date_s, unistrg)
  519. fmtobj = Format(fmtkey, ty, unistrg)
  520. if blah:
  521. fmtobj.dump(self.logfile,
  522. header="--- handle_format [%d] ---" % (self.actualfmtcount-1, ))
  523. self.format_map[fmtkey] = fmtobj
  524. self.format_list.append(fmtobj)
  525. # =============================================================================
  526. def handle_palette(book, data):
  527. if not book.formatting_info:
  528. return
  529. blah = DEBUG or book.verbosity >= 2
  530. n_colours, = unpack('<H', data[:2])
  531. expected_n_colours = (16, 56)[book.biff_version >= 50]
  532. if ((DEBUG or book.verbosity >= 1)
  533. and n_colours != expected_n_colours):
  534. fprintf(book.logfile,
  535. "NOTE *** Expected %d colours in PALETTE record, found %d\n",
  536. expected_n_colours, n_colours)
  537. elif blah:
  538. fprintf(book.logfile,
  539. "PALETTE record with %d colours\n", n_colours)
  540. fmt = '<xx%di' % n_colours # use i to avoid long integers
  541. expected_size = 4 * n_colours + 2
  542. actual_size = len(data)
  543. tolerance = 4
  544. if not expected_size <= actual_size <= expected_size + tolerance:
  545. raise XLRDError('PALETTE record: expected size %d, actual size %d' % (expected_size, actual_size))
  546. colours = unpack(fmt, data[:expected_size])
  547. assert book.palette_record == [] # There should be only 1 PALETTE record
  548. # a colour will be 0xbbggrr
  549. # IOW, red is at the little end
  550. for i in xrange(n_colours):
  551. c = colours[i]
  552. red = c & 0xff
  553. green = (c >> 8) & 0xff
  554. blue = (c >> 16) & 0xff
  555. old_rgb = book.colour_map[8+i]
  556. new_rgb = (red, green, blue)
  557. book.palette_record.append(new_rgb)
  558. book.colour_map[8+i] = new_rgb
  559. if blah:
  560. if new_rgb != old_rgb:
  561. print("%2d: %r -> %r" % (i, old_rgb, new_rgb), file=book.logfile)
  562. def palette_epilogue(book):
  563. # Check colour indexes in fonts etc.
  564. # This must be done here as FONT records
  565. # come *before* the PALETTE record :-(
  566. for font in book.font_list:
  567. if font.font_index == 4: # the missing font record
  568. continue
  569. cx = font.colour_index
  570. if cx == 0x7fff: # system window text colour
  571. continue
  572. if cx in book.colour_map:
  573. book.colour_indexes_used[cx] = 1
  574. elif book.verbosity:
  575. print("Size of colour table:", len(book.colour_map), file=book.logfile)
  576. fprintf(book.logfile, "*** Font #%d (%r): colour index 0x%04x is unknown\n",
  577. font.font_index, font.name, cx)
  578. if book.verbosity >= 1:
  579. used = sorted(book.colour_indexes_used.keys())
  580. print("\nColour indexes used:\n%r\n" % used, file=book.logfile)
  581. def handle_style(book, data):
  582. if not book.formatting_info:
  583. return
  584. blah = DEBUG or book.verbosity >= 2
  585. bv = book.biff_version
  586. flag_and_xfx, built_in_id, level = unpack('<HBB', data[:4])
  587. xf_index = flag_and_xfx & 0x0fff
  588. if (data == b"\0\0\0\0"
  589. and "Normal" not in book.style_name_map):
  590. # Erroneous record (doesn't have built-in bit set).
  591. # Example file supplied by Jeff Bell.
  592. built_in = 1
  593. built_in_id = 0
  594. xf_index = 0
  595. name = "Normal"
  596. level = 255
  597. elif flag_and_xfx & 0x8000:
  598. # built-in style
  599. built_in = 1
  600. name = built_in_style_names[built_in_id]
  601. if 1 <= built_in_id <= 2:
  602. name += str(level + 1)
  603. else:
  604. # user-defined style
  605. built_in = 0
  606. built_in_id = 0
  607. level = 0
  608. if bv >= 80:
  609. try:
  610. name = unpack_unicode(data, 2, lenlen=2)
  611. except UnicodeDecodeError:
  612. print("STYLE: built_in=%d xf_index=%d built_in_id=%d level=%d" \
  613. % (built_in, xf_index, built_in_id, level), file=book.logfile)
  614. print("raw bytes:", repr(data[2:]), file=book.logfile)
  615. raise
  616. else:
  617. name = unpack_string(data, 2, book.encoding, lenlen=1)
  618. if blah and not name:
  619. print("WARNING *** A user-defined style has a zero-length name", file=book.logfile)
  620. book.style_name_map[name] = (built_in, xf_index)
  621. if blah:
  622. fprintf(book.logfile, "STYLE: built_in=%d xf_index=%d built_in_id=%d level=%d name=%r\n",
  623. built_in, xf_index, built_in_id, level, name)
  624. def check_colour_indexes_in_obj(book, obj, orig_index):
  625. alist = sorted(obj.__dict__.items())
  626. for attr, nobj in alist:
  627. if hasattr(nobj, 'dump'):
  628. check_colour_indexes_in_obj(book, nobj, orig_index)
  629. elif attr.find('colour_index') >= 0:
  630. if nobj in book.colour_map:
  631. book.colour_indexes_used[nobj] = 1
  632. continue
  633. oname = obj.__class__.__name__
  634. print("*** xf #%d : %s.%s = 0x%04x (unknown)" \
  635. % (orig_index, oname, attr, nobj), file=book.logfile)
  636. def fill_in_standard_formats(book):
  637. for x in std_format_code_types.keys():
  638. if x not in book.format_map:
  639. ty = std_format_code_types[x]
  640. # Note: many standard format codes (mostly CJK date formats) have
  641. # format strings that vary by locale; xlrd does not (yet)
  642. # handle those; the type (date or numeric) is recorded but the fmt_str will be None.
  643. fmt_str = std_format_strings.get(x)
  644. fmtobj = Format(x, ty, fmt_str)
  645. book.format_map[x] = fmtobj
  646. def handle_xf(self, data):
  647. ### self is a Book instance
  648. # DEBUG = 0
  649. blah = DEBUG or self.verbosity >= 3
  650. bv = self.biff_version
  651. xf = XF()
  652. xf.alignment = XFAlignment()
  653. xf.alignment.indent_level = 0
  654. xf.alignment.shrink_to_fit = 0
  655. xf.alignment.text_direction = 0
  656. xf.border = XFBorder()
  657. xf.border.diag_up = 0
  658. xf.border.diag_down = 0
  659. xf.border.diag_colour_index = 0
  660. xf.border.diag_line_style = 0 # no line
  661. xf.background = XFBackground()
  662. xf.protection = XFProtection()
  663. # fill in the known standard formats
  664. if bv >= 50 and not self.xfcount:
  665. # i.e. do this once before we process the first XF record
  666. fill_in_standard_formats(self)
  667. if bv >= 80:
  668. unpack_fmt = '<HHHBBBBIiH'
  669. (xf.font_index, xf.format_key, pkd_type_par,
  670. pkd_align1, xf.alignment.rotation, pkd_align2,
  671. pkd_used, pkd_brdbkg1, pkd_brdbkg2, pkd_brdbkg3,
  672. ) = unpack(unpack_fmt, data[0:20])
  673. upkbits(xf.protection, pkd_type_par, (
  674. (0, 0x01, 'cell_locked'),
  675. (1, 0x02, 'formula_hidden'),
  676. ))
  677. upkbits(xf, pkd_type_par, (
  678. (2, 0x0004, 'is_style'),
  679. # Following is not in OOo docs, but is mentioned
  680. # in Gnumeric source and also in (deep breath)
  681. # org.apache.poi.hssf.record.ExtendedFormatRecord.java
  682. (3, 0x0008, 'lotus_123_prefix'), # Meaning is not known.
  683. (4, 0xFFF0, 'parent_style_index'),
  684. ))
  685. upkbits(xf.alignment, pkd_align1, (
  686. (0, 0x07, 'hor_align'),
  687. (3, 0x08, 'text_wrapped'),
  688. (4, 0x70, 'vert_align'),
  689. ))
  690. upkbits(xf.alignment, pkd_align2, (
  691. (0, 0x0f, 'indent_level'),
  692. (4, 0x10, 'shrink_to_fit'),
  693. (6, 0xC0, 'text_direction'),
  694. ))
  695. reg = pkd_used >> 2
  696. for attr_stem in \
  697. "format font alignment border background protection".split():
  698. attr = "_" + attr_stem + "_flag"
  699. setattr(xf, attr, reg & 1)
  700. reg >>= 1
  701. upkbitsL(xf.border, pkd_brdbkg1, (
  702. (0, 0x0000000f, 'left_line_style'),
  703. (4, 0x000000f0, 'right_line_style'),
  704. (8, 0x00000f00, 'top_line_style'),
  705. (12, 0x0000f000, 'bottom_line_style'),
  706. (16, 0x007f0000, 'left_colour_index'),
  707. (23, 0x3f800000, 'right_colour_index'),
  708. (30, 0x40000000, 'diag_down'),
  709. (31, 0x80000000, 'diag_up'),
  710. ))
  711. upkbits(xf.border, pkd_brdbkg2, (
  712. (0, 0x0000007F, 'top_colour_index'),
  713. (7, 0x00003F80, 'bottom_colour_index'),
  714. (14, 0x001FC000, 'diag_colour_index'),
  715. (21, 0x01E00000, 'diag_line_style'),
  716. ))
  717. upkbitsL(xf.background, pkd_brdbkg2, (
  718. (26, 0xFC000000, 'fill_pattern'),
  719. ))
  720. upkbits(xf.background, pkd_brdbkg3, (
  721. (0, 0x007F, 'pattern_colour_index'),
  722. (7, 0x3F80, 'background_colour_index'),
  723. ))
  724. elif bv >= 50:
  725. unpack_fmt = '<HHHBBIi'
  726. (xf.font_index, xf.format_key, pkd_type_par,
  727. pkd_align1, pkd_orient_used,
  728. pkd_brdbkg1, pkd_brdbkg2,
  729. ) = unpack(unpack_fmt, data[0:16])
  730. upkbits(xf.protection, pkd_type_par, (
  731. (0, 0x01, 'cell_locked'),
  732. (1, 0x02, 'formula_hidden'),
  733. ))
  734. upkbits(xf, pkd_type_par, (
  735. (2, 0x0004, 'is_style'),
  736. (3, 0x0008, 'lotus_123_prefix'), # Meaning is not known.
  737. (4, 0xFFF0, 'parent_style_index'),
  738. ))
  739. upkbits(xf.alignment, pkd_align1, (
  740. (0, 0x07, 'hor_align'),
  741. (3, 0x08, 'text_wrapped'),
  742. (4, 0x70, 'vert_align'),
  743. ))
  744. orientation = pkd_orient_used & 0x03
  745. xf.alignment.rotation = [0, 255, 90, 180][orientation]
  746. reg = pkd_orient_used >> 2
  747. for attr_stem in \
  748. "format font alignment border background protection".split():
  749. attr = "_" + attr_stem + "_flag"
  750. setattr(xf, attr, reg & 1)
  751. reg >>= 1
  752. upkbitsL(xf.background, pkd_brdbkg1, (
  753. ( 0, 0x0000007F, 'pattern_colour_index'),
  754. ( 7, 0x00003F80, 'background_colour_index'),
  755. (16, 0x003F0000, 'fill_pattern'),
  756. ))
  757. upkbitsL(xf.border, pkd_brdbkg1, (
  758. (22, 0x01C00000, 'bottom_line_style'),
  759. (25, 0xFE000000, 'bottom_colour_index'),
  760. ))
  761. upkbits(xf.border, pkd_brdbkg2, (
  762. ( 0, 0x00000007, 'top_line_style'),
  763. ( 3, 0x00000038, 'left_line_style'),
  764. ( 6, 0x000001C0, 'right_line_style'),
  765. ( 9, 0x0000FE00, 'top_colour_index'),
  766. (16, 0x007F0000, 'left_colour_index'),
  767. (23, 0x3F800000, 'right_colour_index'),
  768. ))
  769. elif bv >= 40:
  770. unpack_fmt = '<BBHBBHI'
  771. (xf.font_index, xf.format_key, pkd_type_par,
  772. pkd_align_orient, pkd_used,
  773. pkd_bkg_34, pkd_brd_34,
  774. ) = unpack(unpack_fmt, data[0:12])
  775. upkbits(xf.protection, pkd_type_par, (
  776. (0, 0x01, 'cell_locked'),
  777. (1, 0x02, 'formula_hidden'),
  778. ))
  779. upkbits(xf, pkd_type_par, (
  780. (2, 0x0004, 'is_style'),
  781. (3, 0x0008, 'lotus_123_prefix'), # Meaning is not known.
  782. (4, 0xFFF0, 'parent_style_index'),
  783. ))
  784. upkbits(xf.alignment, pkd_align_orient, (
  785. (0, 0x07, 'hor_align'),
  786. (3, 0x08, 'text_wrapped'),
  787. (4, 0x30, 'vert_align'),
  788. ))
  789. orientation = (pkd_align_orient & 0xC0) >> 6
  790. xf.alignment.rotation = [0, 255, 90, 180][orientation]
  791. reg = pkd_used >> 2
  792. for attr_stem in \
  793. "format font alignment border background protection".split():
  794. attr = "_" + attr_stem + "_flag"
  795. setattr(xf, attr, reg & 1)
  796. reg >>= 1
  797. upkbits(xf.background, pkd_bkg_34, (
  798. ( 0, 0x003F, 'fill_pattern'),
  799. ( 6, 0x07C0, 'pattern_colour_index'),
  800. (11, 0xF800, 'background_colour_index'),
  801. ))
  802. upkbitsL(xf.border, pkd_brd_34, (
  803. ( 0, 0x00000007, 'top_line_style'),
  804. ( 3, 0x000000F8, 'top_colour_index'),
  805. ( 8, 0x00000700, 'left_line_style'),
  806. (11, 0x0000F800, 'left_colour_index'),
  807. (16, 0x00070000, 'bottom_line_style'),
  808. (19, 0x00F80000, 'bottom_colour_index'),
  809. (24, 0x07000000, 'right_line_style'),
  810. (27, 0xF8000000, 'right_colour_index'),
  811. ))
  812. elif bv == 30:
  813. unpack_fmt = '<BBBBHHI'
  814. (xf.font_index, xf.format_key, pkd_type_prot,
  815. pkd_used, pkd_align_par,
  816. pkd_bkg_34, pkd_brd_34,
  817. ) = unpack(unpack_fmt, data[0:12])
  818. upkbits(xf.protection, pkd_type_prot, (
  819. (0, 0x01, 'cell_locked'),
  820. (1, 0x02, 'formula_hidden'),
  821. ))
  822. upkbits(xf, pkd_type_prot, (
  823. (2, 0x0004, 'is_style'),
  824. (3, 0x0008, 'lotus_123_prefix'), # Meaning is not known.
  825. ))
  826. upkbits(xf.alignment, pkd_align_par, (
  827. (0, 0x07, 'hor_align'),
  828. (3, 0x08, 'text_wrapped'),
  829. ))
  830. upkbits(xf, pkd_align_par, (
  831. (4, 0xFFF0, 'parent_style_index'),
  832. ))
  833. reg = pkd_used >> 2
  834. for attr_stem in \
  835. "format font alignment border background protection".split():
  836. attr = "_" + attr_stem + "_flag"
  837. setattr(xf, attr, reg & 1)
  838. reg >>= 1
  839. upkbits(xf.background, pkd_bkg_34, (
  840. ( 0, 0x003F, 'fill_pattern'),
  841. ( 6, 0x07C0, 'pattern_colour_index'),
  842. (11, 0xF800, 'background_colour_index'),
  843. ))
  844. upkbitsL(xf.border, pkd_brd_34, (
  845. ( 0, 0x00000007, 'top_line_style'),
  846. ( 3, 0x000000F8, 'top_colour_index'),
  847. ( 8, 0x00000700, 'left_line_style'),
  848. (11, 0x0000F800, 'left_colour_index'),
  849. (16, 0x00070000, 'bottom_line_style'),
  850. (19, 0x00F80000, 'bottom_colour_index'),
  851. (24, 0x07000000, 'right_line_style'),
  852. (27, 0xF8000000, 'right_colour_index'),
  853. ))
  854. xf.alignment.vert_align = 2 # bottom
  855. xf.alignment.rotation = 0
  856. elif bv == 21:
  857. #### Warning: incomplete treatment; formatting_info not fully supported.
  858. #### Probably need to offset incoming BIFF2 XF[n] to BIFF8-like XF[n+16],
  859. #### and create XF[0:16] like the standard ones in BIFF8
  860. #### *AND* add 16 to all XF references in cell records :-(
  861. (xf.font_index, format_etc, halign_etc) = unpack('<BxBB', data)
  862. xf.format_key = format_etc & 0x3F
  863. upkbits(xf.protection, format_etc, (
  864. (6, 0x40, 'cell_locked'),
  865. (7, 0x80, 'formula_hidden'),
  866. ))
  867. upkbits(xf.alignment, halign_etc, (
  868. (0, 0x07, 'hor_align'),
  869. ))
  870. for mask, side in ((0x08, 'left'), (0x10, 'right'), (0x20, 'top'), (0x40, 'bottom')):
  871. if halign_etc & mask:
  872. colour_index, line_style = 8, 1 # black, thin
  873. else:
  874. colour_index, line_style = 0, 0 # none, none
  875. setattr(xf.border, side + '_colour_index', colour_index)
  876. setattr(xf.border, side + '_line_style', line_style)
  877. bg = xf.background
  878. if halign_etc & 0x80:
  879. bg.fill_pattern = 17
  880. else:
  881. bg.fill_pattern = 0
  882. bg.background_colour_index = 9 # white
  883. bg.pattern_colour_index = 8 # black
  884. xf.parent_style_index = 0 # ???????????
  885. xf.alignment.vert_align = 2 # bottom
  886. xf.alignment.rotation = 0
  887. for attr_stem in \
  888. "format font alignment border background protection".split():
  889. attr = "_" + attr_stem + "_flag"
  890. setattr(xf, attr, 1)
  891. else:
  892. raise XLRDError('programmer stuff-up: bv=%d' % bv)
  893. xf.xf_index = len(self.xf_list)
  894. self.xf_list.append(xf)
  895. self.xfcount += 1
  896. if blah:
  897. xf.dump(
  898. self.logfile,
  899. header="--- handle_xf: xf[%d] ---" % xf.xf_index,
  900. footer=" ",
  901. )
  902. try:
  903. fmt = self.format_map[xf.format_key]
  904. cellty = _cellty_from_fmtty[fmt.type]
  905. except KeyError:
  906. cellty = XL_CELL_NUMBER
  907. self._xf_index_to_xl_type_map[xf.xf_index] = cellty
  908. # Now for some assertions ...
  909. if self.formatting_info:
  910. if self.verbosity and xf.is_style and xf.parent_style_index != 0x0FFF:
  911. msg = "WARNING *** XF[%d] is a style XF but parent_style_index is 0x%04x, not 0x0fff\n"
  912. fprintf(self.logfile, msg, xf.xf_index, xf.parent_style_index)
  913. check_colour_indexes_in_obj(self, xf, xf.xf_index)
  914. if xf.format_key not in self.format_map:
  915. msg = "WARNING *** XF[%d] unknown (raw) format key (%d, 0x%04x)\n"
  916. if self.verbosity:
  917. fprintf(self.logfile, msg,
  918. xf.xf_index, xf.format_key, xf.format_key)
  919. xf.format_key = 0
  920. def xf_epilogue(self):
  921. # self is a Book instance.
  922. self._xf_epilogue_done = 1
  923. num_xfs = len(self.xf_list)
  924. blah = DEBUG or self.verbosity >= 3
  925. blah1 = DEBUG or self.verbosity >= 1
  926. if blah:
  927. fprintf(self.logfile, "xf_epilogue called ...\n")
  928. def check_same(book_arg, xf_arg, parent_arg, attr):
  929. # the _arg caper is to avoid a Warning msg from Python 2.1 :-(
  930. if getattr(xf_arg, attr) != getattr(parent_arg, attr):
  931. fprintf(book_arg.logfile,
  932. "NOTE !!! XF[%d] parent[%d] %s different\n",
  933. xf_arg.xf_index, parent_arg.xf_index, attr)
  934. for xfx in xrange(num_xfs):
  935. xf = self.xf_list[xfx]
  936. try:
  937. fmt = self.format_map[xf.format_key]
  938. cellty = _cellty_from_fmtty[fmt.type]
  939. except KeyError:
  940. cellty = XL_CELL_TEXT
  941. self._xf_index_to_xl_type_map[xf.xf_index] = cellty
  942. # Now for some assertions etc
  943. if not self.formatting_info:
  944. continue
  945. if xf.is_style:
  946. continue
  947. if not(0 <= xf.parent_style_index < num_xfs):
  948. if blah1:
  949. fprintf(self.logfile,
  950. "WARNING *** XF[%d]: is_style=%d but parent_style_index=%d\n",
  951. xf.xf_index, xf.is_style, xf.parent_style_index)
  952. # make it conform
  953. xf.parent_style_index = 0
  954. if self.biff_version >= 30:
  955. if blah1:
  956. if xf.parent_style_index == xf.xf_index:
  957. fprintf(self.logfile,
  958. "NOTE !!! XF[%d]: parent_style_index is also %d\n",
  959. xf.xf_index, xf.parent_style_index)
  960. elif not self.xf_list[xf.parent_style_index].is_style:
  961. fprintf(self.logfile,
  962. "NOTE !!! XF[%d]: parent_style_index is %d; style flag not set\n",
  963. xf.xf_index, xf.parent_style_index)
  964. if blah1 and xf.parent_style_index > xf.xf_index:
  965. fprintf(self.logfile,
  966. "NOTE !!! XF[%d]: parent_style_index is %d; out of order?\n",
  967. xf.xf_index, xf.parent_style_index)
  968. parent = self.xf_list[xf.parent_style_index]
  969. if not xf._alignment_flag and not parent._alignment_flag:
  970. if blah1: check_same(self, xf, parent, 'alignment')
  971. if not xf._background_flag and not parent._background_flag:
  972. if blah1: check_same(self, xf, parent, 'background')
  973. if not xf._border_flag and not parent._border_flag:
  974. if blah1: check_same(self, xf, parent, 'border')
  975. if not xf._protection_flag and not parent._protection_flag:
  976. if blah1: check_same(self, xf, parent, 'protection')
  977. if not xf._format_flag and not parent._format_flag:
  978. if blah1 and xf.format_key != parent.format_key:
  979. fprintf(self.logfile,
  980. "NOTE !!! XF[%d] fmtk=%d, parent[%d] fmtk=%r\n%r / %r\n",
  981. xf.xf_index, xf.format_key, parent.xf_index, parent.format_key,
  982. self.format_map[xf.format_key].format_str,
  983. self.format_map[parent.format_key].format_str)
  984. if not xf._font_flag and not parent._font_flag:
  985. if blah1 and xf.font_index != parent.font_index:
  986. fprintf(self.logfile,
  987. "NOTE !!! XF[%d] fontx=%d, parent[%d] fontx=%r\n",
  988. xf.xf_index, xf.font_index, parent.xf_index, parent.font_index)
  989. def initialise_book(book):
  990. initialise_colour_map(book)
  991. book._xf_epilogue_done = 0
  992. methods = (
  993. handle_font,
  994. handle_efont,
  995. handle_format,
  996. is_date_format_string,
  997. handle_palette,
  998. palette_epilogue,
  999. handle_style,
  1000. handle_xf,
  1001. xf_epilogue,
  1002. )
  1003. for method in methods:
  1004. setattr(book.__class__, method.__name__, method)
  1005. ##
  1006. # <p>A collection of the border-related attributes of an XF record.
  1007. # Items correspond to those in the Excel UI's Format/Cells/Border tab.</p>
  1008. # <p> An explanations of "colour index" is given in the Formatting
  1009. # section at the start of this document.
  1010. # There are five line style attributes; possible values and the
  1011. # associated meanings are:
  1012. # 0&nbsp;=&nbsp;No line,
  1013. # 1&nbsp;=&nbsp;Thin,
  1014. # 2&nbsp;=&nbsp;Medium,
  1015. # 3&nbsp;=&nbsp;Dashed,
  1016. # 4&nbsp;=&nbsp;Dotted,
  1017. # 5&nbsp;=&nbsp;Thick,
  1018. # 6&nbsp;=&nbsp;Double,
  1019. # 7&nbsp;=&nbsp;Hair,
  1020. # 8&nbsp;=&nbsp;Medium dashed,
  1021. # 9&nbsp;=&nbsp;Thin dash-dotted,
  1022. # 10&nbsp;=&nbsp;Medium dash-dotted,
  1023. # 11&nbsp;=&nbsp;Thin dash-dot-dotted,
  1024. # 12&nbsp;=&nbsp;Medium dash-dot-dotted,
  1025. # 13&nbsp;=&nbsp;Slanted medium dash-dotted.
  1026. # The line styles 8 to 13 appear in BIFF8 files (Excel 97 and later) only.
  1027. # For pictures of the line styles, refer to OOo docs s3.10 (p22)
  1028. # "Line Styles for Cell Borders (BIFF3-BIFF8)".</p>
  1029. # <br /> -- New in version 0.6.1
  1030. class XFBorder(BaseObject, EqNeAttrs):
  1031. ##
  1032. # The colour index for the cell's top line
  1033. top_colour_index = 0
  1034. ##
  1035. # The colour index for the cell's bottom line
  1036. bottom_colour_index = 0
  1037. ##
  1038. # The colour index for the cell's left line
  1039. left_colour_index = 0
  1040. ##
  1041. # The colour index for the cell's right line
  1042. right_colour_index = 0
  1043. ##
  1044. # The colour index for the cell's diagonal lines, if any
  1045. diag_colour_index = 0
  1046. ##
  1047. # The line style for the cell's top line
  1048. top_line_style = 0
  1049. ##
  1050. # The line style for the cell's bottom line
  1051. bottom_line_style = 0
  1052. ##
  1053. # The line style for the cell's left line
  1054. left_line_style = 0
  1055. ##
  1056. # The line style for the cell's right line
  1057. right_line_style = 0
  1058. ##
  1059. # The line style for the cell's diagonal lines, if any
  1060. diag_line_style = 0
  1061. ##
  1062. # 1 = draw a diagonal from top left to bottom right
  1063. diag_down = 0
  1064. ##
  1065. # 1 = draw a diagonal from bottom left to top right
  1066. diag_up = 0
  1067. ##
  1068. # A collection of the background-related attributes of an XF record.
  1069. # Items correspond to those in the Excel UI's Format/Cells/Patterns tab.
  1070. # An explanation of "colour index" is given in the Formatting
  1071. # section at the start of this document.
  1072. # <br /> -- New in version 0.6.1
  1073. class XFBackground(BaseObject, EqNeAttrs):
  1074. ##
  1075. # See section 3.11 of the OOo docs.
  1076. fill_pattern = 0
  1077. ##
  1078. # See section 3.11 of the OOo docs.
  1079. background_colour_index = 0
  1080. ##
  1081. # See section 3.11 of the OOo docs.
  1082. pattern_colour_index = 0
  1083. ##
  1084. # A collection of the alignment and similar attributes of an XF record.
  1085. # Items correspond to those in the Excel UI's Format/Cells/Alignment tab.
  1086. # <br /> -- New in version 0.6.1
  1087. class XFAlignment(BaseObject, EqNeAttrs):
  1088. ##
  1089. # Values: section 6.115 (p 214) of OOo docs
  1090. hor_align = 0
  1091. ##
  1092. # Values: section 6.115 (p 215) of OOo docs
  1093. vert_align = 0
  1094. ##
  1095. # Values: section 6.115 (p 215) of OOo docs.<br />
  1096. # Note: file versions BIFF7 and earlier use the documented
  1097. # "orientation" attribute; this will be mapped (without loss)
  1098. # into "rotation".
  1099. rotation = 0
  1100. ##
  1101. # 1 = text is wrapped at right margin
  1102. text_wrapped = 0
  1103. ##
  1104. # A number in range(15).
  1105. indent_level = 0
  1106. ##
  1107. # 1 = shrink font size to fit text into cell.
  1108. shrink_to_fit = 0
  1109. ##
  1110. # 0 = according to context; 1 = left-to-right; 2 = right-to-left
  1111. text_direction = 0
  1112. ##
  1113. # A collection of the protection-related attributes of an XF record.
  1114. # Items correspond to those in the Excel UI's Format/Cells/Protection tab.
  1115. # Note the OOo docs include the "cell or style" bit
  1116. # in this bundle of attributes.
  1117. # This is incorrect; the bit is used in determining which bundles to use.
  1118. # <br /> -- New in version 0.6.1
  1119. class XFProtection(BaseObject, EqNeAttrs):
  1120. ##
  1121. # 1 = Cell is prevented from being changed, moved, resized, or deleted
  1122. # (only if the sheet is protected).
  1123. cell_locked = 0
  1124. ##
  1125. # 1 = Hide formula so that it doesn't appear in the formula bar when
  1126. # the cell is selected (only if the sheet is protected).
  1127. formula_hidden = 0
  1128. ##
  1129. # eXtended Formatting information for cells, rows, columns and styles.
  1130. # <br /> -- New in version 0.6.1
  1131. #
  1132. # <p>Each of the 6 flags below describes the validity of
  1133. # a specific group of attributes.
  1134. # <br />
  1135. # In cell XFs, flag==0 means the attributes of the parent style XF are used,
  1136. # (but only if the attributes are valid there); flag==1 means the attributes
  1137. # of this XF are used.<br />
  1138. # In style XFs, flag==0 means the attribute setting is valid; flag==1 means
  1139. # the attribute should be ignored.<br />
  1140. # Note that the API
  1141. # provides both "raw" XFs and "computed" XFs -- in the latter case, cell XFs
  1142. # have had the above inheritance mechanism applied.
  1143. # </p>
  1144. class XF(BaseObject):
  1145. ##
  1146. # 0 = cell XF, 1 = style XF
  1147. is_style = 0
  1148. ##
  1149. # cell XF: Index into Book.xf_list
  1150. # of this XF's style XF<br />
  1151. # style XF: 0xFFF
  1152. parent_style_index = 0
  1153. ##
  1154. #
  1155. _format_flag = 0
  1156. ##
  1157. #
  1158. _font_flag = 0
  1159. ##
  1160. #
  1161. _alignment_flag = 0
  1162. ##
  1163. #
  1164. _border_flag = 0
  1165. ##
  1166. #
  1167. _background_flag = 0
  1168. ##
  1169. # &nbsp;
  1170. _protection_flag = 0
  1171. ##
  1172. # Index into Book.xf_list
  1173. xf_index = 0
  1174. ##
  1175. # Index into Book.font_list
  1176. font_index = 0
  1177. ##
  1178. # Key into Book.format_map
  1179. # <p>
  1180. # Warning: OOo docs on the XF record call this "Index to FORMAT record".
  1181. # It is not an index in the Python sense. It is a key to a map.
  1182. # It is true <i>only</i> for Excel 4.0 and earlier files
  1183. # that the key into format_map from an XF instance
  1184. # is the same as the index into format_list, and <i>only</i>
  1185. # if the index is less than 164.
  1186. # </p>
  1187. format_key = 0
  1188. ##
  1189. # An instance of an XFProtection object.
  1190. protection = None
  1191. ##
  1192. # An instance of an XFBackground object.
  1193. background = None
  1194. ##
  1195. # An instance of an XFAlignment object.
  1196. alignment = None
  1197. ##
  1198. # An instance of an XFBorder object.
  1199. border = None