@progress/kendo-angular-grid
Version:
Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.
214 lines (213 loc) • 8.88 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Component, Input, ContentChildren, QueryList, NgZone } from '@angular/core';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';
import { saveAs } from '@progress/kendo-file-saver';
import { toDataURL, workbookOptions, ColumnBase } from '@progress/kendo-angular-excel-export';
import { ExcelService } from './excel.service';
import { ExcelExportEvent } from './excel-export-event';
import { orderBy } from '@progress/kendo-data-query';
import { sortColumns } from '../columns/column-common';
import { ContextService } from '../common/provider.service';
import * as i0 from "@angular/core";
import * as i1 from "./excel.service";
import * as i2 from "../common/provider.service";
const fetchComponentData = (component) => {
return {
data: component.view.map(item => item),
group: component.group
};
};
const toExcelColumn = (column) => {
return {
title: column.title,
field: column.field,
locked: Boolean(column.locked),
width: column.width,
level: column.level,
hidden: !column.isVisible,
groupHeaderTemplate: column.groupHeaderTemplate,
groupHeaderColumnTemplate: column.groupHeaderColumnTemplate,
groupFooterTemplate: column.groupFooterTemplate,
footerTemplate: column.footerTemplate
};
};
const toExcelColumns = (columns) => {
const result = [];
sortColumns(columns)
.forEach((column) => {
if (column.isSpanColumn) {
result.push(...toExcelColumns(column.childrenArray));
}
else {
const excelColumn = toExcelColumn(column);
if (column.isColumnGroup) {
excelColumn.children = [excelColumn].concat(toExcelColumns(column.childrenArray));
}
result.push(excelColumn);
}
});
return result;
};
const componentColumns = (component) => {
const columns = toExcelColumns(component.columns.toArray());
return orderBy(columns, [{ field: 'locked', dir: 'desc' }]);
};
/**
* Configures the settings for the export of Grid in Excel ([see example]({% slug excelexport_grid %})).
*/
export class ExcelComponent {
ctx;
zone;
/**
* Specifies the file name of the exported Excel file.
* @default "Export.xlsx"
*/
fileName = 'Export.xlsx';
/**
* Enables or disables column filtering in the Excel file. This behavior is different from the filtering feature of the Grid.
*/
filterable;
/**
* The author of the workbook.
*/
creator;
/**
* The date on which the workbook was created. Defaults to `new Date()`.
*/
date;
/**
* If set to `true`, the content is forwarded to [proxyURL](#toc-proxyurl) even if the browser supports the saving of files locally.
*/
forceProxy;
/**
* The URL of the server-side proxy which streams the file to the end user.
*
* Using a proxy is required if the browser is not capable of saving files locally.
*
* Optionally, set up a proxy to reduce memory usage. This avoids copying the file contents in memory,
* but transmits it over the network instead. For this use case, set [forceProxy](#toc-forceproxy) to `true`
* to skip client-side saving even in browser that support it.
*
* In the request body, the proxy receives a POST request with the specific parameters. [See example](slug:server_proxy#toc-implementations).
* The proxy returns the decoded file with the `"Content-Disposition"` header set to `attachment; filename="<fileName.xslx>"`.
*
* For details on the server-side proxy usage and implementation, see the [File Saver]({% slug overview_filesaver %}) documentation.
*/
proxyURL;
/**
* The function that is used to get the exported data options. By default, uses the current data and group of the Grid.
* To export data that is different from the current Grid data, provide a custom function.
*/
fetchData;
/**
* If the data is grouped, the options of the cells that are inserted before the data,
* group, and footer cells to indicate the group hierarchy.
*/
paddingCellOptions;
/**
* If the data is grouped, the options of the cells that are inserted before the
* header cells to align the headers and the column values.
*/
headerPaddingCellOptions;
/**
* Specifies if the groups in the Excel file are collapsible.
*/
collapsible;
/**
* @hidden
*/
columns = new QueryList();
saveSubscription;
dataSubscription;
constructor(excelService, ctx, zone) {
this.ctx = ctx;
this.zone = zone;
this.saveSubscription = excelService.saveToExcel.subscribe(this.save.bind(this));
}
ngOnDestroy() {
this.saveSubscription.unsubscribe();
if (this.dataSubscription) {
this.dataSubscription.unsubscribe();
}
}
save(component) {
const data = (this.fetchData || fetchComponentData)(component);
const exportData = (result) => {
delete this.dataSubscription;
this.exportData(component, result);
};
if (data instanceof Promise) {
data.then(exportData);
}
else if (data instanceof Observable) {
this.dataSubscription = data.pipe(take(1)).subscribe(exportData);
}
else {
exportData(data);
}
}
exportData(component, result) {
const options = workbookOptions({
columns: this.columns.length ? this.columns : componentColumns(component),
data: result.data,
group: result.group,
filterable: this.filterable,
creator: this.creator,
date: this.date,
paddingCellOptions: this.paddingCellOptions,
headerPaddingCellOptions: this.headerPaddingCellOptions,
rtl: this.ctx.localization.rtl,
collapsible: this.collapsible
});
const args = new ExcelExportEvent(options);
component.excelExport.emit(args);
if (!args.isDefaultPrevented()) {
this.zone.runOutsideAngular(() => this.saveFile(options));
}
}
saveFile(options) {
toDataURL(options).then((dataURL) => {
saveAs(dataURL, this.fileName, {
forceProxy: this.forceProxy,
proxyURL: this.proxyURL
});
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ExcelComponent, deps: [{ token: i1.ExcelService }, { token: i2.ContextService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ExcelComponent, isStandalone: true, selector: "kendo-grid-excel", inputs: { fileName: "fileName", filterable: "filterable", creator: "creator", date: "date", forceProxy: "forceProxy", proxyURL: "proxyURL", fetchData: "fetchData", paddingCellOptions: "paddingCellOptions", headerPaddingCellOptions: "headerPaddingCellOptions", collapsible: "collapsible" }, queries: [{ propertyName: "columns", predicate: ColumnBase, descendants: true }], ngImport: i0, template: ``, isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ExcelComponent, decorators: [{
type: Component,
args: [{
selector: 'kendo-grid-excel',
template: ``,
standalone: true
}]
}], ctorParameters: function () { return [{ type: i1.ExcelService }, { type: i2.ContextService }, { type: i0.NgZone }]; }, propDecorators: { fileName: [{
type: Input
}], filterable: [{
type: Input
}], creator: [{
type: Input
}], date: [{
type: Input
}], forceProxy: [{
type: Input
}], proxyURL: [{
type: Input
}], fetchData: [{
type: Input
}], paddingCellOptions: [{
type: Input
}], headerPaddingCellOptions: [{
type: Input
}], collapsible: [{
type: Input
}], columns: [{
type: ContentChildren,
args: [ColumnBase, { descendants: true }]
}] } });