Source code for pyExcelerator.Formatting

#!/usr/bin/env python
# -*- coding: windows-1251 -*-

#  Copyright (C) 2005 Roman V. Kiseliov
#  All rights reserved.
# 
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions
#  are met:
# 
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in
#     the documentation and/or other materials provided with the
#     distribution.
# 
#  3. All advertising materials mentioning features or use of this
#     software must display the following acknowledgment:
#     "This product includes software developed by
#      Roman V. Kiseliov <roman@kiseliov.ru>."
# 
#  4. Redistributions of any form whatsoever must retain the following
#     acknowledgment:
#     "This product includes software developed by
#      Roman V. Kiseliov <roman@kiseliov.ru>."
# 
#  THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
#  EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL Roman V. Kiseliov OR
#  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
#  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
#  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
#  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
#  OF THE POSSIBILITY OF SUCH DAMAGE.



'''
The  XF  record is able to store explicit cell formatting attributes or the
attributes  of  a cell style. Explicit formatting includes the reference to
a  cell  style  XF  record. This allows to extend a defined cell style with
some  explicit  attributes.  The  formatting  attributes  are  divided into
6 groups:

Group           Attributes
-------------------------------------
Number format   Number format index (index to FORMAT record)
Font            Font index (index to FONT record)
Alignment       Horizontal and vertical alignment, text wrap, indentation, 
                orientation/rotation, text direction
Border          Border line styles and colours
Background      Background area style and colours
Protection      Cell locked, formula hidden

For  each  group  a flag in the cell XF record specifies whether to use the
attributes  contained  in  that  XF  record  or  in  the  referenced  style
XF  record. In style XF records, these flags specify whether the attributes
will  overwrite  explicit  cell  formatting  when  the  style is applied to
a  cell. Changing a cell style (without applying this style to a cell) will
change  all  cells which already use that style and do not contain explicit
cell  attributes for the changed style attributes. If a cell XF record does
not  contain  explicit  attributes  in a group (if the attribute group flag
is not set), it repeats the attributes of its style XF record.

'''

__rev_id__ = """$Id: Formatting.py,v 1.4 2005/07/20 07:24:11 rvk Exp $"""


import BIFFRecords

colours = {
        'aqua'    : 0x0F,
        'cyan'    : 0x0F,
        'black'   : 0x08,
        'blue'    : 0x0C,
        'brown'   : 0x10,
        'magenta' : 0x0E,
        'fuchsia' : 0x0E,
        'gray'    : 0x17,
        'grey'    : 0x17,
        'green'   : 0x11,
        'lime'    : 0x0B,
        'navy'    : 0x12,
        'orange'  : 0x35,
        'pink'    : 0x21,
        'purple'  : 0x14,
        'red'     : 0x0A,
        'silver'  : 0x16,
        'white'   : 0x09,
        'yellow'  : 0x0D,
}

