Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ ws[1][1].style.alignment.rotation = 90
ws[1][1].style.alignment.wrap_text = True
ws[1][1].style.borders.top.color = Color(255, 0, 0)
ws[1][1].style.borders.right.style = '-.'
ws[1][1].style.data_type = DataTypes.INLINE_STRING
ws[1][1].style.quote_prefix = True
```

Each attribute also has constructors for implementing via `set_cell_style()`.
Expand Down
42 changes: 39 additions & 3 deletions pyexcelerate/Style.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,47 @@


class Style(object):
__slots__ = ("_font", "_fill", "_format", "_alignment", "_borders", "_size", "id")
__slots__ = ("_font", "_fill", "_format", "_alignment", "_borders", "_size", "_data_type", "_quote_prefix", "id")

def __init__(
self, font=None, fill=None, format=None, alignment=None, borders=None, size=None
self, font=None, fill=None, format=None, alignment=None, borders=None, size=None, data_type=None, quote_prefix=None
):
self._font = font
self._fill = fill
self._format = format
self._alignment = alignment
self._borders = borders
self._size = size
self._data_type = data_type
self._quote_prefix = quote_prefix

@property
def data_type(self):
return self._data_type

@data_type.setter
def data_type(self, value):
Utility.lazy_set(self, "_data_type", None, value)

@property
def quote_prefix(self):
return self._quote_prefix

@quote_prefix.setter
def quote_prefix(self, value):
if value not in (True, False):
raise TypeError(
"Invalid quote prefix value. Expects either True or False."
)
Utility.lazy_set(self, "_quote_prefix", None, value)

@property
def size(self):
return self._size

@size.setter
def size(self, value):
Utility.lazy_set(self, "_size", None, value)

@property
def is_default(self):
Expand All @@ -29,6 +55,8 @@ def is_default(self):
or self._alignment
or self._borders
or self._size is not None
or self._data_type is not None
or self._quote_prefix is not None
)

@property
Expand Down Expand Up @@ -84,6 +112,8 @@ def get_xml_string(self):
tag.append('applyFill="1" fillId="%d"' % (self._fill.id + 1))
if not self._borders is None:
tag.append('applyBorder="1" borderId="%d"' % (self._borders.id))
if not self._quote_prefix is None:
tag.append('quotePrefix="%d"' % (1 if self._quote_prefix else 0))
if self._alignment is None:
return '<xf xfId="0" %s/>' % (" ".join(tag))
else:
Expand All @@ -93,7 +123,8 @@ def get_xml_string(self):
)

def __hash__(self):
return hash((self._font, self._fill, self._format, self._alignment))
return hash((self._font, self._fill, self._format, self._alignment,
self._size, self._data_type, self._quote_prefix))

def __eq__(self, other):
if other is None:
Expand All @@ -116,6 +147,9 @@ def _binary_operation(self, other, operation):
format=operation(self.format, other.format),
alignment=operation(self.alignment, other.alignment),
borders=operation(self.borders, other.borders),
size=operation(self.size, other.size, None),
data_type=operation(self.data_type, other.data_type, None),
quote_prefix=operation(self.quote_prefix, other.quote_prefix, None),
)

def _to_tuple(self):
Expand All @@ -126,6 +160,8 @@ def _to_tuple(self):
self._alignment,
self._borders,
self._size,
self._data_type,
self._quote_prefix,
)

def __str__(self):
Expand Down
6 changes: 5 additions & 1 deletion pyexcelerate/Worksheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,12 @@ def __get_cell_data(self, cell, x, y, style):
if cell is None:
return "" # no cell data
# boolean values are treated oddly in dictionaries, manually override
type = DataTypes.get_type(cell)

if style and style.data_type:
type = style.data_type
else:
type = DataTypes.get_type(cell)

if type == DataTypes.NUMBER:
if math.isnan(cell):
z = '" t="e"><v>#NUM!</v></c>'
Expand Down
38 changes: 38 additions & 0 deletions pyexcelerate/tests/test_Style.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import openpyxl
from nose.tools import eq_, ok_, raises

from ..DataTypes import DataTypes
from ..Alignment import Alignment
from ..Color import Color
from ..Fill import Fill
from ..Font import Font
from ..Format import Format
from ..Style import Style
from ..Workbook import Workbook
from .utils import get_output_path
Expand Down Expand Up @@ -73,6 +75,14 @@ def test_invalid_vertical():
a.vertical = "somewhere"


@raises(TypeError)
def test_invalid_quote_prefix():
a = Style()
a.quote_prefix = True
ok_(a.quote_prefix)
a.quote_prefix = "some random nonsense"


def test_style_compression():
wb = Workbook()
ws = wb.new_sheet("test")
Expand Down Expand Up @@ -187,3 +197,31 @@ def test_unicode_with_styles():
ws[1][1].value = u"Körperschaft des öffentlichen"
ws.set_col_style(2, Style(size=0))
wb.save(get_output_path("unicode-styles.xlsx"))


def test_style_data_type():
wb = Workbook()
ws = wb.new_sheet("test")
ws[1][2].value = "no datatype"
ws[1][3].value = "has datatype"
ws[2][1].value = "no format"
ws[3][1].value = "has format"
ws[2][2].value = "=abcde"
ws[2][3].value = "=abcde"
ws[3][2].value = "=abcde"
ws[3][3].value = "=abcde"
ws[2][3].style.data_type = DataTypes.INLINE_STRING
ws[3][3].style.data_type = DataTypes.INLINE_STRING
ws[3][2].style.format = Format('@')
ws[3][3].style.format = Format('@')
wb.save(r"test.xlsx")


def test_style_quota_prefix():
wb = Workbook()
ws = wb.new_sheet("test")
ws[1][1].value = "abcde"
ws[1][1].style.quote_prefix = True
ws[1][2].value = "'abcde"
ws[1][2].style.quote_prefix = True
wb.save(r"test.xlsx")