1 Ext.ns("Msp.Component");
2
3 //config = {
4 // fileName : "净值及头寸核对",
5 // exportDate : "2014-01-20",
6 // dataSource : [
7 // {grid : grid1, param : param1, showType : true},
8 // {grid : grid2, param : param2, showType : false}
9 // ],
10 // hiddenColumnArr : ["assetName"],
11 // isMail : true,
12 // filePath : "C:\\mspMail\\"
13 //}
14
15 Msp.Component.PageToExcel = function(config){
16 this.initialConfig = config;
17 this.excel = null;
18 this.workBook = null;
19 this.sheet = null;
20
21 //是否发送邮件
22 this.isMail = false;
23 //如果是发送邮件,生成excel附件的存放目录
24 this.filePath = "C:\\mspMail\\";
25 //导出日期,默认为当天
26 this.exportDate = getCurDate();
27 //定时执行垃圾回收的标识
28 this.idTmr = "";
29 this.dataSource = [];
30
31 //过滤自定义不显示的列
32 this.hiddenColumnArr = ['checked','checkerId','checkTime'];
33 Ext.apply(this,config);
34 };
35
36 Msp.Component.PageToExcel.prototype = {
37
38 /**
39 * 创建excel对象
40 */
41 createExcel : function(){
42 try{
43 this.excel = new ActiveXObject("Excel.Application");
44 //控制execl是否打开 true 打开 ,false 不打开
45 this.excel.Visible = false;
46 this.workBook = this.excel.Workbooks.Add();
47 this.sheet = null;
48 }catch(e){
49 sofa.alert("请确认安装了非绿色版本的excel!"+e.description);
50 }
51 },
52
53 /**
54 * 关闭excle对象
55 */
56 closeExcel : function(){
57 if(this.workBook != null){
58 this.workBook.Close(SaveChanges=false);
59 }
60 if(this.excel != null){
61 this.excel.Quit();
62 }
63 this.workBook = null;
64 this.sheet = null;
65 //EXCEL.EXE进程清理
66 this.idTmr = window.setInterval(this.cleanup,1);
67 },
68
69 /**
70 * EXCEL.EXE进程清理
71 */
72 cleanup : function(){
73 window.clearInterval(this.idTmr);
74 window.CollectGarbage();
75 },
76
77 /**
78 * 默认的sheet不够用时,添加额外的sheet
79 */
80 addSheetsExt : function(){
81 //默认的sheet数量,经测试win7默认3个sheet,xp默认1个sheet
82 var defaultSheetNum = this.workBook.Sheets.count,
83 count = 0;//需要sheet的个数
84 for(var i = 0; i < this.dataSource.length; i++){
85 //判断是否需要生成新的sheet,如果默认的sheet不够用则生成新的sheet
86 if(this.dataSource[i].showType){
87 count++;
88 if(count > defaultSheetNum){
89 this.workBook.Sheets.add;
90 }
91 }
92 }
93 },
94
95 /**
96 * 生成一个excel文件
97 */
98 handleExcel : function(){
99
100 if(this.dataSource && this.dataSource.length > 0){
101 var layerNum = 0,//sheet的层数
102 rowIndex = 0;//行索引
103
104 this.addSheetsExt();
105
106 for(var i = 0; i < this.dataSource.length; i++){
107 if(this.dataSource[i].showType){
108 layerNum ++;
109 this.sheet = this.workBook.Worksheets(layerNum);
110 this.sheet.name = "第【"+layerNum+"】层";
111
112 //行索引归零
113 rowIndex = 0;
114 }
115 //生成数据到sheet,并返回当前grid的总记录数
116 var totalRecords = this.changeGridToExcel(this.dataSource[i].grid,this.dataSource[i].param,this.sheet,rowIndex);
117 //保存grid查询出来的总记录数,方便以后统计异常记录数
118 this.dataSource[i].total = totalRecords;
119 if(totalRecords > 0){
120 rowIndex = rowIndex + totalRecords + 3;
121 }
122 }
123 }
124
125 },
126
127 /**
128 * 构建工作表的标题
129 * @param {} sheet 工作表
130 * @param {} rowIndex 行索引
131 * @param {} colNum 总列数
132 * @param {} titleName 标题名称
133 */
134 buildTitle : function(sheet, rowIndex, colNum, titleName){
135 /***************************************标题开始***********************************************/
136 //合并标题单元格
137 sheet.Range("A"+(rowIndex+1),sheet.Cells(rowIndex+1,colNum)).MergeCells=true;
138 //居中显示
139 sheet.Cells(rowIndex+1,1).HorizontalAlignment=3;
140 //设置粗体
141 sheet.Cells(rowIndex+1,1).Font.Bold=true;
142 //字体大小
143 sheet.Cells(rowIndex+1,1).Font.Size=15;
144 //字体颜色
145 sheet.Cells(rowIndex+1,1).Font.ColorIndex=10;
146 //模块名称
147 sheet.Cells(rowIndex+1,1).value = titleName;
148 /***************************************标题结束***********************************************/
149
150 /***************************************导出日期开始*******************************************/
151 //合并时间单元格
152 sheet.Range("A"+(rowIndex+2),sheet.Cells(rowIndex+2,colNum)).MergeCells=true;
153 //居左显示
154 sheet.Cells(rowIndex+2,1).HorizontalAlignment=2;
155 //导出日期
156 sheet.Cells(rowIndex+2,1).value = this.exportDate;
157 /***************************************导出日期结束*******************************************/
158 },
159
160 /**
161 * 构建工作表的内容
162 * @param {} sheet 工作表
163 * @param {} rowArr 行数组
164 * @param {} columnArr 列数组
165 * @param {} rowIndex 行索引
166 * @return {} 工作表的列数
167 */
168 buildContent : function(sheet, rowArr, columnArr, rowIndex){
169 //标题行、日期行、表头行占三行
170 var startIndex = rowIndex + 3;
171 /***************************************内容设置开始***********************************************/
172 for (var i = 0;i< rowArr.length; i++){
173 var count = 1;
174 for(var j = 0;j< columnArr.length;j++){
175 //列出不隐藏的列
176 if(columnArr[j].hidden == undefined && !Ext.isEmpty(columnArr[j].dataIndex) ){
177 //过滤自定义不显示的列
178 if(this.hiddenColumnArr && this.hiddenColumnArr.indexOf(columnArr[j].dataIndex) > -1){
179 continue;
180 }
181 //居中显示
182 sheet.Cells(startIndex+1+i,count).HorizontalAlignment=3;
183 //边框样式
184 sheet.Cells(startIndex+1+i,count).Borders.LineStyle=1;
185 //单元格边框颜色
186 sheet.Cells(startIndex+1+i,count).Borders.ColorIndex=10;
187 //将单元置为文本,避免非数字列被自动变成科学计数法和丢失前缀的0
188 sheet.Cells(startIndex+1+i,count).NumberFormat = "@";
189
190 var viewValue = rowArr[i][columnArr[j].dataIndex];
191 if(columnArr[j].renderer != undefined && !Ext.isEmpty(viewValue)){
192 //页面渲染时需要使用当前行的数据作为判断条件
193 var rdata = {};
194 rdata.data = rowArr[i];
195 viewValue = columnArr[j].renderer(viewValue,null,rdata);
196 }
197 if(viewValue == undefined){
198 viewValue = '';
199 }
200 if(viewValue != null){
201 viewValue = Ext.util.Format.trim(viewValue.toString());//去空格
202 }
203 //viewValue 前面加空格是为了处理 2/2的数据格式,cells默认会理解为日期
204 sheet.Cells(startIndex+1+i,count).value = " "+viewValue;
205 count++;
206 }
207 }
208 }
209 /***************************************内容设置结束***********************************************/
210 return count - 1;
211 },
212
213 /**
214 * 构建工作表的列头
215 * @param {} sheet 工作表
216 * @param {} columnArr 列头数组
217 * @param {} rowIndex 行索引
218 */
219 buildHeader : function(sheet, columnArr, rowIndex){
220 /***************************************列头设置开始***********************************************/
221 //标题行、日期行、表头行占三行
222 var startIndex = rowIndex + 3;
223 var count = 1;
224 for (var i = 0 ;i < columnArr.length; i++){
225 //列出不隐藏的列头项并排除序号列和复选框列
226 if(!columnArr[i].hidden &&
227 (columnArr[i].header && columnArr[i].header.length>0 && columnArr[i].header != '序号') &&
228 columnArr[i].id != 'checker'){
229 //过滤自定义不显示的列
230 if(this.hiddenColumnArr && this.hiddenColumnArr.indexOf(columnArr[i].dataIndex) > -1){
231 continue;
232 }
233 //居中显示
234 sheet.Cells(startIndex,count).HorizontalAlignment=3;
235 //设置粗体
236 sheet.Cells(startIndex,count).Font.Bold=true;
237 //列头名称
238 sheet.Cells(startIndex,count).value = columnArr[i].header;
239 //边框样式
240 sheet.Cells(startIndex,count).Borders.LineStyle=1;
241 //单元格边框颜色
242 sheet.Cells(startIndex,count).Borders.ColorIndex=10;
243 //单元格底色
244 sheet.Cells(startIndex,count).Interior.ColorIndex=2;
245 count++;
246 }
247 }
248 /***************************************列头设置结束***********************************************/
249 },
250
251 /**
252 * 将grid的数据写入到sheet中
253 * @param {} grid 表格
254 * @param {} param 查询参数
255 * @param {} sheet 当前工作表
256 * @param {} rowIndex 行索引,记录写入行的起始位置
257 * @return {} 总记录数
258 */
259 changeGridToExcel : function(grid, param, sheet,rowIndex){
260 var totalRecords = 0;
261 sofa.api.request({
262 url:grid.url,
263 params : param,
264 method:'post',
265 async:false,
266 success: function(response){
267 var rowArr = null;//行数组
268 if(typeof response.responseText == 'string'){
269 rowArr = Ext.decode(response.responseText);
270 }
271 if(rowArr == null || rowArr.length == 0){
272 return 0;
273 }
274 var columnArr = grid.getColumnModel().config;//列数组
275 try{
276 //生成内容
277 var colNum = this.buildContent(sheet, rowArr, columnArr, rowIndex);
278 //生成列头
279 this.buildHeader(sheet, columnArr, rowIndex);
280 //标题
281 var titleName = (sheet.name == '第【1】层' ? this.fileName : rowArr[0]['bizName']);
282 //生成标题
283 this.buildTitle(sheet, rowIndex, colNum,titleName);
284 //列自增长
285 sheet.Columns.AutoFit();
286 totalRecords = rowArr.length;
287 }catch(e){
288 }
289 },
290 scope:this
291 });
292 return totalRecords;
293 },
294
295 /**
296 * 保存
297 */
298 saveExcel :function(){
299 var savePath = null;
300 //导出发送邮件用的excel文件
301 if(this.isMail){
302 //无异常记录不保存
303 if(this.dataSource[0].total != 0){
304 savePath = this.filePath+this.fileName+".xls";
305 if(!Ext.isEmpty(savePath)){
306 this.sheet.SaveAs(savePath);
307 }
308 }
309 //默认的excel导出
310 }else{
311 savePath = this.excel.Application.GetSaveAsFilename(this.fileName+".xls","Excel Spreadshsheets (*.xls),*.xls,(*.xlsx),*.xlsx");
312 if(!Ext.isEmpty(savePath)){
313 this.sheet.SaveAs(savePath);
314 }
315 }
316 },
317
318 /**
319 * excel导出
320 */
321 exportExcel : function(){
322 try{
323 this.createExcel();
324 this.handleExcel();
325 this.saveExcel();
326 }catch(e){
327 }finally{
328 this.closeExcel();
329 }
330 }
331 };