UpExcel.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  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. bodyStyle : 'background: #f1f1f1;padding: 10px;',
  153. items : items
  154. });
  155. },
  156. createExcelGrid : function(columns, fields, data) {
  157. var me = this;
  158. var cols = new Array();
  159. Ext.each(columns, function(c) {
  160. c = me.removeKeys(c, [ 'locked', 'summaryType', 'logic', 'renderer' ]);
  161. cols.push(c);
  162. });
  163. var l = Math.floor(cols.length / 5);
  164. var h = 95 - l * 5;
  165. return Ext.create('Ext.grid.Panel', {
  166. id : 'excelgrid',
  167. anchor : '100% ' + h + '%',
  168. columns : cols,
  169. store : Ext.create('Ext.data.Store', {
  170. fields : fields,
  171. data : data
  172. }),
  173. columnLines : true,
  174. multiselected : new Array(),
  175. selModel : Ext.create('Ext.selection.CheckboxModel', {
  176. ignoreRightMouseSelection : false,
  177. listeners : {
  178. selectionchange : function(selectionModel, selected, options) {
  179. }
  180. },
  181. onRowMouseDown : function(view, record, item, index, e) {
  182. var me = Ext.getCmp('excelgrid');
  183. var bool = true;
  184. var items = me.selModel.getSelection();
  185. Ext.each(items, function(item, index) {
  186. if (this.index == record.index) {
  187. bool = false;
  188. me.selModel.deselect(record);
  189. Ext.Array.remove(items, item);
  190. Ext.Array.remove(me.multiselected, record);
  191. }
  192. });
  193. Ext.each(me.multiselected, function(item, index) {
  194. items.push(item);
  195. });
  196. me.selModel.select(items);
  197. if (bool) {
  198. view.el.focus();
  199. var checkbox = item.childNodes[0].childNodes[0].childNodes[0];
  200. if (checkbox.getAttribute('class') == 'x-grid-row-checker') {
  201. me.multiselected.push(record);
  202. items.push(record);
  203. me.selModel.select(items);
  204. } else {
  205. me.selModel.deselect(record);
  206. Ext.Array.remove(me.multiselected, record);
  207. }
  208. }
  209. },
  210. onHeaderClick : function(headerCt, header, e) {
  211. if (header.isCheckerHd) {
  212. e.stopEvent();
  213. var isChecked = header.el.hasCls(Ext.baseCSSPrefix + 'grid-hd-checker-on');
  214. if (isChecked) {
  215. this.deselectAll(true);
  216. var grid = Ext.getCmp('excelgrid');
  217. this.deselect(grid.multiselected);
  218. grid.multiselected = new Array();
  219. var els = Ext.select('div[@class=x-grid-row-checker-checked]').elements;
  220. Ext.each(els, function(el, index) {
  221. el.setAttribute('class', 'x-grid-row-checker');
  222. });
  223. header.el.removeCls(Ext.baseCSSPrefix + 'grid-hd-checker-on');// 添加这个
  224. } else {
  225. var grid = Ext.getCmp('excelgrid');
  226. this.deselect(grid.multiselected);
  227. grid.multiselected = new Array();
  228. var els = Ext.select('div[@class=x-grid-row-checker-checked]').elements;
  229. Ext.each(els, function(el, index) {
  230. el.setAttribute('class', 'x-grid-row-checker');
  231. });
  232. this.selectAll(true);
  233. header.el.addCls(Ext.baseCSSPrefix + 'grid-hd-checker-on');// 添加这个
  234. }
  235. }
  236. }
  237. })
  238. });
  239. },
  240. getGridText : function(grid) {
  241. var texts = [];
  242. Ext.Array.each(grid.columns, function(c) {
  243. if (!c.hidden && (c.width > 0 || c.flex > 0) && !c.isCheckerHd) {
  244. var text = c.text || c.header;
  245. if (text) {
  246. if ((c.items && c.items.length > 0) || (c.columns && c.columns.length > 0)) {
  247. var items = (c.items && c.items.items) || c.columns;
  248. Ext.Array.each(items, function(i) {
  249. texts.push(text + '(' + (i.text || i.header) + ')');
  250. });
  251. } else
  252. texts.push(text);
  253. }
  254. }
  255. });
  256. return texts;
  257. },
  258. getGridHeaders : function(grid) {
  259. var cols = {};
  260. Ext.Array.each(grid.columns, function(c) {
  261. if (!c.hidden && (c.width > 0 || c.flex > 0) && !c.isCheckerHd) {
  262. var text = c.text || c.header;
  263. if (text) {
  264. if ((c.items && c.items.length > 0) || (c.columns && c.columns.length > 0)) {
  265. var items = (c.items && c.items.items) || c.columns;
  266. Ext.Array.each(items, function(i) {
  267. cols[text + '(' + (i.text || i.header) + ')'] = i;
  268. });
  269. } else
  270. cols[text] = c;
  271. }
  272. }
  273. });
  274. return cols;
  275. },
  276. /**
  277. * excel没有grid列的dataIndex,只能根据grid列的header来匹配 From fGrid To tGrid
  278. */
  279. exportGridToGrid : function(fGrid, tGrid, callback) {
  280. var me = this, cols = me.getGridHeaders(tGrid);
  281. var f = new Array();
  282. var rel = new Object();
  283. Ext.each(fGrid.columns, function(c) {
  284. if (!c.hidden && cols[c.text]) {
  285. f.push(c);
  286. rel[c.dataIndex] = cols[c.text];
  287. }
  288. });
  289. var fields = Ext.Array.pluck(f, 'dataIndex');
  290. var data = new Array();
  291. var o = null, errs = [];
  292. var r = fGrid.ownerCt.down('radiogroup'), m = r.getValue().import_mode;
  293. var detno = 1, len = tGrid.store.data.items.length;
  294. if (m == '+' && tGrid.detno) {
  295. detno = (tGrid.store.max(tGrid.detno) || 0) + 1;
  296. }
  297. Ext.each(fGrid.selModel.getSelection(), function(item, index) {
  298. o = new Object();
  299. if (m == '-') {
  300. if (index + 1 <= len) {
  301. o = tGrid.store.getAt(index).data; // 可以保留覆盖的原数据的其它值不变
  302. }
  303. }
  304. var keys = Ext.Object.getKeys(item.data);
  305. Ext.each(keys, function(key) {
  306. if (Ext.Array.contains(fields, key)) {
  307. var toCol = rel[key], val = item.data[key];
  308. if(!me.isValid(val, toCol)) {
  309. errs.push('行' + (index + 1) + '(' + toCol.text + ')');
  310. } else {
  311. if(toCol.xtype == 'combocolumn' && toCol.editor)
  312. val = me.getComboValue(val, toCol.editor.store);
  313. else if(toCol.xtype == 'yncolumn')
  314. val = me.getYnValue(val);
  315. else if(toCol.xtype == 'datecolumn')
  316. val = me.getDateValue(val);
  317. }
  318. o[toCol.dataIndex] = val;
  319. }
  320. });
  321. if (tGrid.detno) {
  322. if (!o[tGrid.detno]) {
  323. o[tGrid.detno] = detno++;
  324. }
  325. }
  326. data.push(o);
  327. });
  328. if(errs.length > 0) {
  329. showError('数据未通过校验:<hr>' + errs.join('<br>'));
  330. return;
  331. }
  332. if (m == '+') {
  333. var start = tGrid.store.indexOf(tGrid.store.last());
  334. tGrid.store.add(data);
  335. var mfields = (tGrid.necessaryFields || tGrid.necessaryField);
  336. tGrid.store.each(function(item, index) {
  337. if (index > start) {
  338. item.dirty = true;// 标记为已修改
  339. var m = {};
  340. if (mfields !== undefined) {
  341. if (mfields instanceof String) {
  342. m[mfields] = item.data[mfields];
  343. } else {
  344. Ext.each(mfields, function(f) {
  345. m[f] = item.data[f];
  346. });
  347. }
  348. }
  349. item.modified = m;
  350. }
  351. });
  352. } else if (m == '-') {
  353. tGrid.store.loadData(data);
  354. var mfields = (tGrid.necessaryFields || tGrid.necessaryField);
  355. Ext.each(tGrid.store.data.items, function(item) {
  356. item.dirty = true;// 标记为已修改
  357. var m = {};
  358. if (mfields !== undefined) {
  359. if (mfields instanceof String) {
  360. m[mfields] = item.data[mfields];
  361. } else {
  362. Ext.each(mfields, function(f) {
  363. m[f] = item.data[f];
  364. });
  365. }
  366. }
  367. item.modified = m;
  368. });
  369. }
  370. callback.call(me);
  371. },
  372. removeKeys : function(obj, keys) {
  373. var o = new Object();
  374. var key = Ext.Object.getKeys(obj);
  375. Ext.each(key, function(k) {
  376. if (!Ext.Array.contains(keys, k)) {
  377. o[k] = obj[k];
  378. }
  379. });
  380. return o;
  381. },
  382. isValid: function(v, toColumn) {
  383. if(v && toColumn) {
  384. var me = this;
  385. if(toColumn.xtype == 'numbercolumn')
  386. return me.isNumber(v);
  387. else if(toColumn.xtype == 'datecolumn')
  388. return me.isDate(v);
  389. else if(toColumn.xtype == 'combocolumn' && toColumn.editor)
  390. return me.isCombo(v, toColumn.editor.store);
  391. else if(toColumn.xtype == 'yncolumn')
  392. return me.isYn(v);
  393. }
  394. return true;
  395. },
  396. isNumber: function(v) {
  397. return !isNaN(parseFloat(v)) && isFinite(v);
  398. },
  399. isDate: function(v) {
  400. var dx1 = /\d{2,4}(-|\/)\d{1,2}(-|\/)\d{1,2}/,
  401. dx2 = /\d{1,2}(-|\/)\d{1,2}(-|\/)\d{4}/;
  402. return dx1.test(v) || dx2.test(v);
  403. },
  404. isCombo: function(v, store) {
  405. if(typeof store.each == 'undefined') {
  406. for(var i in store.data) {
  407. if(store.data[i].display == v || store.data[i].value == v)
  408. return true;
  409. }
  410. } else {
  411. var r;
  412. for(var i in store.data.items) {
  413. r = store.data.items[i];
  414. if(r.get('display') == v || r.get('value') == v)
  415. return true;
  416. }
  417. }
  418. return false;
  419. },
  420. isYn: function(v) {
  421. return [-1, '-1', 1, '1', 0, '0', '是', '否'].indexOf(v) > -1;
  422. },
  423. getComboValue: function(v, store) {
  424. var actual = v;
  425. if(typeof store.each == 'undefined') {
  426. Ext.Array.each(store.data, function(d){
  427. if(d.display == v)
  428. actual = d.value;
  429. });
  430. } else {
  431. store.each(function(r){
  432. if(r.get('display') == v)
  433. actual = r.get('value');
  434. });
  435. }
  436. return actual;
  437. },
  438. getYnValue: function(v) {
  439. return [-1, '-1', 1, '1', '是'].indexOf(v) > -1 ? -1 : 0;
  440. },
  441. getDateValue: function(v) {
  442. var dx1 = /\d{2,4}-\d{1,2}-\d{1,2}/,
  443. dx2 = /\d{2,4}\/\d{1,2}\/\d{1,2}/,
  444. dx3 = /\d{1,2}-\d{1,2}-\d{4}/;
  445. dx4 = /\d{1,2}\/\d{1,2}\/\d{4}/;
  446. if(dx1.test(v))
  447. return Ext.Date.parse(v, 'Y-m-d');
  448. else if(dx2.test(v))
  449. return Ext.Date.parse(v, 'Y/m/d');
  450. else if(dx3.test(v))
  451. return Ext.Date.parse(v, 'm-d-Y');
  452. else if(dx4.test(v))
  453. return Ext.Date.parse(v, 'm/d/Y');
  454. else
  455. return null;
  456. }
  457. });