root/excelreportplugin/0.10/excel_report_plugin.py

Revision 1980, 5.4 kB (checked in by ajo, 2 years ago)

ExcelReportPlugin:

* cleaned up a little bit
* added spanish support

Line 
1 """ Report renderer for Excel .xls format """
2
3 from trac.core import *
4 from trac.ticket.report import ITicketReportRenderer
5 from trac.ticket.web_ui import TicketModule
6 from trac.ticket.query import QueryModule
7 from pyExcelerator import *
8 from datetime import datetime
9 import copy
10 import types
11
12 class XlsDoc(CompoundDoc.XlsDoc):
13     def get(self, stream):
14         padding = '\x00' * (0x1000 - (len(stream) % 0x1000))
15         self.book_stream_len = len(stream) + len(padding)
16         self.__build_directory()
17         self.__build_sat()
18         self.__build_header()
19         return '%s%s%s%s%s%s%s' % (
20             self.header,
21             self.packed_MSAT_1st,
22             stream,
23             padding,
24             self.packed_MSAT_2nd,
25             self.packed_SAT,
26             self.dir_stream)
27
28 class Workbook(Workbook):
29     def get(self):
30        doc = XlsDoc()
31        return doc.get(self.get_biff_data())
32
33
34 class ReportToExcel(Component):
35         implements (ITicketReportRenderer)
36        
37         # ITicketRerportRenderer
38         def get_report_format(self):
39                 return 'xls'
40                
41         def get_report_mimetype(self):
42                 return 'application/vnd.ms-excel'
43                
44         def get_report_linkname(self):
45                 return 'Excel'
46                  
47         def get_report_linkclass(self):
48                 return None #'xls'
49                                        
50         def render(self, req, cols, rows):
51                
52                 req.send_response(200)
53                 req.send_header('Content-Type', self.get_report_mimetype())
54                 req.send_header('Content-Disposition',
55                                 'filename=Report%s.xls' % req.hdf['report.id'])
56                 req.end_headers()
57          
58                 wb = Workbook()
59                 sheetname = "%s - %s" % (req.hdf['report.title'],
60                                          req.hdf['project.name'])
61                
62                
63                 ws = wb.add_sheet(self.convertSheetName(sheetname))
64                
65                 ws.panes_frozen = True
66                 ro = 1
67                 ws.horz_split_pos = ro
68                
69                
70                 font0 = Font()
71                 font0.charset = font0.CHARSET_SYS_DEFAULT
72                 font0.name = 'MS UI Gothic'
73                 font1 = copy.copy(font0)
74                 font1.bold = True
75                 font2 = copy.copy(font0)
76                 font2.height = 0x00A0
77                 align0 = Alignment()
78                 align1 = copy.copy(align0)
79                 align1.vert = align1.VERT_TOP
80                 align2 = copy.copy(align1)
81                 align2.wrap = align2.WRAP_AT_RIGHT
82          
83                 self.style0 = XFStyle()
84                 self.style0.font = font0
85                 self.style0.alignment = align1
86                 self.style0.num_format_str = 'general'
87                 self.style_colheader = copy.copy(self.style0)
88                 self.style_colheader.num_format_str = '@'
89                 self.style_colheader.font = font1
90                 self.style_num = copy.copy(self.style0)
91                 self.style_str = copy.copy(self.style0)
92                 self.style_str.num_format_str = '@'
93                 self.style_wrap_str = copy.copy(self.style0)
94                 self.style_wrap_str.alignment = align2
95                 self.style_wrap_str.font = font2
96                 self.style_date = copy.copy(self.style0)
97                 self.style_date.num_format_str = 'yyyy/mm/dd'
98          
99                 for col, cx in map(lambda x, y: [x, y], cols, range(len(cols))):
100                    
101                     name = str(col).replace('_','')
102                     ws.write(ro-1, cx, name.decode('utf-8'), self.style_colheader)
103                    
104                     conv = self.convertComments
105        
106                     style = self.style_str
107                    
108                     if name in ['time', 'date','changetime', 'created', 'modified',
109                                 'hora', 'fecha','cambio'   ,'creado'  ,'modificado']:
110                         ws.col(cx).width = 0xb00
111                         conv = self.convertTimeStamp
112                         style = self.style_date
113                        
114                     elif name in ['summary','resumen']:
115                         ws.col(cx).width = 0x1a00
116                         style = self.style_wrap_str
117                        
118                     elif name in ['description','descripcion']:
119                         ws.col(cx).width = 0x7000
120                         style = self.style_wrap_str
121                        
122                     elif name in ['color', 'ticket', 'id']:
123                         if name in ['color']:
124                             ws.col(cx).hidden = 1
125                         conv = self.convertInteger
126                         style = self.style_num
127                     elif name in ['style']:
128                         ws.col(cx).hidden = 1
129                     elif name == "component":
130                         ws.col(cx).width = 0x1a00
131                        
132                        
133                     for value, rx in map(lambda x, y: [conv(x[cx]), ro + y], \
134                                          rows, range(len(rows))):
135                         if type(value) is int:
136                                 ws.write(rx, cx, value, self.style_num)
137                         elif type(value) is datetime:
138                                 ws.write(rx, cx, value, self.style_date)
139                         elif type(value) is types.NoneType:
140                                 ws.write(rx, cx, '-',self.style_str)
141                         else:
142                                 ws.write(rx, cx, value, style)
143                        
144                        
145                                
146                    
147                 req.write(wb.get())     
148
149         def convertComments(self, x):
150                 try:   
151                         if type(x) is types.NoneType:
152                                 return x
153                         else:
154                                 return str(x).replace('\r','').rstrip('\r\n').decode('utf-8')
155                 except:
156                         return x.replace('\r','').rstrip('\r\n')
157                
158        
159         def convertTimeStamp(self,timestamp):
160                
161                 try:
162                         return datetime.fromtimestamp(float(timestamp))
163                 except:
164                         return timestamp
165                
166         def convertInteger(self,value):
167                 try:
168                         return int(value)
169                 except:
170                         return value
171                        
172         def convertSheetName(self, sheetname):
173                
174                 sheetname = sheetname.replace('/','-')
175                
176                 try:
177                         return sheetname.decode('utf-8')
178                 except:
179                         return sheetname
180                        
181                  
182                        
183                
Note: See TracBrowser for help on using the browser.