UpExcel.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /**
  2. * excel导入Grid
  3. */
  4. Ext.define('erp.view.core.button.UpExcel', {
  5. extend : 'Ext.form.Panel',
  6. alias : 'widget.upexcel',
  7. initComponent : function() {
  8. if (this.iconCls) {
  9. this.items[0].buttonConfig.iconCls = this.iconCls;
  10. }
  11. if (this.cls) {
  12. this.items[0].buttonConfig.cls = this.cls;
  13. }
  14. if (this.itemCls) {
  15. this.items[0].buttonConfig.cls = this.itemCls;
  16. }
  17. if (this.iconCls) {
  18. this.items[0].buttonConfig.text = this.text;
  19. }
  20. this.callParent(arguments);
  21. },
  22. bodyStyle : 'background: transparent no-repeat 0 0;border: none;',
  23. items : [ {
  24. xtype : 'filefield',
  25. name : 'file',
  26. buttonOnly : true,
  27. hideLabel : true,
  28. width : 62,
  29. height : 17,
  30. buttonConfig : {
  31. iconCls : 'x-button-icon-excel',
  32. cls : 'x-btn-gray',
  33. text : $I18N.common.button.erpUpExcelButton
  34. },
  35. listeners : {
  36. change : function(field) {
  37. field.ownerCt.upexcel(field);
  38. }
  39. }
  40. } ],
  41. upexcel : function(field) {
  42. var bool = this.fireEvent('beforeimport', this);
  43. if (bool != false) {
  44. this.getForm().submit({
  45. url : basePath + 'common/upexcel.action',
  46. waitMsg : "正在解析Excel",
  47. success : function(fp, o) {
  48. field.reset();
  49. var data = Ext.decode(Ext.String.htmlDecode(o.result.grid.dataString.replace(/,}/g, '}').replace(/,]/g, ']')));
  50. field.ownerCt.createWin(o.result.grid.gridColumns, o.result.grid.gridFields, data);
  51. },
  52. failure : function(fp, o) {
  53. if (o.result.size) {
  54. showError(o.result.error + " " + Ext.util.Format.fileSize(o.result.size));
  55. field.reset();
  56. } else {
  57. showError(o.result.error);
  58. field.reset();
  59. }
  60. }
  61. });
  62. }
  63. },
  64. createWin : function(columns, fields, data) {
  65. var me = this;
  66. var form = me.createExcelForm(columns);
  67. var grid = me.createExcelGrid(columns, fields, data);
  68. Ext.create('Ext.window.Window', {
  69. id : 'excelwin',
  70. height : '100%',
  71. width : '90%',
  72. title : '请选择要导入的列和数据',
  73. layout : 'anchor',
  74. items : [ form, {
  75. xtype : 'radiogroup',
  76. columns : 2,
  77. margin : '0 0 0 10',
  78. anchor : '50% 3%',
  79. fieldLabel : '导入模式',
  80. vertical : true,
  81. items : [ {
  82. boxLabel : '追加',
  83. name : 'import_mode',
  84. inputValue : '+'
  85. }, {
  86. boxLabel : '替换',
  87. name : 'import_mode',
  88. inputValue : '-',
  89. checked : true
  90. } ]
  91. }, grid ],
  92. buttonAlign : 'center',
  93. buttons : [ {
  94. text : $I18N.common.button.erpConfirmButton,
  95. iconCls : 'x-button-icon-save',
  96. cls : 'x-btn-gray',
  97. handler : function() {
  98. me.exportGridToGrid(grid, me.grid || me.ownerCt.ownerCt || me.ownerCt.floatParent.ownerCt.ownerCt, function(){
  99. Ext.getCmp('excelwin').close();
  100. });
  101. }
  102. }, {
  103. text : $I18N.common.button.erpCloseButton,
  104. iconCls : 'x-button-icon-close',
  105. cls : 'x-btn-gray',
  106. handler : function() {
  107. Ext.getCmp('excelwin').close();
  108. }
  109. } ]
  110. }).show();
  111. grid.selModel.selectAll();
  112. Ext.each(form.items.items, function(item, index) {
  113. item.on('change', function() {
  114. Ext.each(grid.columns, function(c) {
  115. if (c.dataIndex == item.name) {
  116. if (item.checked) {
  117. c.show();
  118. } else {
  119. c.hide();
  120. }
  121. }
  122. });
  123. });
  124. });
  125. },
  126. createExcelForm : function(columns) {
  127. var l = Math.floor(columns.length / 5);
  128. var h = 2 + l * 5;
  129. var items = new Array();
  130. var item = null;
  131. var tGrid = this.grid || this.ownerCt.ownerCt || this.ownerCt.floatParent.ownerCt.ownerCt;
  132. var texts = this.getGridText(tGrid);
  133. Ext.each(columns, function(c, index) {
  134. item = new Object();
  135. item.id = c.dataIndex;
  136. item.name = c.dataIndex;
  137. item.xtype = 'checkbox';
  138. var label = c.header || c.text;
  139. if (!Ext.Array.contains(texts, label)) {// 将tGrid里面没有的列,加特殊的样式
  140. label = "<s>" + label + "</s>";
  141. item.style = 'color:#B6B7F9';
  142. }
  143. item.boxLabel = label;
  144. item.checked = true;
  145. item.labelAlign = 'right';
  146. item.columnWidth = .2;
  147. items.push(item);
  148. });
  149. return Ext.create('Ext.form.Panel', {
  150. anchor : '100% ' + h + '%',
  151. layout : 'column',
  152. autoScroll:true,
  153. bodyStyle : 'background: #f1f1f1;padding: 10px;',
  154. items : items
  155. });
  156. },
  157. createExcelGrid : function(columns, fields, data) {
  158. var me = this;
  159. var cols = new Array();
  160. Ext.each(columns, function(c) {
  161. c = me.removeKeys(c, [ 'locked', 'summaryType', 'logic', 'renderer' ]);
  162. cols.push(c);
  163. });
  164. var l = Math.floor(cols.length / 5);
  165. var h = 95 - l * 5;
  166. return Ext.create('Ext.grid.Panel', {
  167. id : 'excelgrid',
  168. anchor : '100% ' + h + '%',
  169. columns : cols,
  170. store : Ext.create('Ext.data.Store', {
  171. fields : fields,
  172. data : data
  173. }),
  174. columnLines : true,
  175. multiselected : new Array(),
  176. selModel : Ext.create('Ext.selection.CheckboxModel', {
  177. ignoreRightMouseSelection : false,
  178. listeners : {
  179. selectionchange : function(selectionModel, selected, options) {
  180. }
  181. },
  182. onRowMouseDown : function(view, record, item, index, e) {
  183. var me = Ext.getCmp('excelgrid');
  184. var bool = true;
  185. var items = me.selModel.getSelection();
  186. Ext.each(items, function(item, index) {
  187. if (this.index == record.index) {
  188. bool = false;
  189. me.selModel.deselect(record);
  190. Ext.Array.remove(items, item);
  191. Ext.Array.remove(me.multiselected, record);
  192. }
  193. });
  194. Ext.each(me.multiselected, function(item, index) {
  195. items.push(item);
  196. });
  197. me.selModel.select(items);
  198. if (bool) {
  199. view.el.focus();
  200. var checkbox = item.childNodes[0].childNodes[0].childNodes[0];
  201. if (checkbox.getAttribute('class') == 'x-grid-row-checker') {
  202. me.multiselected.push(record);
  203. items.push(record);
  204. me.selModel.select(items);
  205. } else {
  206. me.selModel.deselect(record);
  207. Ext.Array.remove(me.multiselected, record);
  208. }
  209. }
  210. },
  211. onHeaderClick : function(headerCt, header, e) {
  212. if (header.isCheckerHd) {
  213. e.stopEvent();
  214. var isChecked = header.el.hasCls(Ext.baseCSSPrefix + 'grid-hd-checker-on');
  215. if (isChecked) {
  216. this.deselectAll(true);
  217. var grid = Ext.getCmp('excelgrid');
  218. this.deselect(grid.multiselected);
  219. grid.multiselected = new Array();
  220. var els = Ext.select('div[@class=x-grid-row-checker-checked]').elements;
  221. Ext.each(els, function(el, index) {
  222. el.setAttribute('class', 'x-grid-row-checker');
  223. });
  224. header.el.removeCls(Ext.baseCSSPrefix + 'grid-hd-checker-on');// 添加这个
  225. } else {
  226. var grid = Ext.getCmp('excelgrid');
  227. this.deselect(grid.multiselected);
  228. grid.multiselected = new Array();
  229. var els = Ext.select('div[@class=x-grid-row-checker-checked]').elements;
  230. Ext.each(els, function(el, index) {
  231. el.setAttribute('class', 'x-grid-row-checker');
  232. });
  233. this.selectAll(true);
  234. header.el.addCls(Ext.baseCSSPrefix + 'grid-hd-checker-on');// 添加这个
  235. }
  236. }
  237. }
  238. })
  239. });
  240. },
  241. getGridText : function(grid) {
  242. var texts = [];
  243. Ext.Array.each(grid.columns, function(c) {
  244. if (!c.hidden && (c.width > 0 || c.flex > 0) && !c.isCheckerHd) {
  245. var text = c.text || c.header;
  246. if (text) {
  247. if ((c.items && c.items.length > 0) || (c.columns && c.columns.length > 0)) {
  248. var items = (c.items && c.items.items) || c.columns;
  249. Ext.Array.each(items, function(i) {
  250. texts.push(text + '(' + (i.text || i.header) + ')');
  251. });
  252. } else
  253. texts.push(text);
  254. }
  255. }
  256. });
  257. return texts;
  258. },
  259. getGridHeaders : function(grid) {
  260. var cols = {};
  261. Ext.Array.each(grid.columns, function(c) {
  262. if (!c.hidden && (c.width > 0 || c.flex > 0) && !c.isCheckerHd) {
  263. var text = c.text || c.header;
  264. if (text) {
  265. if ((c.items && c.items.length > 0) || (c.columns && c.columns.length > 0)) {
  266. var items = (c.items && c.items.items) || c.columns;
  267. Ext.Array.each(items, function(i) {
  268. cols[text + '(' + (i.text || i.header) + ')'] = i;
  269. });
  270. } else
  271. cols[text] = c;
  272. }
  273. }
  274. });
  275. return cols;
  276. },
  277. /**
  278. * excel没有grid列的dataIndex,只能根据grid列的header来匹配 From fGrid To tGrid
  279. */
  280. exportGridToGrid : function(fGrid, tGrid, callback) {
  281. var me = this, cols = me.getGridHeaders(tGrid);
  282. var f = new Array();
  283. var rel = new Object();
  284. Ext.each(fGrid.columns, function(c) {
  285. if (!c.hidden && cols[c.text]) {
  286. f.push(c);
  287. rel[c.dataIndex] = cols[c.text];
  288. }
  289. });
  290. var fields = Ext.Array.pluck(f, 'dataIndex');
  291. var data = new Array();
  292. var o = null, errs = [];
  293. var r = fGrid.ownerCt.down('radiogroup'), m = r.getValue().import_mode;
  294. var detno = 1, len = tGrid.store.data.items.length;
  295. if (m == '+' && tGrid.detno) {
  296. detno = (tGrid.store.max(tGrid.detno) || 0) + 1;
  297. }
  298. Ext.each(fGrid.selModel.getSelection(), function(item, index) {
  299. o = new Object();
  300. if (m == '-') {
  301. if (index + 1 <= len) {
  302. o = tGrid.store.getAt(index).data; // 可以保留覆盖的原数据的其它值不变
  303. if(tGrid.detno && o[tGrid.detno]) detno++;
  304. }
  305. }
  306. var keys = Ext.Object.getKeys(item.data);
  307. Ext.each(keys, function(key) {
  308. if (Ext.Array.contains(fields, key)) {
  309. var toCol = rel[key], val = item.data[key];
  310. if(!me.isValid(val, toCol)) {
  311. errs.push('行' + (index + 1) + '(' + toCol.text + ')');
  312. } else {
  313. if(toCol.xtype == 'combocolumn' && toCol.editor)
  314. val = me.getComboValue(val, toCol.editor.store);
  315. else if(toCol.xtype == 'yncolumn')
  316. val = me.getYnValue(val);
  317. else if(toCol.xtype == 'datecolumn')
  318. val = me.getDateValue(val);
  319. }
  320. o[toCol.dataIndex] = val;
  321. }
  322. });
  323. if (tGrid.detno) {
  324. if (!o[tGrid.detno]) {
  325. o[tGrid.detno] = detno++;
  326. }
  327. }
  328. data.push(o);
  329. });
  330. if(errs.length > 0) {
  331. showError('数据未通过校验:<hr>' + errs.join('<br>'));
  332. return;
  333. }
  334. if (m == '+') {
  335. var start = tGrid.store.indexOf(tGrid.store.last());
  336. tGrid.store.add(data);
  337. var mfields = (tGrid.necessaryFields || tGrid.necessaryField);
  338. tGrid.store.each(function(item, index) {
  339. if (index > start) {
  340. item.dirty = true;// 标记为已修改
  341. var m = {};
  342. if (mfields !== undefined) {
  343. if (mfields instanceof String) {
  344. m[mfields] = item.data[mfields];
  345. } else {
  346. Ext.each(mfields, function(f) {
  347. m[f] = item.data[f];
  348. });
  349. }
  350. }
  351. item.modified = m;
  352. }
  353. });
  354. } else if (m == '-') {
  355. tGrid.store.loadData(data);
  356. var mfields = (tGrid.necessaryFields || tGrid.necessaryField);
  357. Ext.each(tGrid.store.data.items, function(item) {
  358. item.dirty = true;// 标记为已修改
  359. var m = {};
  360. if (mfields !== undefined) {
  361. if (mfields instanceof String) {
  362. m[mfields] = item.data[mfields];
  363. } else {
  364. Ext.each(mfields, function(f) {
  365. m[f] = item.data[f];
  366. });
  367. }
  368. }
  369. item.modified = m;
  370. });
  371. }
  372. callback.call(me);
  373. },
  374. removeKeys : function(obj, keys) {
  375. var o = new Object();
  376. var key = Ext.Object.getKeys(obj);
  377. Ext.each(key, function(k) {
  378. if (!Ext.Array.contains(keys, k)) {
  379. o[k] = obj[k];
  380. }
  381. });
  382. return o;
  383. },
  384. isValid: function(v, toColumn) {
  385. if(v && toColumn) {
  386. var me = this;
  387. if(toColumn.xtype == 'numbercolumn')
  388. return me.isNumber(v);
  389. else if(toColumn.xtype == 'datecolumn')
  390. return me.isDate(v);
  391. else if(toColumn.xtype == 'combocolumn' && toColumn.editor)
  392. return me.isCombo(v, toColumn.editor.store);
  393. else if(toColumn.xtype == 'yncolumn')
  394. return me.isYn(v);
  395. }
  396. return true;
  397. },
  398. isNumber: function(v) {
  399. return !isNaN(parseFloat(v)) && isFinite(v);
  400. },
  401. isDate: function(v) {
  402. var dx1 = /\d{2,4}(-|\/)\d{1,2}(-|\/)\d{1,2}/,
  403. dx2 = /\d{1,2}(-|\/)\d{1,2}(-|\/)\d{4}/;
  404. return dx1.test(v) || dx2.test(v);
  405. },
  406. isCombo: function(v, store) {
  407. if(typeof store.each == 'undefined') {
  408. for(var i in store.data) {
  409. if(store.data[i].display == v || store.data[i].value == v)
  410. return true;
  411. }
  412. } else {
  413. var r;
  414. for(var i in store.data.items) {
  415. r = store.data.items[i];
  416. if(r.get('display') == v || r.get('value') == v)
  417. return true;
  418. }
  419. }
  420. return false;
  421. },
  422. isYn: function(v) {
  423. return [-1, '-1', 1, '1', 0, '0', '是', '否'].indexOf(v) > -1;
  424. },
  425. getComboValue: function(v, store) {
  426. var actual = v;
  427. if(typeof store.each == 'undefined') {
  428. Ext.Array.each(store.data, function(d){
  429. if(d.display == v)
  430. actual = d.value;
  431. });
  432. } else {
  433. store.each(function(r){
  434. if(r.get('display') == v)
  435. actual = r.get('value');
  436. });
  437. }
  438. return actual;
  439. },
  440. getYnValue: function(v) {
  441. return [-1, '-1', 1, '1', '是'].indexOf(v) > -1 ? -1 : 0;
  442. },
  443. getDateValue: function(v) {
  444. var dx1 = /\d{2,4}-\d{1,2}-\d{1,2}/,
  445. dx2 = /\d{2,4}\/\d{1,2}\/\d{1,2}/,
  446. dx3 = /\d{1,2}-\d{1,2}-\d{4}/;
  447. dx4 = /\d{1,2}\/\d{1,2}\/\d{4}/;
  448. if(dx1.test(v))
  449. return Ext.Date.parse(v, 'Y-m-d');
  450. else if(dx2.test(v))
  451. return Ext.Date.parse(v, 'Y/m/d');
  452. else if(dx3.test(v))
  453. return Ext.Date.parse(v, 'm-d-Y');
  454. else if(dx4.test(v))
  455. return Ext.Date.parse(v, 'm/d/Y');
  456. else
  457. return null;
  458. }
  459. });