Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/xlwt/Utils.py: 13%

100 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1# see the xlwt.license module for details of licensing. 

2 

3# Utilities for work with reference to cells and with sheetnames 

4 

5import re 

6from .ExcelMagic import MAX_ROW, MAX_COL 

7from .compat import xrange 

8 

9_re_cell_ex = re.compile(r"(\$?)([A-I]?[A-Z])(\$?)(\d+)", re.IGNORECASE) 

10_re_row_range = re.compile(r"\$?(\d+):\$?(\d+)") 

11_re_col_range = re.compile(r"\$?([A-I]?[A-Z]):\$?([A-I]?[A-Z])", re.IGNORECASE) 

12_re_cell_range = re.compile(r"\$?([A-I]?[A-Z]\$?\d+):\$?([A-I]?[A-Z]\$?\d+)", re.IGNORECASE) 

13_re_cell_ref = re.compile(r"\$?([A-I]?[A-Z]\$?\d+)", re.IGNORECASE) 

14 

15 

16def col_by_name(colname): 

17 """'A' -> 0, 'Z' -> 25, 'AA' -> 26, etc 

18 """ 

19 col = 0 

20 power = 1 

21 for i in xrange(len(colname)-1, -1, -1): 

22 ch = colname[i] 

23 col += (ord(ch) - ord('A') + 1) * power 

24 power *= 26 

25 return col - 1 

26 

27 

28def cell_to_rowcol(cell): 

29 """Convert an Excel cell reference string in A1 notation 

30 to numeric row/col notation. 

31 

32 Returns: row, col, row_abs, col_abs 

33 

34 """ 

35 m = _re_cell_ex.match(cell) 

36 if not m: 

37 raise Exception("Ill-formed single_cell reference: %s" % cell) 

38 col_abs, col, row_abs, row = m.groups() 

39 row_abs = bool(row_abs) 

40 col_abs = bool(col_abs) 

41 row = int(row) - 1 

42 col = col_by_name(col.upper()) 

43 return row, col, row_abs, col_abs 

44 

45 

46def cell_to_rowcol2(cell): 

47 """Convert an Excel cell reference string in A1 notation 

48 to numeric row/col notation. 

49 

50 Returns: row, col 

51 

52 """ 

53 m = _re_cell_ex.match(cell) 

54 if not m: 

55 raise Exception("Error in cell format") 

56 col_abs, col, row_abs, row = m.groups() 

57 # Convert base26 column string to number 

58 # All your Base are belong to us. 

59 row = int(row) - 1 

60 col = col_by_name(col.upper()) 

61 return row, col 

62 

63 

64def rowcol_to_cell(row, col, row_abs=False, col_abs=False): 

65 """Convert numeric row/col notation to an Excel cell reference string in 

66 A1 notation. 

67 

68 """ 

69 assert 0 <= row < MAX_ROW # MAX_ROW counts from 1 

70 assert 0 <= col < MAX_COL # MAX_COL counts from 1 

71 d = col // 26 

72 m = col % 26 

73 chr1 = "" # Most significant character in AA1 

74 if row_abs: 

75 row_abs = '$' 

76 else: 

77 row_abs = '' 

78 if col_abs: 

79 col_abs = '$' 

80 else: 

81 col_abs = '' 

82 if d > 0: 

83 chr1 = chr(ord('A') + d - 1) 

84 chr2 = chr(ord('A') + m) 

85 # Zero index to 1-index 

86 return col_abs + chr1 + chr2 + row_abs + str(row + 1) 

87 

88def rowcol_pair_to_cellrange(row1, col1, row2, col2, 

89 row1_abs=False, col1_abs=False, row2_abs=False, col2_abs=False): 

90 """Convert two (row,column) pairs 

91 into a cell range string in A1:B2 notation. 

92 

93 Returns: cell range string 

94 """ 

95 assert row1 <= row2 

96 assert col1 <= col2 

97 return ( 

98 rowcol_to_cell(row1, col1, row1_abs, col1_abs) 

99 + ":" 

100 + rowcol_to_cell(row2, col2, row2_abs, col2_abs) 

101 ) 

102 

103def cellrange_to_rowcol_pair(cellrange): 

104 """Convert cell range string in A1 notation to numeric row/col 

105 pair. 

106 

107 Returns: row1, col1, row2, col2 

108 

109 """ 

110 cellrange = cellrange.upper() 

111 # Convert a row range: '1:3' 

112 res = _re_row_range.match(cellrange) 

113 if res: 

114 row1 = int(res.group(1)) - 1 

115 col1 = 0 

116 row2 = int(res.group(2)) - 1 

117 col2 = -1 

118 return row1, col1, row2, col2 

119 # Convert a column range: 'A:A' or 'B:G'. 

120 # A range such as A:A is equivalent to A1:A16384, so add rows as required 

121 res = _re_col_range.match(cellrange) 

122 if res: 

123 col1 = col_by_name(res.group(1).upper()) 

124 row1 = 0 

125 col2 = col_by_name(res.group(2).upper()) 

126 row2 = -1 

127 return row1, col1, row2, col2 

128 # Convert a cell range: 'A1:B7' 

129 res = _re_cell_range.match(cellrange) 

130 if res: 

131 row1, col1 = cell_to_rowcol2(res.group(1)) 

132 row2, col2 = cell_to_rowcol2(res.group(2)) 

133 return row1, col1, row2, col2 

134 # Convert a cell reference: 'A1' or 'AD2000' 

135 res = _re_cell_ref.match(cellrange) 

136 if res: 

137 row1, col1 = cell_to_rowcol2(res.group(1)) 

138 return row1, col1, row1, col1 

139 raise Exception("Unknown cell reference %s" % (cellrange)) 

140 

141 

142def cell_to_packed_rowcol(cell): 

143 """ pack row and column into the required 4 byte format """ 

144 row, col, row_abs, col_abs = cell_to_rowcol(cell) 

145 if col >= MAX_COL: 

146 raise Exception("Column %s greater than IV in formula" % cell) 

147 if row >= MAX_ROW: # this for BIFF8. for BIFF7 available 2^14 

148 raise Exception("Row %s greater than %d in formula" % (cell, MAX_ROW)) 

149 col |= int(not row_abs) << 15 

150 col |= int(not col_abs) << 14 

151 return row, col 

152 

153# === sheetname functions === 

154 

155def valid_sheet_name(sheet_name): 

156 if sheet_name == u"" or sheet_name[0] == u"'" or len(sheet_name) > 31: 

157 return False 

158 for c in sheet_name: 

159 if c in u"[]:\\?/*\x00": 

160 return False 

161 return True 

162 

163def quote_sheet_name(unquoted_sheet_name): 

164 if not valid_sheet_name(unquoted_sheet_name): 

165 raise Exception( 

166 'attempt to quote an invalid worksheet name %r' % unquoted_sheet_name) 

167 return u"'" + unquoted_sheet_name.replace(u"'", u"''") + u"'"