Пример #1
0
def test_format_comparisions(NumberFormat):
    format1 = NumberFormat('m/d/yyyy')
    format2 = NumberFormat('m/d/yyyy')
    format3 = NumberFormat('mm/dd/yyyy')
    assert format1 == format2
    assert format1 == 'm/d/yyyy' and format1 != 'mm/dd/yyyy'
    assert format3 != 'm/d/yyyy' and format3 == 'mm/dd/yyyy'
    assert format1 != format3
Пример #2
0
def test_is_not_date_color_format():

    wb = Workbook()
    ws = Worksheet(wb)
    cell = Cell(ws, 'A', 1)

    cell.value = -13.5
    cell.style = cell.style.copy(number_format=NumberFormat('0.00_);[Red]\(0.00\)'))

    assert cell.is_date() is False
Пример #3
0
    def parse_cell_xfs(self):
        """Read styles from the shared style table"""
        cell_xfs = self.root.find('{%s}cellXfs' % SHEET_MAIN_NS)
        styles_list = self.style_prop['list']

        if cell_xfs is None:  # can happen on bad OOXML writers (e.g. Gnumeric)
            return

        builtin_formats = NumberFormat._BUILTIN_FORMATS
        cell_xfs_nodes = safe_iterator(cell_xfs, '{%s}xf' % SHEET_MAIN_NS)
        for index, cell_xfs_node in enumerate(cell_xfs_nodes):
            _style = {}

            number_format_id = int(cell_xfs_node.get('numFmtId'))
            if number_format_id < 164:
                format_code = builtin_formats.get(number_format_id, 'General')
            else:
                fmt_code = self.custom_num_formats.get(number_format_id)
                if fmt_code is not None:
                    format_code = fmt_code
                else:
                    raise MissingNumberFormat('%s' % number_format_id)
            _style['number_format'] = NumberFormat(format_code=format_code)

            if bool(cell_xfs_node.get('applyAlignment')):
                alignment = {}
                al = cell_xfs_node.find('{%s}alignment' % SHEET_MAIN_NS)
                if al is not None:
                    alignment = al.attrib
                _style['alignment'] = Alignment(**alignment)

            if bool(cell_xfs_node.get('applyFont')):
                _style['font'] = self.font_list[int(
                    cell_xfs_node.get('fontId'))].copy()

            if bool(cell_xfs_node.get('applyFill')):
                _style['fill'] = self.fill_list[int(
                    cell_xfs_node.get('fillId'))].copy()

            if bool(cell_xfs_node.get('applyBorder')):
                _style['border'] = self.border_list[int(
                    cell_xfs_node.get('borderId'))].copy()

            if bool(cell_xfs_node.get('applyProtection')):
                protection = {}
                prot = cell_xfs_node.find('{%s}protection' % SHEET_MAIN_NS)
                if prot is not None:
                    protection.update(prot.attrib)
                _style['protection'] = Protection(**protection)

            self.style_prop['table'][index] = styles_list.add(Style(**_style))
Пример #4
0
 def setup_class(cls):
     now = datetime.datetime.now()
     cls.workbook = Workbook(guess_types=True)
     cls.worksheet = cls.workbook.create_sheet()
     cls.worksheet.cell(coordinate='A1').value = '12.34%'  # 2
     cls.worksheet.cell(coordinate='B4').value = now  # 3
     cls.worksheet.cell(coordinate='B5').value = now
     cls.worksheet.cell(coordinate='C14').value = 'This is a test'  # 1
     cls.worksheet.cell(coordinate='D9').value = '31.31415'  # 3
     st = Style(number_format=NumberFormat(NumberFormat.FORMAT_NUMBER_00),
                protection=Protection(locked=True))  # 4
     cls.worksheet.cell(coordinate='D9').style = st
     st2 = Style(protection=Protection(hidden=True))  # 5
     cls.worksheet.cell(coordinate='E1').style = st2
     cls.writer = StyleWriter(cls.workbook)
Пример #5
0
def test_write_number_formats():
    wb = DummyWorkbook()
    from openpyxl.xml.functions import Element
    from openpyxl.styles import NumberFormat, Style
    wb.shared_styles = [Style(), Style(number_format=NumberFormat('YYYY'))]
    writer = StyleWriter(wb)
    writer._write_number_format(writer._root, 0, "YYYY")
    xml = get_xml(writer._root)
    expected = """
    <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
           <numFmt formatCode="YYYY" numFmtId="0"></numFmt>
    </styleSheet>
    """
    diff = compare_xml(xml, expected)
    assert diff is None, diff
