9
9
10
10
import * as XLSX from 'xlsx' ;
11
11
12
+ import * as utils from './utils' ;
13
+
12
14
export interface ConvertOptions {
13
15
anchor ?: ( string | HTMLAnchorElement ) ,
14
16
openAsDownload ?: boolean ,
@@ -31,147 +33,8 @@ export interface SheetOptions {
31
33
32
34
const ExcellentExport = function ( ) {
33
35
34
- const b64toBlob = function ( b64Data :string , contentType :string , sliceSize ?:number ) : Blob {
35
- // function taken from http://stackoverflow.com/a/16245768/2591950
36
- // author Jeremy Banks http://stackoverflow.com/users/1114/jeremy-banks
37
- contentType = contentType || '' ;
38
- sliceSize = sliceSize || 512 ;
39
-
40
- const byteCharacters = atob ( b64Data ) ;
41
- const byteArrays = [ ] ;
42
-
43
- for ( let offset = 0 ; offset < byteCharacters . length ; offset += sliceSize ) {
44
- const slice = byteCharacters . slice ( offset , offset + sliceSize ) ;
45
-
46
- const byteNumbers = new Array ( slice . length ) ;
47
- for ( let i = 0 ; i < slice . length ; i = i + 1 ) {
48
- byteNumbers [ i ] = slice . charCodeAt ( i ) ;
49
- }
50
-
51
- const byteArray = new Uint8Array ( byteNumbers ) ;
52
-
53
- byteArrays . push ( byteArray ) ;
54
- }
55
-
56
- return new Blob ( byteArrays , {
57
- type : contentType
58
- } ) ;
59
- } ;
60
-
61
36
const version = "3.7.2" ;
62
- const template = { excel : '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><meta name=ProgId content=Excel.Sheet> <meta name=Generator content="Microsoft Excel 11"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>' } ;
63
- let csvDelimiter = "," ;
64
- let csvNewLine = "\r\n" ;
65
-
66
- /**
67
- * Convert a string to Base64.
68
- */
69
- const base64 = function ( s :string ) : string {
70
- return btoa ( unescape ( encodeURIComponent ( s ) ) ) ;
71
- } ;
72
-
73
- const format = function ( s :string , context :any ) : string {
74
- return s . replace ( new RegExp ( "{(\\w+)}" , "g" ) , function ( m , p ) {
75
- return context [ p ] ;
76
- } ) ;
77
- } ;
78
-
79
- /**
80
- * Get element by ID.
81
- * @param {* } element
82
- */
83
- const getTable = function ( element :( HTMLTableElement | string ) ) : HTMLTableElement {
84
- if ( typeof element === 'string' ) {
85
- return document . getElementById ( element ) as HTMLTableElement ;
86
- }
87
- return element ;
88
- } ;
89
-
90
- /**
91
- * Get element by ID.
92
- * @param {* } element
93
- */
94
- const getAnchor = function ( element :( HTMLAnchorElement | string ) ) : HTMLAnchorElement {
95
- if ( typeof element === 'string' ) {
96
- return document . getElementById ( element ) as HTMLAnchorElement ;
97
- }
98
- return element ;
99
- } ;
100
-
101
- /**
102
- * Encode a value for CSV.
103
- * @param {* } value
104
- */
105
- const fixCSVField = function ( value ) {
106
- let fixedValue = value ;
107
- const addQuotes = ( value . indexOf ( csvDelimiter ) !== - 1 ) || ( value . indexOf ( '\r' ) !== - 1 ) || ( value . indexOf ( '\n' ) !== - 1 ) ;
108
- const replaceDoubleQuotes = ( value . indexOf ( '"' ) !== - 1 ) ;
109
37
110
- if ( replaceDoubleQuotes ) {
111
- fixedValue = fixedValue . replace ( / " / g, '""' ) ;
112
- }
113
- if ( addQuotes || replaceDoubleQuotes ) {
114
- fixedValue = '"' + fixedValue + '"' ;
115
- }
116
-
117
- return fixedValue ;
118
- } ;
119
-
120
- const tableToArray = function ( table :HTMLTableElement ) : any [ ] [ ] {
121
- let tableInfo = Array . prototype . map . call ( table . querySelectorAll ( 'tr' ) , function ( tr ) {
122
- return Array . prototype . map . call ( tr . querySelectorAll ( 'th,td' ) , function ( td ) {
123
- return td . innerHTML ;
124
- } ) ;
125
- } ) ;
126
- return tableInfo ;
127
- } ;
128
-
129
- const tableToCSV = function ( table :HTMLTableElement ) : string {
130
- let data = "" ;
131
- for ( let i = 0 ; i < table . rows . length ; i = i + 1 ) {
132
- const row = table . rows [ i ] ;
133
- for ( let j = 0 ; j < row . cells . length ; j = j + 1 ) {
134
- const col = row . cells [ j ] ;
135
- data = data + ( j ? csvDelimiter : '' ) + fixCSVField ( col . textContent . trim ( ) ) ;
136
- }
137
- data = data + csvNewLine ;
138
- }
139
- return data ;
140
- } ;
141
-
142
- const createDownloadLink = function ( anchor :HTMLAnchorElement , base64data :string , exporttype :string , filename :string ) : boolean {
143
- if ( window . navigator . msSaveBlob ) {
144
- const blob = b64toBlob ( base64data , exporttype ) ;
145
- window . navigator . msSaveBlob ( blob , filename ) ;
146
- return false ;
147
- } else if ( window . URL . createObjectURL ) {
148
- const blob = b64toBlob ( base64data , exporttype ) ;
149
- anchor . href = window . URL . createObjectURL ( blob ) ;
150
- } else {
151
- anchor . download = filename ;
152
- anchor . href = "data:" + exporttype + ";base64," + base64data ;
153
- }
154
-
155
- // Return true to allow the link to work
156
- return true ;
157
- } ;
158
-
159
- // String to ArrayBuffer
160
- const s2ab = function ( s :string ) : ArrayBuffer {
161
- let buf = new ArrayBuffer ( s . length ) ;
162
- let view = new Uint8Array ( buf ) ;
163
- for ( let i = 0 ; i !== s . length ; ++ i ) {
164
- view [ i ] = s . charCodeAt ( i ) & 0xFF ;
165
- }
166
- return buf ;
167
- } ;
168
-
169
- const removeColumn = function ( arr2d :any [ ] [ ] , colIndex :number ) {
170
- for ( let i = 0 ; i < arr2d . length ; i ++ ) {
171
- const row = arr2d [ i ] ;
172
- row . splice ( colIndex , 1 ) ;
173
- }
174
- } ;
175
38
176
39
/*
177
40
ExcellentExport.convert(options, sheets);
@@ -225,7 +88,7 @@ const ExcellentExport = function() {
225
88
// Select data source
226
89
let dataArray ;
227
90
if ( sheetConf . from && sheetConf . from . table ) {
228
- dataArray = tableToArray ( getTable ( sheetConf . from . table ) ) ;
91
+ dataArray = utils . tableToArray ( utils . getTable ( sheetConf . from . table ) ) ;
229
92
} else if ( sheetConf . from && sheetConf . from . array ) {
230
93
dataArray = sheetConf . from . array
231
94
} else {
@@ -242,10 +105,7 @@ const ExcellentExport = function() {
242
105
}
243
106
// Filter columns
244
107
if ( sheetConf . removeColumns ) {
245
- const toRemove = sheetConf . removeColumns . sort ( ) . reverse ( ) ;
246
- toRemove . forEach ( function ( columnIndex ) {
247
- removeColumn ( dataArray , columnIndex ) ;
248
- } ) ;
108
+ utils . removeColumns ( dataArray , sheetConf . removeColumns ) ;
249
109
}
250
110
251
111
// Convert data, by value
@@ -272,15 +132,15 @@ const ExcellentExport = function() {
272
132
273
133
const wbOut :string = XLSX . write ( workbook , { bookType : options . format , bookSST :true , type : 'binary' } ) ;
274
134
try {
275
- const blob = new Blob ( [ s2ab ( wbOut ) ] , { type : "application/octet-stream" } ) ;
135
+ const blob = new Blob ( [ utils . string2ArrayBuffer ( wbOut ) ] , { type : "application/octet-stream" } ) ;
276
136
const filename = ( options . filename || 'download' ) + '.' + options . format ;
277
137
// Support for IE.
278
138
if ( window . navigator . msSaveBlob ) {
279
139
window . navigator . msSaveBlob ( blob , filename ) ;
280
140
return false ;
281
141
}
282
142
if ( options . anchor ) {
283
- const anchor = getAnchor ( options . anchor ) ;
143
+ const anchor = utils . getAnchor ( options . anchor ) ;
284
144
anchor . href = window . URL . createObjectURL ( blob ) ;
285
145
anchor . download = filename ;
286
146
} else if ( options . openAsDownload ) {
@@ -306,25 +166,28 @@ const ExcellentExport = function() {
306
166
return version ;
307
167
} ,
308
168
excel : function ( anchor :( HTMLAnchorElement | string ) , table :HTMLTableElement , name :string ) {
309
- table = getTable ( table ) ;
310
- anchor = getAnchor ( anchor ) ;
169
+ table = utils . getTable ( table ) ;
170
+ anchor = utils . getAnchor ( anchor ) ;
311
171
const ctx = { worksheet : name || 'Worksheet' , table : table . innerHTML } ;
312
- const b64 = base64 ( format ( template . excel , ctx ) ) ;
313
- return createDownloadLink ( anchor , b64 , 'application/vnd.ms-excel' , 'export.xls' ) ;
172
+ const b64 = utils . base64 ( utils . format ( utils . templates . excel , ctx ) ) ;
173
+ return utils . createDownloadLink ( anchor , b64 , 'application/vnd.ms-excel' , 'export.xls' ) ;
314
174
} ,
315
175
csv : function ( anchor :( HTMLAnchorElement | string ) , table :HTMLTableElement , delimiter ?:string , newLine ?:string ) {
176
+ let csvDelimiter = "," ;
177
+ let csvNewLine = "\r\n" ;
178
+
316
179
if ( delimiter !== undefined && delimiter ) {
317
180
csvDelimiter = delimiter ;
318
181
}
319
182
if ( newLine !== undefined && newLine ) {
320
183
csvNewLine = newLine ;
321
184
}
322
185
323
- table = getTable ( table ) ;
324
- anchor = getAnchor ( anchor ) ;
325
- const csvData = "\uFEFF" + tableToCSV ( table ) ;
326
- const b64 = base64 ( csvData ) ;
327
- return createDownloadLink ( anchor , b64 , 'application/csv' , 'export.csv' ) ;
186
+ table = utils . getTable ( table ) ;
187
+ anchor = utils . getAnchor ( anchor ) ;
188
+ const csvData = "\uFEFF" + utils . tableToCSV ( table , csvDelimiter , csvNewLine ) ;
189
+ const b64 = utils . base64 ( csvData ) ;
190
+ return utils . createDownloadLink ( anchor , b64 , 'application/csv' , 'export.csv' ) ;
328
191
} ,
329
192
convert : function ( options :ConvertOptions , sheets :SheetOptions [ ] ) {
330
193
return convert ( options , sheets ) ;
0 commit comments