Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import pandas._libs.json as json 

2 

3from pandas.io.excel._base import ExcelWriter 

4from pandas.io.excel._util import _validate_freeze_panes 

5 

6 

7class _XlwtWriter(ExcelWriter): 

8 engine = "xlwt" 

9 supported_extensions = (".xls",) 

10 

11 def __init__(self, path, engine=None, encoding=None, mode="w", **engine_kwargs): 

12 # Use the xlwt module as the Excel writer. 

13 import xlwt 

14 

15 engine_kwargs["engine"] = engine 

16 

17 if mode == "a": 

18 raise ValueError("Append mode is not supported with xlwt!") 

19 

20 super().__init__(path, mode=mode, **engine_kwargs) 

21 

22 if encoding is None: 

23 encoding = "ascii" 

24 self.book = xlwt.Workbook(encoding=encoding) 

25 self.fm_datetime = xlwt.easyxf(num_format_str=self.datetime_format) 

26 self.fm_date = xlwt.easyxf(num_format_str=self.date_format) 

27 

28 def save(self): 

29 """ 

30 Save workbook to disk. 

31 """ 

32 return self.book.save(self.path) 

33 

34 def write_cells( 

35 self, cells, sheet_name=None, startrow=0, startcol=0, freeze_panes=None 

36 ): 

37 # Write the frame cells using xlwt. 

38 

39 sheet_name = self._get_sheet_name(sheet_name) 

40 

41 if sheet_name in self.sheets: 

42 wks = self.sheets[sheet_name] 

43 else: 

44 wks = self.book.add_sheet(sheet_name) 

45 self.sheets[sheet_name] = wks 

46 

47 if _validate_freeze_panes(freeze_panes): 

48 wks.set_panes_frozen(True) 

49 wks.set_horz_split_pos(freeze_panes[0]) 

50 wks.set_vert_split_pos(freeze_panes[1]) 

51 

52 style_dict = {} 

53 

54 for cell in cells: 

55 val, fmt = self._value_with_fmt(cell.val) 

56 

57 stylekey = json.dumps(cell.style) 

58 if fmt: 

59 stylekey += fmt 

60 

61 if stylekey in style_dict: 

62 style = style_dict[stylekey] 

63 else: 

64 style = self._convert_to_style(cell.style, fmt) 

65 style_dict[stylekey] = style 

66 

67 if cell.mergestart is not None and cell.mergeend is not None: 

68 wks.write_merge( 

69 startrow + cell.row, 

70 startrow + cell.mergestart, 

71 startcol + cell.col, 

72 startcol + cell.mergeend, 

73 val, 

74 style, 

75 ) 

76 else: 

77 wks.write(startrow + cell.row, startcol + cell.col, val, style) 

78 

79 @classmethod 

80 def _style_to_xlwt( 

81 cls, item, firstlevel: bool = True, field_sep=",", line_sep=";" 

82 ) -> str: 

83 """helper which recursively generate an xlwt easy style string 

84 for example: 

85 

86 hstyle = {"font": {"bold": True}, 

87 "border": {"top": "thin", 

88 "right": "thin", 

89 "bottom": "thin", 

90 "left": "thin"}, 

91 "align": {"horiz": "center"}} 

92 will be converted to 

93 font: bold on; \ 

94 border: top thin, right thin, bottom thin, left thin; \ 

95 align: horiz center; 

96 """ 

97 if hasattr(item, "items"): 

98 if firstlevel: 

99 it = [ 

100 f"{key}: {cls._style_to_xlwt(value, False)}" 

101 for key, value in item.items() 

102 ] 

103 out = f"{(line_sep).join(it)} " 

104 return out 

105 else: 

106 it = [ 

107 f"{key} {cls._style_to_xlwt(value, False)}" 

108 for key, value in item.items() 

109 ] 

110 out = f"{(field_sep).join(it)} " 

111 return out 

112 else: 

113 item = f"{item}" 

114 item = item.replace("True", "on") 

115 item = item.replace("False", "off") 

116 return item 

117 

118 @classmethod 

119 def _convert_to_style(cls, style_dict, num_format_str=None): 

120 """ 

121 converts a style_dict to an xlwt style object 

122 

123 Parameters 

124 ---------- 

125 style_dict : style dictionary to convert 

126 num_format_str : optional number format string 

127 """ 

128 import xlwt 

129 

130 if style_dict: 

131 xlwt_stylestr = cls._style_to_xlwt(style_dict) 

132 style = xlwt.easyxf(xlwt_stylestr, field_sep=",", line_sep=";") 

133 else: 

134 style = xlwt.XFStyle() 

135 if num_format_str is not None: 

136 style.num_format_str = num_format_str 

137 

138 return style