Пример #6
0
 def _convert_to_number_format(cls, number_format_dict):
     """
     Convert ``number_format_dict`` to an openpyxl v2.1.0 number format
     initializer.
     Parameters
     ----------
     number_format_dict : dict
         A dict with zero or more of the following keys.
             'format_code' : str
     Returns
     -------
     number_format : str
     """
     try:
         # >= 2.0.0 < 2.1.0
         from openpyxl.styles import NumberFormat
         return NumberFormat(**number_format_dict)
     except:
         # >= 2.1.0
         return number_format_dict['format_code']
Пример #7
0
 def number_format(self, format_code):
     """Set a new formatting code for numeric values"""
     self.style = self.style.copy(number_format=NumberFormat(
         format_code=format_code))
Пример #8
0
def test_builtin_format(NumberFormat):
    fmt = NumberFormat(format_code='0.00')
    assert fmt.builtin_format_code(2) == fmt.format_code
Пример #9
0
EXCEL_NUMBER_FORMAT = '0.00'

TITLE_STYLE = Style(font=Font(size=24, bold=True))
HEADER_STYLE = Style(
    font=Font(bold=True),
    fill=PatternFill(
        fill_type=fills.FILL_SOLID,
        start_color=Color(rgb=Color.header)
    )
)
BOLD_CELL = Style(
    font=Font(bold=True)
)
NUMBER_CELL = Style(
    number_format=NumberFormat(format_code=EXCEL_NUMBER_FORMAT)
)
FOOTER_CELL = Style(
    font=Font(bold=True),
    fill=PatternFill(
        fill_type=fills.FILL_SOLID,
        start_color=Color(rgb=Color.footer)
    ),
    number_format=NumberFormat(format_code=EXCEL_NUMBER_FORMAT)
)
LARGE_FOOTER_CELL = Style(
    font=Font(bold=True, size=16),
    fill=PatternFill(
        fill_type=fills.FILL_SOLID,
        start_color=Color(rgb=Color.footer)
    ),
Пример #10
0
def test_change_existing_styles(datadir):
    wb = load_workbook("complex-styles.xlsx")
    ws = wb.get_active_sheet()

    ws.column_dimensions['A'].width = 20
    i_style = ws.get_style('I')
    ws.set_style('I', i_style.copy(fill=PatternFill(fill_type='solid',
                                             start_color=Color('FF442200')),
                                   font=Font(color=Color('FF002244'))))
    ws.cell('A2').style = ws.cell('A2').style.copy(font=Font(name='Times New Roman',
                                                             size=12,
                                                             bold=True,
                                                             italic=True))
    ws.cell('A3').style = ws.cell('A3').style.copy(font=Font(name='Times New Roman',
                                                             size=14,
                                                             bold=False,
                                                             italic=True))
    ws.cell('A4').style = ws.cell('A4').style.copy(font=Font(name='Times New Roman',
                                                             size=16,
                                                             bold=True,
                                                             italic=False))
    ws.cell('A5').style = ws.cell('A5').style.copy(font=Font(color=Color('FF66FF66')))
    ws.cell('A6').style = ws.cell('A6').style.copy(font=Font(color=Color(theme='1')))
    ws.cell('A7').style = ws.cell('A7').style.copy(fill=PatternFill(fill_type='solid',
                                                             start_color=Color('FF330066')))
    ws.cell('A8').style = ws.cell('A8').style.copy(fill=PatternFill(fill_type='solid',
                                                             start_color=Color(theme='2')))
    ws.cell('A9').style = ws.cell('A9').style.copy(alignment=Alignment(horizontal='center'))
    ws.cell('A10').style = ws.cell('A10').style.copy(alignment=Alignment(horizontal='left'))
    ws.cell('A11').style = ws.cell('A11').style.copy(alignment=Alignment(horizontal='right'))
    ws.cell('A12').style = ws.cell('A12').style.copy(alignment=Alignment(vertical='bottom'))
    ws.cell('A13').style = ws.cell('A13').style.copy(alignment=Alignment(vertical='top'))
    ws.cell('A14').style = ws.cell('A14').style.copy(alignment=Alignment(vertical='center'))
    ws.cell('A15').style = ws.cell('A15').style.copy(number_format=NumberFormat('0.00%'))
    ws.cell('A16').style = ws.cell('A16').style.copy(number_format=NumberFormat('0.00'))
    ws.cell('A17').style = ws.cell('A17').style.copy(number_format=NumberFormat('mm-dd-yy'))
    ws.unmerge_cells('A18:B18')
    ws.cell('A19').style = ws.cell('A19').style.copy(border=Border(top=Side(border_style=borders.BORDER_THIN,
                                                                                color=Color('FF006600')),
                                                                     bottom=Side(border_style=borders.BORDER_THIN,
                                                                                   color=Color('FF006600')),
                                                                     left=Side(border_style=borders.BORDER_THIN,
                                                                                 color=Color('FF006600')),
                                                                     right=Side(border_style=borders.BORDER_THIN,
                                                                                  color=Color('FF006600'))))
    ws.cell('A21').style = ws.cell('A21').style.copy(border=Border(top=Side(border_style=borders.BORDER_THIN,
                                                                                color=Color(theme=7)),
                                                                     bottom=Side(border_style=borders.BORDER_THIN,
                                                                                   color=Color(theme=7)),
                                                                     left=Side(border_style=borders.BORDER_THIN,
                                                                                 color=Color(theme=7)),
                                                                     right=Side(border_style=borders.BORDER_THIN,
                                                                                  color=Color(theme=7))))
    ws.cell('A23').style = ws.cell('A23').style.copy(border=Border(top=Side(border_style=borders.BORDER_THIN,
                                                                                color=Color(theme=6))),
                                                     fill=PatternFill(fill_type='solid',
                                                               start_color=Color('FFCCCCFF')))
    ws.unmerge_cells('A23:B24')
    ws.cell('A25').style = ws.cell('A25').style.copy(alignment=Alignment(wrap_text=False))
    ws.cell('A26').style = ws.cell('A26').style.copy(alignment=Alignment(shrink_to_fit=False))

    saved_wb = save_virtual_workbook(wb)
    new_wb = load_workbook(BytesIO(saved_wb))
    ws = new_wb.get_active_sheet()

    assert ws.column_dimensions['A'].width == 20.0

    style = partial(ws.get_style)

    assert ws.get_style('I').fill.start_color.value == 'FF442200'
    assert ws.get_style('I').font.color.value == 'FF002244'
    assert style('A2').font.name == 'Times New Roman'
    assert style('A2').font.size == 12
    assert style('A2').font.bold
    assert style('A2').font.italic
    assert style('A3').font.name == 'Times New Roman'
    assert style('A3').font.size == 14
    assert not style('A3').font.bold
    assert style('A3').font.italic
    assert style('A4').font.name == 'Times New Roman'
    assert style('A4').font.size == 16
    assert style('A4').font.bold
    assert not style('A4').font.italic
    assert style('A5').font.color.value == 'FF66FF66'
    assert style('A6').font.color.value == 1
    assert style('A7').fill.start_color.value == 'FF330066'
    assert style('A8').fill.start_color.value == 2
    assert style('A9').alignment.horizontal == 'center'
    assert style('A10').alignment.horizontal == 'left'
    assert style('A11').alignment.horizontal == 'right'
    assert style('A12').alignment.vertical == 'bottom'
    assert style('A13').alignment.vertical == 'top'
    assert style('A14').alignment.vertical == 'center'
    assert style('A15').number_format == '0.00%'
    assert style('A16').number_format == '0.00'
    assert style('A17').number_format == 'mm-dd-yy'
    assert 'A18:B18' not in ws._merged_cells
    assert not ws.cell('B18').merged
    assert style('A19').border.top.color.value == 'FF006600'
    assert style('A19').border.bottom.color.value == 'FF006600'
    assert style('A19').border.left.color.value == 'FF006600'
    assert style('A19').border.right.color.value == 'FF006600'
    assert style('A21').border.top.color.value == 7
    assert style('A21').border.bottom.color.value == 7
    assert style('A21').border.left.color.value == 7
    assert style('A21').border.right.color.value == 7
    assert style('A23').fill.start_color.value == 'FFCCCCFF'
    assert style('A23').border.top.color.value == 6
    assert 'A23:B24' not in ws._merged_cells
    assert not ws.cell('A24').merged
    assert not ws.cell('B23').merged
    assert not ws.cell('B24').merged
    assert not style('A25').alignment.wrap_text
    assert not style('A26').alignment.shrink_to_fit

    # Verify that previously duplicate styles remain the same
    assert ws.column_dimensions['C'].width == 31.1640625
    assert style('C2').font.name == 'Arial'
    assert style('C2').font.size == 10
    assert not style('C2').font.bold
    assert not style('C2').font.italic
    assert style('C3').font.name == 'Arial'
    assert style('C3').font.size == 12
    assert style('C3').font.bold
    assert not style('C3').font.italic
    assert style('C4').font.name == 'Arial'
    assert style('C4').font.size == 14
    assert not style('C4').font.bold
    assert style('C4').font.italic
    assert style('C5').font.color.value == 'FF3300FF'
    assert style('C6').font.color.value == 9
    assert style('C7').fill.start_color.value == 'FFFFFF66'
    assert style('C8').fill.start_color.value == 8
    assert style('C9').alignment.horizontal == 'left'
    assert style('C10').alignment.horizontal == 'right'
    assert style('C11').alignment.horizontal == 'center'
    assert style('C12').alignment.vertical == 'top'
    assert style('C13').alignment.vertical == 'center'
    assert style('C14').alignment.vertical == 'bottom'
    assert style('C15').number_format == '0.00'
    assert style('C16').number_format == 'mm-dd-yy'
    assert style('C17').number_format == '0.00%'
    assert 'C18:D18' in ws._merged_cells
    assert ws.cell('D18').merged
    assert style('C19').border.top.color.value == 'FF006600'
    assert style('C19').border.bottom.color.value == 'FF006600'
    assert style('C19').border.left.color.value == 'FF006600'
    assert style('C19').border.right.color.value == 'FF006600'
    assert style('C21').border.top.color.value == 7
    assert style('C21').border.bottom.color.value == 7
    assert style('C21').border.left.color.value == 7
    assert style('C21').border.right.color.value == 7
    assert style('C23').fill.start_color.value == 'FFCCCCFF'
    assert style('C23').border.top.color.value == 6
    assert 'C23:D24' in ws._merged_cells
    assert ws.cell('C24').merged
    assert ws.cell('D23').merged
    assert ws.cell('D24').merged
    assert style('C25').alignment.wrap_text
    assert style('C26').alignment.shrink_to_fit
Пример #11
0
    def parse_cell_xfs(self):
        """Read styles from the shared style table"""
        cell_xfs = self.root.find('{%s}cellXfs' % SHEET_MAIN_NS)
        styles_list = self.style_prop['list']

        if cell_xfs is None:  # can happen on bad OOXML writers (e.g. Gnumeric)
            return

        builtin_formats = NumberFormat._BUILTIN_FORMATS
        cell_xfs_nodes = safe_iterator(cell_xfs, '{%s}xf' % SHEET_MAIN_NS)
        for index, cell_xfs_node in enumerate(cell_xfs_nodes):
            _style = {}

            number_format_id = int(cell_xfs_node.get('numFmtId'))
            if number_format_id < 164:
                format_code = builtin_formats.get(number_format_id, 'General')
            else:
                fmt_code = self.custom_num_formats.get(number_format_id)
                if fmt_code is not None:
                    format_code = fmt_code
                else:
                    raise MissingNumberFormat('%s' % number_format_id)
            _style['number_format'] = NumberFormat(format_code=format_code)

            if bool(cell_xfs_node.get('applyAlignment')):
                alignment = {}
                al = cell_xfs_node.find('{%s}alignment' % SHEET_MAIN_NS)
                if al is not None:
                    for key in ('horizontal', 'vertical', 'indent'):
                        _value = al.get(key)
                        if _value is not None:
                            alignment[key] = _value
                    alignment['wrap_text'] = bool(al.get('wrapText'))
                    alignment['shrink_to_fit'] = bool(al.get('shrinkToFit'))
                    text_rotation = al.get('textRotation')
                    if text_rotation is not None:
                        alignment['text_rotation'] = int(text_rotation)
                    # ignore justifyLastLine option when horizontal = distributed
                _style['alignment'] = Alignment(**alignment)

            if bool(cell_xfs_node.get('applyFont')):
                _style['font'] = self.font_list[int(
                    cell_xfs_node.get('fontId'))].copy()

            if bool(cell_xfs_node.get('applyFill')):
                _style['fill'] = self.fill_list[int(
                    cell_xfs_node.get('fillId'))].copy()

            if bool(cell_xfs_node.get('applyBorder')):
                _style['border'] = self.border_list[int(
                    cell_xfs_node.get('borderId'))].copy()

            if bool(cell_xfs_node.get('applyProtection')):
                protection = {}
                prot = cell_xfs_node.find('{%s}protection' % SHEET_MAIN_NS)
                # Ignore if there are no protection sub-nodes
                if prot is not None:
                    protection['locked'] = bool(prot.get('locked'))
                    protection['hidden'] = bool(prot.get('hidden'))
                _style['protection'] = Protection(**protection)

            self.style_prop['table'][index] = styles_list.add(Style(**_style))
Пример #12
0
Color.LightCyan = "FFE0FFFF"
Color.LightCoral = "FFF08080"
Color.LightGreen = "FF90EE90"
Color.Crimson = "FFDC143C"
Color.header = "FFD9EDF7"
Color.footer = "FFFCF8E3"

EXCEL_NUMBER_FORMAT = '0.00'

TITLE_STYLE = Style(font=Font(size=24, bold=True))
HEADER_STYLE = Style(font=Font(bold=True),
                     fill=PatternFill(fill_type=fills.FILL_SOLID,
                                      start_color=Color(rgb=Color.header)))
BOLD_CELL = Style(font=Font(bold=True))
NUMBER_CELL = Style(number_format=NumberFormat(
    format_code=EXCEL_NUMBER_FORMAT))
FOOTER_CELL = Style(
    font=Font(bold=True),
    fill=PatternFill(fill_type=fills.FILL_SOLID,
                     start_color=Color(rgb=Color.footer)),
    number_format=NumberFormat(format_code=EXCEL_NUMBER_FORMAT))
LARGE_FOOTER_CELL = Style(
    font=Font(bold=True, size=16),
    fill=PatternFill(fill_type=fills.FILL_SOLID,
                     start_color=Color(rgb=Color.footer)),
    number_format=NumberFormat(format_code=EXCEL_NUMBER_FORMAT))

# A, B, C, ..., AA, AB, AC, ..., ZZ
ASCII_UPPERCASE = list(ascii_uppercase) + list(
    ''.join(duple)
    for duple in itertools.combinations_with_replacement(ascii_uppercase, 2))
Пример #13
0
class Axis(object):

    POSITION_BOTTOM = 'b'
    POSITION_LEFT = 'l'
    ORIENTATION_MIN_MAX = "minMax"

    position = None
    tick_label_position = None
    crosses = None
    auto = None
    label_align = None
    label_offset = None
    cross_between = None
    orientation = ORIENTATION_MIN_MAX
    number_format = NumberFormat()
    delete_axis = False

    def __init__(self, auto_axis=True):
        self.auto_axis = auto_axis
        self.min = 0
        self.max = 0
        self.unit = None
        self.title = ''

    def _max_min(self):
        """
        Calculate minimum and maximum for the axis adding some padding.
        There are always a maximum of ten units for the length of the axis.
        """
        value = length = self._max - self._min

        sign = value / value
        zoom = less_than_one(value) or 1
        value = value * zoom
        ab = abs(value)
        value = math.ceil(ab * 1.1) * sign

        # calculate tick
        l = math.log10(abs(value))
        exp = int(l)
        mant = l - exp
        unit = math.ceil(math.ceil(10**mant) * 10**(exp - 1))
        # recalculate max
        value = math.ceil(value / unit) * unit
        unit = unit / zoom

        if value / unit > 9:
            # no more that 10 ticks
            unit *= 2
        self.unit = unit
        scale = value / length
        mini = math.floor(self._min * scale) / zoom
        maxi = math.ceil(self._max * scale) / zoom
        return mini, maxi

    @property
    def min(self):
        if self.auto_axis:
            return self._max_min()[0]
        return self._min

    @min.setter
    def min(self, value):
        self._min = value

    @property
    def max(self):
        if self.auto_axis:
            return self._max_min()[1]
        return self._max

    @max.setter
    def max(self, value):
        self._max = value

    @property
    def unit(self):
        if self.auto_axis:
            self._max_min()
        return self._unit

    @unit.setter
    def unit(self, value):
        self._unit = value
Пример #14
0
from openpyxl.worksheet import Worksheet
from openpyxl.xml.functions import (XMLGenerator, start_tag, end_tag, tag)
from openpyxl.date_time import (to_excel, timedelta_to_days, time_to_days)
from openpyxl.xml.constants import MAX_COLUMN, MAX_ROW, PACKAGE_XL
from openpyxl.units import NUMERIC_TYPES
from openpyxl.exceptions import WorkbookAlreadySaved
from openpyxl.writer.excel import ExcelWriter
from openpyxl.writer.strings import write_string_table
from openpyxl.writer.styles import StyleWriter
from openpyxl.styles import Style, NumberFormat, DEFAULTS

from openpyxl.xml.constants import (ARC_SHARED_STRINGS, PACKAGE_WORKSHEETS)

ITERABLES = (list, tuple)

DATETIME_STYLE = Style(number_format=NumberFormat(
    format_code=NumberFormat.FORMAT_DATE_YYYYMMDD2))
STYLES = {
    'datetime': {
        'type': Cell.TYPE_NUMERIC,
        'style': DATETIME_STYLE
    },
    'string': {
        'type': Cell.TYPE_STRING,
        'style': DEFAULTS
    },
    'numeric': {
        'type': Cell.TYPE_NUMERIC,
        'style': DEFAULTS
    },
    'formula': {
        'type': Cell.TYPE_FORMULA,