UNPKG

8.16 kBPlain TextView Raw
1import {Bean, Autowired, PostConstruct} from "./context/context";
2import {
3 GridSerializer, RowAccumulator, BaseGridSerializingSession, RowSpanningAccumulator,
4 GridSerializingSession
5} from "./gridSerializer";
6import {Downloader} from "./downloader";
7import {Column} from "./entities/column";
8import {RowNode} from "./entities/rowNode";
9import {ColumnController} from "./columnController/columnController";
10import {ValueService} from "./valueService/valueService";
11import {GridOptionsWrapper} from "./gridOptionsWrapper";
12import {
13 BaseExportParams, CsvExportParams, ExportParams, ProcessCellForExportParams,
14 ProcessHeaderForExportParams
15} from "./exportParams";
16import {Constants} from "./constants";
17import {_} from "./utils";
18
19let LINE_SEPARATOR = '\r\n';
20
21export class CsvSerializingSession extends BaseGridSerializingSession<string> {
22 private result:string = '';
23 private lineOpened:boolean = false;
24
25 constructor(
26 columnController: ColumnController,
27 valueService: ValueService,
28 gridOptionsWrapper: GridOptionsWrapper,
29 processCellCallback:(params: ProcessCellForExportParams)=>string,
30 processHeaderCallback:(params: ProcessHeaderForExportParams)=>string,
31 private suppressQuotes: boolean,
32 private columnSeparator: string
33 ){
34 super(columnController, valueService, gridOptionsWrapper, processCellCallback, processHeaderCallback);
35 }
36
37 public prepare(columnsToExport: Column[]): void {
38 }
39
40 public addCustomHeader(customHeader: string): void {
41 if (!customHeader) return;
42 this.result += customHeader + LINE_SEPARATOR;
43 }
44
45 public addCustomFooter(customFooter: string): void {
46 if (!customFooter) return;
47 this.result += customFooter + LINE_SEPARATOR;
48 }
49
50 public onNewHeaderGroupingRow(): RowSpanningAccumulator {
51 if(this.lineOpened) this.result += LINE_SEPARATOR;
52
53 return {
54 onColumn: this.onNewHeaderGroupingRowColumn.bind(this)
55 };
56 }
57
58 private onNewHeaderGroupingRowColumn (header: string, index: number, span:number) {
59 if (index != 0) {
60 this.result += this.columnSeparator;
61 }
62
63 this.result += header;
64 for (let i = 1; i<= span; i++){
65 this.result += this.columnSeparator + this.putInQuotes("", this.suppressQuotes);
66 }
67 this.lineOpened = true;
68 }
69
70 public onNewHeaderRow(): RowAccumulator {
71 if(this.lineOpened) this.result += LINE_SEPARATOR;
72
73 return {
74 onColumn:this.onNewHeaderRowColumn.bind(this)
75 };
76 }
77
78 private onNewHeaderRowColumn(column: Column, index: number, node?:RowNode):void{
79 if (index != 0) {
80 this.result += this.columnSeparator;
81 }
82 this.result += this.putInQuotes(this.extractHeaderValue(column), this.suppressQuotes);
83 this.lineOpened = true;
84 }
85
86 public onNewBodyRow(): RowAccumulator {
87 if(this.lineOpened) this.result += LINE_SEPARATOR;
88
89 return {
90 onColumn: this.onNewBodyRowColumn.bind(this)
91 };
92 }
93
94 private onNewBodyRowColumn (column: Column, index: number, node?:RowNode):void{
95 if (index != 0) {
96 this.result += this.columnSeparator;
97 }
98 this.result += this.putInQuotes(this.extractRowCellValue(column, index, Constants.EXPORT_TYPE_CSV, node), this.suppressQuotes);
99 this.lineOpened = true;
100 }
101
102
103 private putInQuotes(value: any, suppressQuotes: boolean): string {
104 if (suppressQuotes) { return value; }
105
106 if (value === null || value === undefined) {
107 return '""';
108 }
109
110 let stringValue: string;
111 if (typeof value === 'string') {
112 stringValue = value;
113 } else if (typeof value.toString === 'function') {
114 stringValue = value.toString();
115 } else {
116 console.warn('unknown value type during csv conversion');
117 stringValue = '';
118 }
119
120 // replace each " with "" (ie two sets of double quotes is how to do double quotes in csv)
121 let valueEscaped = stringValue.replace(/"/g, "\"\"");
122
123 return '"' + valueEscaped + '"';
124 }
125
126 public parse(): string {
127 return this.result;
128 }
129}
130
131export interface BaseCreatorBeans {
132 downloader: Downloader;
133 gridSerializer: GridSerializer;
134 gridOptionsWrapper: GridOptionsWrapper;
135}
136
137export abstract class BaseCreator<T, S extends GridSerializingSession<T>, P extends ExportParams<T>> {
138
139 private beans: BaseCreatorBeans;
140
141 protected setBeans(beans: BaseCreatorBeans) {
142 this.beans = beans;
143 }
144
145 public export(userParams?: P): string {
146 if (this.isExportSuppressed()){
147 console.warn(`ag-grid: Export canceled. Export is not allowed as per your configuration.`);
148 return "";
149 }
150 let {mergedParams, data} = this.getMergedParamsAndData(userParams);
151
152 let fileNamePresent = mergedParams && mergedParams.fileName && mergedParams.fileName.length !== 0;
153 let fileName = fileNamePresent ? mergedParams.fileName : this.getDefaultFileName();
154
155 if (fileName.indexOf(".") === -1){
156 fileName = fileName + "." + this.getDefaultFileExtension();
157 }
158
159 this.beans.downloader.download(
160 fileName,
161 data,
162 this.getMimeType()
163 );
164 return data;
165 }
166
167 public getData (params:P):string{
168 return this.getMergedParamsAndData(params).data
169 }
170
171 private getMergedParamsAndData(userParams: P):{mergedParams:P, data:string} {
172 let mergedParams = this.mergeDefaultParams(userParams);
173 let data = this.beans.gridSerializer.serialize(this.createSerializingSession(mergedParams), mergedParams);
174 return {mergedParams, data};
175 }
176
177 private mergeDefaultParams(userParams: P):P {
178 let baseParams: BaseExportParams = this.beans.gridOptionsWrapper.getDefaultExportParams();
179 let params: P = <any>{};
180 _.assign(params, baseParams);
181 _.assign(params, userParams);
182 return params;
183 }
184 public abstract createSerializingSession(params?: P):S;
185 public abstract getMimeType():string;
186 public abstract getDefaultFileName ():string;
187 public abstract getDefaultFileExtension ():string;
188 public abstract isExportSuppressed ():boolean;
189}
190
191@Bean('csvCreator')
192export class CsvCreator extends BaseCreator<string, CsvSerializingSession, CsvExportParams>{
193
194 @Autowired('columnController') private columnController: ColumnController;
195 @Autowired('valueService') private valueService: ValueService;
196
197 @Autowired('downloader') private downloader: Downloader;
198 @Autowired('gridSerializer') private gridSerializer: GridSerializer;
199 @Autowired('gridOptionsWrapper') gridOptionsWrapper: GridOptionsWrapper;
200
201 @PostConstruct
202 public postConstruct(): void {
203 this.setBeans({
204 downloader: this.downloader,
205 gridSerializer: this.gridSerializer,
206 gridOptionsWrapper: this.gridOptionsWrapper
207 });
208 }
209
210 public exportDataAsCsv(params?: CsvExportParams): string {
211 return this.export(params);
212 }
213
214 public getDataAsCsv (params?: CsvExportParams): string {
215 return this.getData(params);
216 }
217
218
219 public getMimeType(): string {
220 return "text/csv;charset=utf-8;"
221 }
222
223 public getDefaultFileName(): string {
224 return 'export.csv';
225 }
226
227 public getDefaultFileExtension(): string {
228 return 'csv';
229 }
230
231 public createSerializingSession(params?:CsvExportParams): CsvSerializingSession{
232 return new CsvSerializingSession(
233 this.columnController,
234 this.valueService,
235 this.gridOptionsWrapper,
236 params ? params.processCellCallback : null,
237 params ? params.processHeaderCallback : null,
238 params && params.suppressQuotes,
239 (params && params.columnSeparator) || ','
240 )
241 }
242
243 public isExportSuppressed ():boolean{
244 return this.gridOptionsWrapper.isSuppressCsvExport();
245 }
246}