[docs]def get_colour_val(c): if c in colours: return colours[c] return c
[docs]class CopyableObject(object): # make sure to override this in the derived class if # copying needs to be more complex
[docs] def copy(self): cobj = self.__class__() cobj.__dict__.update(self.__dict__) return cobj
[docs]class Font(CopyableObject): ESCAPEMENT_NONE = 0x00 ESCAPEMENT_SUPERSCRIPT = 0x01 ESCAPEMENT_SUBSCRIPT = 0x02 UNDERLINE_NONE = 0x00 UNDERLINE_SINGLE = 0x01 UNDERLINE_SINGLE_ACC = 0x21 UNDERLINE_DOUBLE = 0x02 UNDERLINE_DOUBLE_ACC = 0x22 FAMILY_NONE = 0x00 FAMILY_ROMAN = 0x01 FAMILY_SWISS = 0x02 FAMILY_MODERN = 0x03 FAMILY_SCRIPT = 0x04 FAMILY_DECORARTIVE = 0x05 CHARSET_ANSI_LATIN = 0x00 CHARSET_SYS_DEFAULT = 0x01 CHARSET_SYMBOL = 0x02 CHARSET_APPLE_ROMAN = 0x4D CHARSET_ANSI_JAP_SHIFT_JIS = 0x80 CHARSET_ANSI_KOR_HANGUL = 0x81 CHARSET_ANSI_KOR_JOHAB = 0x82 CHARSET_ANSI_CHINESE_GBK = 0x86 CHARSET_ANSI_CHINESE_BIG5 = 0x88 CHARSET_ANSI_GREEK = 0xA1 CHARSET_ANSI_TURKISH = 0xA2 CHARSET_ANSI_VIETNAMESE = 0xA3 CHARSET_ANSI_HEBREW = 0xB1 CHARSET_ANSI_ARABIC = 0xB2 CHARSET_ANSI_BALTIC = 0xBA CHARSET_ANSI_CYRILLIC = 0xCC CHARSET_ANSI_THAI = 0xDE CHARSET_ANSI_LATIN_II = 0xEE CHARSET_OEM_LATIN_I = 0xFF def __init__(self): # twip = 1/20 of a point = 1/1440 of a inch # usually resolution == 96 pixels per 1 inch # (rarely 120 pixels per 1 inch or another one) self.height = 0x00C8 # 200: this is font with height 10 points self.italic = False self.struck_out = False self.outline = False self.shadow = False self.colour_index = 0x7FFF self.bold = False self._weight = 0x0190 # 0x02BC gives bold font self.escapement = self.ESCAPEMENT_NONE self.underline = self.UNDERLINE_NONE self.family = self.FAMILY_NONE self.charset = self.CHARSET_ANSI_CYRILLIC self.name = 'Arial'
[docs] def get_biff_record(self): height = self.height options = 0x00 if self.bold: options |= 0x01 self._weight = 0x02BC if self.italic: options |= 0x02 if self.underline != self.UNDERLINE_NONE: options |= 0x04 if self.struck_out: options |= 0x08 if self.outline: options |= 0x010 if self.shadow: options |= 0x020 colour_index = get_colour_val(self.colour_index) weight = self._weight escapement = self.escapement underline = self.underline family = self.family charset = self.charset name = self.name return BIFFRecords.FontRecord(height, options, colour_index, weight, escapement, underline, family, charset, name)
[docs]class Alignment(CopyableObject): HORZ_GENERAL = 0x00 HORZ_LEFT = 0x01 HORZ_CENTER = 0x02 HORZ_RIGHT = 0x03 HORZ_FILLED = 0x04 HORZ_JUSTIFIED = 0x05 # BIFF4-BIFF8X HORZ_CENTER_ACROSS_SEL = 0x06 # Centred across selection (BIFF4-BIFF8X) HORZ_DISTRIBUTED = 0x07 # Distributed (BIFF8X) VERT_TOP = 0x00 VERT_CENTER = 0x01 VERT_BOTTOM = 0x02 VERT_JUSTIFIED = 0x03 # Justified (BIFF5-BIFF8X) VERT_DISIRIBUTED = 0x04 # Distributed (BIFF8X) DIRECTION_GENERAL = 0x00 # BIFF8X DIRECTION_LR = 0x01 DIRECTION_RL = 0x02 ORIENTATION_NOT_ROTATED = 0x00 ORIENTATION_STACKED = 0x01 ORIENTATION_90_CC = 0x02 ORIENTATION_90_CW = 0x03 ROTATION_0_ANGLE = 0x00 ROTATION_STACKED = 0xFF WRAP_AT_RIGHT = 0x01 NOT_WRAP_AT_RIGHT = 0x00 SHRINK_TO_FIT = 0x01 NOT_SHRINK_TO_FIT = 0x00 def __init__(self): self.horz = self.HORZ_GENERAL self.vert = self.VERT_BOTTOM self.dire = self.DIRECTION_GENERAL self.orie = self.ORIENTATION_NOT_ROTATED self.rota = self.ROTATION_0_ANGLE self.wrap = self.NOT_WRAP_AT_RIGHT self.shri = self.NOT_SHRINK_TO_FIT self.inde = 0 self.merg = 0
[docs]class Borders(CopyableObject): NO_LINE = 0x00 THIN = 0x01 MEDIUM = 0x02 DASHED = 0x03 DOTTED = 0x04 THICK = 0x05 DOUBLE = 0x06 HAIR = 0x07 #The following for BIFF8 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 NEED_DIAG1 = 0x01 NEED_DIAG2 = 0x01 NO_NEED_DIAG1 = 0x00 NO_NEED_DIAG2 = 0x00 def __init__(self): self.left = self.NO_LINE self.right = self.NO_LINE self.top = self.NO_LINE self.bottom = self.NO_LINE self.diag = self.NO_LINE self.left_colour = 0x40 self.right_colour = 0x40 self.top_colour = 0x40 self.bottom_colour = 0x40 self.diag_colour = 0x40 self.need_diag1 = self.NO_NEED_DIAG1 self.need_diag2 = self.NO_NEED_DIAG2
[docs]class Pattern(CopyableObject): # patterns 0x00 - 0x12 NO_PATTERN = 0x00 SOLID_PATTERN = 0x01 def __init__(self): self.pattern = self.NO_PATTERN self._pattern_fore_colour = 0x40 self._pattern_back_colour = 0x41
[docs] def get_pattern_fore_colour(self): return self._pattern_fore_colour
[docs] def set_pattern_fore_colour(self, c): self._pattern_fore_colour = get_colour_val(c)
pattern_fore_colour = property(get_pattern_fore_colour, set_pattern_fore_colour)
[docs] def get_pattern_back_colour(self): return self._pattern_back_colour
[docs] def set_pattern_back_colour(self, c): self._pattern_back_colour = get_colour_val(c)
pattern_back_colour = property(get_pattern_back_colour, set_pattern_back_colour)
[docs]class Protection(CopyableObject): def __init__(self): self.cell_locked = 1 self.formula_hidden = 0
if __name__ == '__main__': font0 = Font() font0.name = 'Arial' font1 = Font() font1.name = 'Arial Cyr' font2 = Font() font2.name = 'Times New Roman' font3 = Font() font3.name = 'Courier New Cyr' for font, filename in [(font0, 'font0.bin'), (font1, 'font1.bin'), (font2, 'font2.bin'), (font3, 'font3.bin')]: f = file(filename, 'wb') f.write(font.get_biff_record().get_data()) f.close