1from __future__ import absolute_import 2# Copyright (c) 2010-2019 openpyxl 3 4from openpyxl.cell import Cell 5from openpyxl.utils import get_column_letter 6from openpyxl.utils.datetime import from_excel 7from openpyxl.styles import is_date_format 8from openpyxl.styles.numbers import BUILTIN_FORMATS, BUILTIN_FORMATS_MAX_SIZE 9 10 11class ReadOnlyCell(object): 12 13 __slots__ = ('parent', 'row', 'column', '_value', 'data_type', '_style_id') 14 15 def __init__(self, sheet, row, column, value, data_type='n', style_id=0): 16 self.parent = sheet 17 self._value = None 18 self.row = row 19 self.column = column 20 self.data_type = data_type 21 self.value = value 22 self._style_id = style_id 23 24 25 def __eq__(self, other): 26 for a in self.__slots__: 27 if getattr(self, a) != getattr(other, a): 28 return 29 return True 30 31 def __ne__(self, other): 32 return not self.__eq__(other) 33 34 35 def __repr__(self): 36 return "<ReadOnlyCell {0!r}.{1}>".format(self.parent.title, self.coordinate) 37 38 39 @property 40 def coordinate(self): 41 column = get_column_letter(self.column) 42 return "{1}{0}".format(self.row, column) 43 44 45 @property 46 def coordinate(self): 47 return Cell.coordinate.__get__(self) 48 49 50 @property 51 def column_letter(self): 52 return Cell.column_letter.__get__(self) 53 54 55 @property 56 def style_array(self): 57 return self.parent.parent._cell_styles[self._style_id] 58 59 @property 60 def number_format(self): 61 _id = self.style_array.numFmtId 62 if _id < BUILTIN_FORMATS_MAX_SIZE: 63 return BUILTIN_FORMATS.get(_id, "General") 64 else: 65 return self.parent.parent._number_formats[ 66 _id - BUILTIN_FORMATS_MAX_SIZE] 67 68 @property 69 def font(self): 70 _id = self.style_array.fontId 71 return self.parent.parent._fonts[_id] 72 73 @property 74 def fill(self): 75 _id = self.style_array.fillId 76 return self.parent.parent._fills[_id] 77 78 @property 79 def border(self): 80 _id = self.style_array.borderId 81 return self.parent.parent._borders[_id] 82 83 @property 84 def alignment(self): 85 _id = self.style_array.alignmentId 86 return self.parent.parent._alignments[_id] 87 88 @property 89 def protection(self): 90 _id = self.style_array.protectionId 91 return self.parent.parent._protections[_id] 92 93 94 @property 95 def is_date(self): 96 return Cell.is_date.__get__(self) 97 98 99 @property 100 def internal_value(self): 101 return self._value 102 103 @property 104 def value(self): 105 return self._value 106 107 @value.setter 108 def value(self, value): 109 if self._value is not None: 110 raise AttributeError("Cell is read only") 111 self._value = value 112 113 114class EmptyCell(object): 115 116 __slots__ = () 117 118 value = None 119 is_date = False 120 font = None 121 border = None 122 fill = None 123 number_format = None 124 alignment = None 125 data_type = 'n' 126 127 128 def __repr__(self): 129 return "<EmptyCell>" 130 131EMPTY_CELL = EmptyCell() 132