Экспорт содержимого гридов в Excel.

Экспорт гридов в Excel является полезным и удобным инструментом. В предыдущих проектах, построенных на ExtJS 4.2.1 использовался самописный плагин для экспорта. Подробное описание можно почитать здесь - https://druckit.wordpress.com/2013/10/26/generate-an-excel-file-from-an-ext-js-4-grid/ .

В новых версиях фреймворка функционал экспорта был добавлен для использования из коробки. Если посмотреть в документацию ExtJS 6.0.0 classic, то можно найти класс Ext.exporter.Excel (http://docs.sencha.com/extjs/6.0/6.0.0-classic/#!/api/Ext.exporter.Excel). К сожалению, из коробки экспортер работает не совсем хорошо. На официальном форуме написано, что работа над ним ещё ведётся.

Поэтому создадим класс-наследник It.grid.plugin.exportToExcel.ExcelExporter для It.Classic и поместим его в соответствующую директорию - It.Classic/It/grid/plugin/exportToExcel/ExcelExporter.ts. Поменяем его alias и метод getContent:

Ext.define('It.grid.plugin.exportToExcel.ExcelExporter', {
	extend: 'Ext.exporter.Excel',

	alias: 'exporter.customExcelExporter',

	getContent: function () {
		var me = this,
			config = this.getConfig(),
			data = config.data,
			colMerge;

		me.workbook = Ext.create('Ext.exporter.file.excel.Workbook', {
			title: config.title,
			author: config.author,
			windowHeight: config.windowHeight,
			windowWidth: config.windowWidth,
			protectStructure: config.protectStructure,
			protectWindows: config.protectWindows
		});
		me.table = me.workbook.addWorksheet({
			name: config.title
		}).addTable();

		me.workbook.addStyle(config.defaultStyle);
		me.tableHeaderStyleId = me.workbook.addStyle(config.tableHeaderStyle).getId();
		me.groupHeaderStyleId = me.workbook.addStyle(config.groupHeaderStyle).getId();
		me.groupFooterStyleId = me.workbook.addStyle(config.groupFooterStyle).getId();

		colMerge = me.getColumnCount(data.columns);
		for (var i = 0; i < colMerge; i++) {
			var col = data.columns[i];
			me.table.addColumn({
				hidden: col.hidden ? 1 : null,
				width: col.width || null
			});
		};

		me.addTitle(config, colMerge);
		me.buildHeader();
		me.buildRows(colMerge);

		return me.workbook.render();
	}

});


В методе getContent необходимо для каждой колонки создать тег в создаваемом xml.

for (var i = 0; i < colMerge; i++) {
	var col = data.columns[i];
	me.table.addColumn({
		hidden: col.hidden ? 1 : null,
		width: col.width || null
	});
};

При вызове addColumn ExtJS обращается к классу Ext.exporter.file.excel.Column, который тоже переопределяем:

Ext.define('Ext.overrides.exporter.file.excel.Column', {

	override: 'Ext.exporter.file.excel.Column',

	config: {
		autoFitWidth: 1,
		caption: null,
		hidden: null,
		index: null,
		span: null,
		styleId: null,
		width: 120
	}

});

Здесь можно поставить значения для колонок по умолчанию.

И в конечном итоге наследуемся от главного класса плагина экспортера Ext.grid.plugin.Exporter и создаем свой - It.grid.plugin.exportToExcel.ExportToExcelPlugin:

Ext.define('It.grid.plugin.exportToExcel.ExportToExcelPlugin', {
	extend: 'Ext.grid.plugin.Exporter',
	alias: 'plugin.specialGridConfigExporter',

	requires: [
		'It.grid.plugin.exportToExcel.ExcelExporter'
	],

	getExporter: function (config) {
		return (Ext).Factory.exporter(Ext.apply({
			type: 'customExcelExporter',
			data: this.prepareData()
		}, config || {}));
	},

	prepareData: function () {
		var me = this,
			grid = me.grid,
			headers, group, simplifyGroup;

		group = me.extractGroups(grid.getColumnManager().getColumns());
		simplifyGroup = this.simplifyGroupRows(group);

		if (grid.lockedGrid) {
			headers = Ext.Array.merge(me.getColumnHeaders(grid.lockedGrid.headerCt.items), me.getColumnHeaders(grid.normalGrid.headerCt.items));
		} else {
			headers = me.getColumnHeaders(grid.headerCt.items);
		}

		return {
			columns: headers,
			groups: [simplifyGroup || group]
		};
	},

	simplifyGroupRows: function (group) {
		var rows = group.rows;
		if (rows && rows.length) {
			for (var i = 0, rowsLength = rows.length; i < rowsLength; i++) {
				var row = rows[i];
				for (var j = 0, columnsLength = row.length; j < columnsLength; j++) {
					var record = row[j];
					if (record && typeof record === 'object')
						rows[i][j] = record.Name;
				}
			}
		}
		return group;
	},

	getColumnHeaders: function (columns) {
		var cols = [],
			i, obj, col;
		for (i = 0; i < columns.length; i++) {
			col = columns.get(i);
			// each column has a config 'ignoreExport' that can tell us to ignore the column on export
			if (!col.ignoreExport) {
				obj = {
					text: col.text,
					hidden: col.hidden,
					width: col.width
				};
				if (col.isGroupHeader) {
					obj.columns = this.getColumnHeaders(col.items);
					if (obj.columns.length === 0) {
						// all children columns are ignored for export so there's no need to export this grouped header
						obj = null;
					}
				}
				if (obj) {
					cols.push(obj);
				}
			}
		}
		return cols;
	},
});

В методе simplifyGroupRows преобразовываем значения колонок, чтобы при эскпорте в них были обычные строковые значения. В getColumnHeaders берем свойства у колонок для того, чтобы их потом правильно отобразить в excel файле.

Результатом станет xml - файл со стилями подобными исходному гриду.

Нет комментариев

Добавить комментарий