123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741 |
- from __future__ import print_function
- # -*- coding: windows-1252 -*-
- from . import Formatting
- from .BIFFRecords import NumberFormatRecord, XFRecord, StyleRecord
- from .compat import basestring, xrange
- FIRST_USER_DEFINED_NUM_FORMAT_IDX = 164
- class XFStyle(object):
- def __init__(self):
- self.num_format_str = 'General'
- self.font = Formatting.Font()
- self.alignment = Formatting.Alignment()
- self.borders = Formatting.Borders()
- self.pattern = Formatting.Pattern()
- self.protection = Formatting.Protection()
- default_style = XFStyle()
- class StyleCollection(object):
- _std_num_fmt_list = [
- 'general',
- '0',
- '0.00',
- '#,##0',
- '#,##0.00',
- '"$"#,##0_);("$"#,##0)',
- '"$"#,##0_);[Red]("$"#,##0)',
- '"$"#,##0.00_);("$"#,##0.00)',
- '"$"#,##0.00_);[Red]("$"#,##0.00)',
- '0%',
- '0.00%',
- '0.00E+00',
- '# ?/?',
- '# ??/??',
- 'M/D/YY',
- 'D-MMM-YY',
- 'D-MMM',
- 'MMM-YY',
- 'h:mm AM/PM',
- 'h:mm:ss AM/PM',
- 'h:mm',
- 'h:mm:ss',
- 'M/D/YY h:mm',
- '_(#,##0_);(#,##0)',
- '_(#,##0_);[Red](#,##0)',
- '_(#,##0.00_);(#,##0.00)',
- '_(#,##0.00_);[Red](#,##0.00)',
- '_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)',
- '_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)',
- '_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)',
- '_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)',
- 'mm:ss',
- '[h]:mm:ss',
- 'mm:ss.0',
- '##0.0E+0',
- '@'
- ]
- def __init__(self, style_compression=0):
- self.style_compression = style_compression
- self.stats = [0, 0, 0, 0, 0, 0]
- self._font_id2x = {}
- self._font_x2id = {}
- self._font_val2x = {}
- for x in (0, 1, 2, 3, 5): # The font with index 4 is omitted in all BIFF versions
- font = Formatting.Font()
- search_key = font._search_key()
- self._font_id2x[font] = x
- self._font_x2id[x] = font
- self._font_val2x[search_key] = x
- self._xf_id2x = {}
- self._xf_x2id = {}
- self._xf_val2x = {}
- self._num_formats = {}
- for fmtidx, fmtstr in zip(range(0, 23), StyleCollection._std_num_fmt_list[0:23]):
- self._num_formats[fmtstr] = fmtidx
- for fmtidx, fmtstr in zip(range(37, 50), StyleCollection._std_num_fmt_list[23:]):
- self._num_formats[fmtstr] = fmtidx
- self.default_style = XFStyle()
- self._default_xf = self._add_style(self.default_style)[0]
- def add(self, style):
- if style == None:
- return 0x10
- return self._add_style(style)[1]
- def _add_style(self, style):
- num_format_str = style.num_format_str
- if num_format_str in self._num_formats:
- num_format_idx = self._num_formats[num_format_str]
- else:
- num_format_idx = (
- FIRST_USER_DEFINED_NUM_FORMAT_IDX
- + len(self._num_formats)
- - len(StyleCollection._std_num_fmt_list)
- )
- self._num_formats[num_format_str] = num_format_idx
- font = style.font
- if font in self._font_id2x:
- font_idx = self._font_id2x[font]
- self.stats[0] += 1
- elif self.style_compression:
- search_key = font._search_key()
- font_idx = self._font_val2x.get(search_key)
- if font_idx is not None:
- self._font_id2x[font] = font_idx
- self.stats[1] += 1
- else:
- font_idx = len(self._font_x2id) + 1 # Why plus 1? Font 4 is missing
- self._font_id2x[font] = font_idx
- self._font_val2x[search_key] = font_idx
- self._font_x2id[font_idx] = font
- self.stats[2] += 1
- else:
- font_idx = len(self._font_id2x) + 1
- self._font_id2x[font] = font_idx
- self.stats[2] += 1
- gof = (style.alignment, style.borders, style.pattern, style.protection)
- xf = (font_idx, num_format_idx) + gof
- if xf in self._xf_id2x:
- xf_index = self._xf_id2x[xf]
- self.stats[3] += 1
- elif self.style_compression == 2:
- xf_key = (font_idx, num_format_idx) + tuple(obj._search_key() for obj in gof)
- xf_index = self._xf_val2x.get(xf_key)
- if xf_index is not None:
- self._xf_id2x[xf] = xf_index
- self.stats[4] += 1
- else:
- xf_index = 0x10 + len(self._xf_x2id)
- self._xf_id2x[xf] = xf_index
- self._xf_val2x[xf_key] = xf_index
- self._xf_x2id[xf_index] = xf
- self.stats[5] += 1
- else:
- xf_index = 0x10 + len(self._xf_id2x)
- self._xf_id2x[xf] = xf_index
- self.stats[5] += 1
- if xf_index >= 0xFFF:
- # 12 bits allowed, 0xFFF is a sentinel value
- raise ValueError("More than 4094 XFs (styles)")
- return xf, xf_index
-
- def add_font(self, font):
- return self._add_font(font)
-
- def _add_font(self, font):
- if font in self._font_id2x:
- font_idx = self._font_id2x[font]
- self.stats[0] += 1
- elif self.style_compression:
- search_key = font._search_key()
- font_idx = self._font_val2x.get(search_key)
- if font_idx is not None:
- self._font_id2x[font] = font_idx
- self.stats[1] += 1
- else:
- font_idx = len(self._font_x2id) + 1 # Why plus 1? Font 4 is missing
- self._font_id2x[font] = font_idx
- self._font_val2x[search_key] = font_idx
- self._font_x2id[font_idx] = font
- self.stats[2] += 1
- else:
- font_idx = len(self._font_id2x) + 1
- self._font_id2x[font] = font_idx
- self.stats[2] += 1
-
- return font_idx
- def get_biff_data(self):
- result = b''
- result += self._all_fonts()
- result += self._all_num_formats()
- result += self._all_cell_styles()
- result += self._all_styles()
- return result
- def _all_fonts(self):
- result = b''
- if self.style_compression:
- fonts = self._font_x2id.items()
- else:
- fonts = [(x, o) for o, x in self._font_id2x.items()]
- for font_idx, font in sorted(fonts):
- result += font.get_biff_record().get()
- return result
- def _all_num_formats(self):
- result = b''
- alist = [
- (v, k)
- for k, v in self._num_formats.items()
- if v >= FIRST_USER_DEFINED_NUM_FORMAT_IDX
- ]
- alist.sort()
- for fmtidx, fmtstr in alist:
- result += NumberFormatRecord(fmtidx, fmtstr).get()
- return result
- def _all_cell_styles(self):
- result = b''
- for i in range(0, 16):
- result += XFRecord(self._default_xf, 'style').get()
- if self.style_compression == 2:
- styles = self._xf_x2id.items()
- else:
- styles = [(x, o) for o, x in self._xf_id2x.items()]
- for xf_idx, xf in sorted(styles):
- result += XFRecord(xf).get()
- return result
- def _all_styles(self):
- return StyleRecord().get()
- # easyxf and its supporting objects ###################################
- class EasyXFException(Exception):
- pass
- class EasyXFCallerError(EasyXFException):
- pass
- class EasyXFAuthorError(EasyXFException):
- pass
- class IntULim(object):
- # If astring represents a valid unsigned integer ('123', '0xabcd', etc)
- # and it is <= limit, return the int value; otherwise return None.
- def __init__(self, limit):
- self.limit = limit
- def __call__(self, astring):
- try:
- value = int(astring, 0)
- except ValueError:
- return None
- if not 0 <= value <= self.limit:
- return None
- return value
- bool_map = {
- # Text values for all Boolean attributes
- '1': 1, 'yes': 1, 'true': 1, 'on': 1,
- '0': 0, 'no': 0, 'false': 0, 'off': 0,
- }
- border_line_map = {
- # Text values for these borders attributes:
- # left, right, top, bottom and diag
- 'no_line': 0x00,
- 'thin': 0x01,
- 'medium': 0x02,
- 'dashed': 0x03,
- 'dotted': 0x04,
- 'thick': 0x05,
- 'double': 0x06,
- 'hair': 0x07,
- 'medium_dashed': 0x08,
- 'thin_dash_dotted': 0x09,
- 'medium_dash_dotted': 0x0a,
- 'thin_dash_dot_dotted': 0x0b,
- 'medium_dash_dot_dotted': 0x0c,
- 'slanted_medium_dash_dotted': 0x0d,
- }
- charset_map = {
- # Text values for font.charset
- 'ansi_latin': 0x00,
- 'sys_default': 0x01,
- 'symbol': 0x02,
- 'apple_roman': 0x4d,
- 'ansi_jap_shift_jis': 0x80,
- 'ansi_kor_hangul': 0x81,
- 'ansi_kor_johab': 0x82,
- 'ansi_chinese_gbk': 0x86,
- 'ansi_chinese_big5': 0x88,
- 'ansi_greek': 0xa1,
- 'ansi_turkish': 0xa2,
- 'ansi_vietnamese': 0xa3,
- 'ansi_hebrew': 0xb1,
- 'ansi_arabic': 0xb2,
- 'ansi_baltic': 0xba,
- 'ansi_cyrillic': 0xcc,
- 'ansi_thai': 0xde,
- 'ansi_latin_ii': 0xee,
- 'oem_latin_i': 0xff,
- }
- # Text values for colour indices. "grey" is a synonym of "gray".
- # The names are those given by Microsoft Excel 2003 to the colours
- # in the default palette. There is no great correspondence with
- # any W3C name-to-RGB mapping.
- _colour_map_text = """\
- aqua 0x31
- black 0x08
- blue 0x0C
- blue_gray 0x36
- bright_green 0x0B
- brown 0x3C
- coral 0x1D
- cyan_ega 0x0F
- dark_blue 0x12
- dark_blue_ega 0x12
- dark_green 0x3A
- dark_green_ega 0x11
- dark_purple 0x1C
- dark_red 0x10
- dark_red_ega 0x10
- dark_teal 0x38
- dark_yellow 0x13
- gold 0x33
- gray_ega 0x17
- gray25 0x16
- gray40 0x37
- gray50 0x17
- gray80 0x3F
- green 0x11
- ice_blue 0x1F
- indigo 0x3E
- ivory 0x1A
- lavender 0x2E
- light_blue 0x30
- light_green 0x2A
- light_orange 0x34
- light_turquoise 0x29
- light_yellow 0x2B
- lime 0x32
- magenta_ega 0x0E
- ocean_blue 0x1E
- olive_ega 0x13
- olive_green 0x3B
- orange 0x35
- pale_blue 0x2C
- periwinkle 0x18
- pink 0x0E
- plum 0x3D
- purple_ega 0x14
- red 0x0A
- rose 0x2D
- sea_green 0x39
- silver_ega 0x16
- sky_blue 0x28
- tan 0x2F
- teal 0x15
- teal_ega 0x15
- turquoise 0x0F
- violet 0x14
- white 0x09
- yellow 0x0D"""
- colour_map = {}
- for _line in _colour_map_text.splitlines():
- _name, _num = _line.split()
- _num = int(_num, 0)
- colour_map[_name] = _num
- if 'gray' in _name:
- colour_map[_name.replace('gray', 'grey')] = _num
- del _colour_map_text, _line, _name, _num
- def add_palette_colour(colour_str, colour_index):
- if not (8 <= colour_index <= 63):
- raise Exception("add_palette_colour: colour_index (%d) not in range(8, 64)" %
- (colour_index))
- colour_map[colour_str] = colour_index
- # user-defined palette defines 56 RGB colors from entry 8 - 64
- #excel_default_palette_b8 = [ # (red, green, blue)
- # ( 0, 0, 0), (255,255,255), (255, 0, 0), ( 0,255, 0),
- # ( 0, 0,255), (255,255, 0), (255, 0,255), ( 0,255,255),
- # (128, 0, 0), ( 0,128, 0), ( 0, 0,128), (128,128, 0),
- # (128, 0,128), ( 0,128,128), (192,192,192), (128,128,128),
- # (153,153,255), (153, 51,102), (255,255,204), (204,255,255),
- # (102, 0,102), (255,128,128), ( 0,102,204), (204,204,255),
- # ( 0, 0,128), (255, 0,255), (255,255, 0), ( 0,255,255),
- # (128, 0,128), (128, 0, 0), ( 0,128,128), ( 0, 0,255),
- # ( 0,204,255), (204,255,255), (204,255,204), (255,255,153),
- # (153,204,255), (255,153,204), (204,153,255), (255,204,153),
- # ( 51,102,255), ( 51,204,204), (153,204, 0), (255,204, 0),
- # (255,153, 0), (255,102, 0), (102,102,153), (150,150,150),
- # ( 0, 51,102), ( 51,153,102), ( 0, 51, 0), ( 51, 51, 0),
- # (153, 51, 0), (153, 51,102), ( 51, 51,153), ( 51, 51, 51),
- # ]
- # Default colour table for BIFF8 copied from
- # OpenOffice.org's Documentation of the Microsoft Excel File Format, Excel Version 2003
- # Note palette has LSB padded with 2 bytes 0x00
- excel_default_palette_b8 = (
- 0x00000000,
- 0xFFFFFF00,
- 0xFF000000,
- 0x00FF0000,
- 0x0000FF00,
- 0xFFFF0000,
- 0xFF00FF00,
- 0x00FFFF00,
- 0x80000000,
- 0x00800000,
- 0x00008000,
- 0x80800000,
- 0x80008000,
- 0x00808000,
- 0xC0C0C000,
- 0x80808000,
- 0x9999FF00,
- 0x99336600,
- 0xFFFFCC00,
- 0xCCFFFF00,
- 0x66006600,
- 0xFF808000,
- 0x0066CC00,
- 0xCCCCFF00,
- 0x00008000,
- 0xFF00FF00,
- 0xFFFF0000,
- 0x00FFFF00,
- 0x80008000,
- 0x80000000,
- 0x00808000,
- 0x0000FF00,
- 0x00CCFF00,
- 0xCCFFFF00,
- 0xCCFFCC00,
- 0xFFFF9900,
- 0x99CCFF00,
- 0xFF99CC00,
- 0xCC99FF00,
- 0xFFCC9900,
- 0x3366FF00,
- 0x33CCCC00,
- 0x99CC0000,
- 0xFFCC0000,
- 0xFF990000,
- 0xFF660000,
- 0x66669900,
- 0x96969600,
- 0x00336600,
- 0x33996600,
- 0x00330000,
- 0x33330000,
- 0x99330000,
- 0x99336600,
- 0x33339900,
- 0x33333300)
- assert len(excel_default_palette_b8) == 56
- pattern_map = {
- # Text values for pattern.pattern
- # xlwt/doc/pattern_examples.xls showcases all of these patterns.
- 'no_fill': 0,
- 'none': 0,
- 'solid': 1,
- 'solid_fill': 1,
- 'solid_pattern': 1,
- 'fine_dots': 2,
- 'alt_bars': 3,
- 'sparse_dots': 4,
- 'thick_horz_bands': 5,
- 'thick_vert_bands': 6,
- 'thick_backward_diag': 7,
- 'thick_forward_diag': 8,
- 'big_spots': 9,
- 'bricks': 10,
- 'thin_horz_bands': 11,
- 'thin_vert_bands': 12,
- 'thin_backward_diag': 13,
- 'thin_forward_diag': 14,
- 'squares': 15,
- 'diamonds': 16,
- }
- def any_str_func(s):
- return s.strip()
- def colour_index_func(s, maxval=0x7F):
- try:
- value = int(s, 0)
- except ValueError:
- return None
- if not (0 <= value <= maxval):
- return None
- return value
- colour_index_func_7 = colour_index_func
- def colour_index_func_15(s):
- return colour_index_func(s, maxval=0x7FFF)
- def rotation_func(s):
- try:
- value = int(s, 0)
- except ValueError:
- return None
- if not (-90 <= value <= 90):
- raise EasyXFCallerError("rotation %d: should be -90 to +90 degrees" % value)
- if value < 0:
- value = 90 - value # encode as 91 to 180 (clockwise)
- return value
- xf_dict = {
- 'align': 'alignment', # synonym
- 'alignment': {
- 'dire': {
- 'general': 0,
- 'lr': 1,
- 'rl': 2,
- },
- 'direction': 'dire',
- 'horiz': 'horz',
- 'horizontal': 'horz',
- 'horz': {
- 'general': 0,
- 'left': 1,
- 'center': 2,
- 'centre': 2, # "align: horiz centre" means xf.alignment.horz is set to 2
- 'right': 3,
- 'filled': 4,
- 'justified': 5,
- 'center_across_selection': 6,
- 'centre_across_selection': 6,
- 'distributed': 7,
- },
- 'inde': IntULim(15), # restriction: 0 <= value <= 15
- 'indent': 'inde',
- 'rota': [{'stacked': 255, 'none': 0, }, rotation_func],
- 'rotation': 'rota',
- 'shri': bool_map,
- 'shrink': 'shri',
- 'shrink_to_fit': 'shri',
- 'vert': {
- 'top': 0,
- 'center': 1,
- 'centre': 1,
- 'bottom': 2,
- 'justified': 3,
- 'distributed': 4,
- },
- 'vertical': 'vert',
- 'wrap': bool_map,
- },
- 'border': 'borders',
- 'borders': {
- 'left': [border_line_map, IntULim(0x0d)],
- 'right': [border_line_map, IntULim(0x0d)],
- 'top': [border_line_map, IntULim(0x0d)],
- 'bottom': [border_line_map, IntULim(0x0d)],
- 'diag': [border_line_map, IntULim(0x0d)],
- 'top_colour': [colour_map, colour_index_func_7],
- 'bottom_colour': [colour_map, colour_index_func_7],
- 'left_colour': [colour_map, colour_index_func_7],
- 'right_colour': [colour_map, colour_index_func_7],
- 'diag_colour': [colour_map, colour_index_func_7],
- 'top_color': 'top_colour',
- 'bottom_color': 'bottom_colour',
- 'left_color': 'left_colour',
- 'right_color': 'right_colour',
- 'diag_color': 'diag_colour',
- 'need_diag1': bool_map,
- 'need_diag2': bool_map,
- },
- 'font': {
- 'bold': bool_map,
- 'charset': charset_map,
- 'color': 'colour_index',
- 'color_index': 'colour_index',
- 'colour': 'colour_index',
- 'colour_index': [colour_map, colour_index_func_15],
- 'escapement': {'none': 0, 'superscript': 1, 'subscript': 2},
- 'family': {'none': 0, 'roman': 1, 'swiss': 2, 'modern': 3, 'script': 4, 'decorative': 5, },
- 'height': IntULim(0xFFFF), # practical limits are much narrower e.g. 160 to 1440 (8pt to 72pt)
- 'italic': bool_map,
- 'name': any_str_func,
- 'outline': bool_map,
- 'shadow': bool_map,
- 'struck_out': bool_map,
- 'underline': [bool_map, {'none': 0, 'single': 1, 'single_acc': 0x21, 'double': 2, 'double_acc': 0x22, }],
- },
- 'pattern': {
- 'back_color': 'pattern_back_colour',
- 'back_colour': 'pattern_back_colour',
- 'fore_color': 'pattern_fore_colour',
- 'fore_colour': 'pattern_fore_colour',
- 'pattern': [pattern_map, IntULim(16)],
- 'pattern_back_color': 'pattern_back_colour',
- 'pattern_back_colour': [colour_map, colour_index_func_7],
- 'pattern_fore_color': 'pattern_fore_colour',
- 'pattern_fore_colour': [colour_map, colour_index_func_7],
- },
- 'protection': {
- 'cell_locked' : bool_map,
- 'formula_hidden': bool_map,
- },
- }
- def _esplit(s, split_char, esc_char="\\"):
- escaped = False
- olist = ['']
- for c in s:
- if escaped:
- olist[-1] += c
- escaped = False
- elif c == esc_char:
- escaped = True
- elif c == split_char:
- olist.append('')
- else:
- olist[-1] += c
- return olist
- def _parse_strg_to_obj(strg, obj, parse_dict,
- field_sep=",", line_sep=";", intro_sep=":", esc_char="\\", debug=False):
- for line in _esplit(strg, line_sep, esc_char):
- line = line.strip()
- if not line:
- break
- split_line = _esplit(line, intro_sep, esc_char)
- if len(split_line) != 2:
- raise EasyXFCallerError('line %r should have exactly 1 "%c"' % (line, intro_sep))
- section, item_str = split_line
- section = section.strip().lower()
- for counter in range(2):
- result = parse_dict.get(section)
- if result is None:
- raise EasyXFCallerError('section %r is unknown' % section)
- if isinstance(result, dict):
- break
- if not isinstance(result, str):
- raise EasyXFAuthorError(
- 'section %r should map to dict or str object; found %r' % (section, type(result)))
- # synonym
- old_section = section
- section = result
- else:
- raise EasyXFAuthorError('Attempt to define synonym of synonym (%r: %r)' % (old_section, result))
- section_dict = result
- section_obj = getattr(obj, section, None)
- if section_obj is None:
- raise EasyXFAuthorError('instance of %s class has no attribute named %s' % (obj.__class__.__name__, section))
- for kv_str in _esplit(item_str, field_sep, esc_char):
- guff = kv_str.split()
- if not guff:
- continue
- k = guff[0].lower().replace('-', '_')
- v = ' '.join(guff[1:])
- if not v:
- raise EasyXFCallerError("no value supplied for %s.%s" % (section, k))
- for counter in xrange(2):
- result = section_dict.get(k)
- if result is None:
- raise EasyXFCallerError('%s.%s is not a known attribute' % (section, k))
- if not isinstance(result, basestring):
- break
- # synonym
- old_k = k
- k = result
- else:
- raise EasyXFAuthorError('Attempt to define synonym of synonym (%r: %r)' % (old_k, result))
- value_info = result
- if not isinstance(value_info, list):
- value_info = [value_info]
- for value_rule in value_info:
- if isinstance(value_rule, dict):
- # dict maps strings to integer field values
- vl = v.lower().replace('-', '_')
- if vl in value_rule:
- value = value_rule[vl]
- break
- elif callable(value_rule):
- value = value_rule(v)
- if value is not None:
- break
- else:
- raise EasyXFAuthorError("unknown value rule for attribute %r: %r" % (k, value_rule))
- else:
- raise EasyXFCallerError("unexpected value %r for %s.%s" % (v, section, k))
- try:
- orig = getattr(section_obj, k)
- except AttributeError:
- raise EasyXFAuthorError('%s.%s in dictionary but not in supplied object' % (section, k))
- if debug: print("+++ %s.%s = %r # %s; was %r" % (section, k, value, v, orig))
- setattr(section_obj, k, value)
- def easyxf(strg_to_parse="", num_format_str=None,
- field_sep=",", line_sep=";", intro_sep=":", esc_char="\\", debug=False):
- """
- This function is used to create and configure
- :class:`XFStyle` objects for use with (for example) the
- :meth:`Worksheet.write` method.
- It takes a string to be parsed to obtain attribute values for
- :class:`Alignment`, :class:`Borders`, :class:`Font`, :class:`Pattern` and
- :class:`Protection` objects.
- Refer to the examples in the file `examples/xlwt_easyxf_simple_demo.py`
- and to the `xf_dict` dictionary in :mod:`xlwt.Style`.
- Various synonyms including color/colour, center/centre and gray/grey are
- allowed. Case is irrelevant (except maybe in font names). ``-`` may be used
- instead of ``_``.
- Example: ``font: bold on; align: wrap on, vert centre, horiz center``
- :param num_format_str:
- To get the "number format string" of an existing
- cell whose format you want to reproduce, select the cell and click on
- Format/Cells/Number/Custom. Otherwise, refer to Excel help.
- Examples: ``"#,##0.00"``, ``"dd/mm/yyyy"``
- :return: An :class:`XFstyle` object.
- """
- xfobj = XFStyle()
- if num_format_str is not None:
- xfobj.num_format_str = num_format_str
- if strg_to_parse:
- _parse_strg_to_obj(strg_to_parse, xfobj, xf_dict,
- field_sep=field_sep, line_sep=line_sep, intro_sep=intro_sep, esc_char=esc_char, debug=debug)
- return xfobj
- def easyfont(strg_to_parse="", field_sep=",", esc_char="\\", debug=False):
- xfobj = XFStyle()
- if strg_to_parse:
- _parse_strg_to_obj("font: " + strg_to_parse, xfobj, xf_dict,
- field_sep=field_sep, line_sep=";", intro_sep=":", esc_char=esc_char, debug=debug)
- return xfobj.font
|