/** * allows for downloading of grid data (store) directly into excel * Method: extracts data of gridPanel store, uses columnModel to construct XML excel document, * converts to Base64, then loads everything into a data URL link. * * @author Animal * */ /** * base64 encode / decode * * @location http://www.webtoolkit.info/ * */ var Base64 = (function () { // Private property var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; // Private method for UTF-8 encoding function utf8Encode(string) { string = string.replace(/\r\n/g, "\n"); var utftext = ""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if ((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; } // Public method for encoding return { encode: (typeof btoa == 'function') ? function (input) { return btoa(utf8Encode(input)); } : function (input) { var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = utf8Encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); } return output; } }; })(); Ext.override(Ext.grid.GridPanel, { getExcelXml: function (includeHidden) { var worksheet = this.createWorksheet(includeHidden); //var totalWidth = this.getColumnModel().getTotalWidth(includeHidden); return '' + '' + '' + this.title + '' + '' + '' + worksheet.height + '' + '' + worksheet.width + '' + 'False' + 'False' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + worksheet.xml + ''; }, createWorksheet: function (includeHidden) { // Calculate cell data types and extra class names which affect formatting var cellType = []; var cellTypeClass = []; var cm = this.columns; var totalWidthInPixels = 0; var colXml = ''; var headerXml = ''; var visibleColumnCountReduction = 0; var colCount = cm.length; var recordCount = this.store.getCount(); for (var i = 0; i < colCount; i++) { var column = cm[i]; if ((column.dataIndex != '') && (includeHidden || !column.isHidden())) { var w = column.getWidth(); totalWidthInPixels += w; if (column.text === "") { cellType.push("None"); cellTypeClass.push(""); ++visibleColumnCountReduction; } else { colXml += ''; headerXml += '' + '' + column.text + '' + ''; var fldtype = 'string'; if (recordCount > 0) { var model = this.store.getAt(0); var fields = model.fields; var field = null; for (key in fields.items) { if (fields.items[key].name == column.dataIndex) { field = fields.items[key]; break; } } //var field = fields.items.indexOf(column.dataIndex);// fields.items[i]; if (field != null) fldtype = field.type.type; } switch (fldtype) { case "int": cellType.push("Number"); cellTypeClass.push("int"); break; case "float": cellType.push("Number"); cellTypeClass.push("float"); break; case "bool": case "boolean": cellType.push("String"); cellTypeClass.push(""); break; case "date": cellType.push("DateTime"); cellTypeClass.push("date"); break; default: cellType.push("String"); cellTypeClass.push(""); break; } } } } var visibleColumnCount = cellType.length - visibleColumnCountReduction; var result = { height: 9000, width: Math.floor(totalWidthInPixels * 30) + 50 }; // Generate worksheet header details. var t = '' + '' + '' + '' + '' + colXml + // '' + // '' + // '' + // 'Generated by ExtJS' + // '' + // '' + '' + headerXml + ''; // Generate the data rows from the data in the Store for (var i = 0, it = this.store.data.items, l = it.length; i < l; i++) { t += ''; var cellClass = (i & 1) ? 'odd' : 'even'; r = it[i].data; var k = 0; for (var j = 0; j < colCount; j++) { var datacolumn = cm[j]; if ((datacolumn.dataIndex != '') && (includeHidden || !datacolumn.isHidden())) { var v = r[datacolumn.dataIndex]; if (cellType[k] !== "None") { t += ''; if (cellType[k] == 'DateTime') { if (v == null) { t += ""; } else { var _s = ""; _s = Ext.util.Format.date(v, "Y-m-d"); t += _s; } } else { t += v; } t += ''; } k++; } } t += ''; } result.xml = t + '' + '' + '' + '' + '' + '' + '' + '' + '' + 'Blank' + '1' + '32767' + '' + '600' + '' + '' + '' + 'False' + 'False' + '' + ''; return result; } });