@@ -23,74 +23,97 @@ export interface SpreadsheetContent {
23
23
type : SpreadsheetType
24
24
}
25
25
26
- export interface SpreadsheetOptions {
26
+ export type SpreadsheetOptions = Partial < {
27
27
type : SpreadsheetType
28
- }
28
+ } >
29
29
30
30
export type Spreadsheet = {
31
+ (
32
+ data : Content ,
33
+ ) : {
34
+ csv : ( ) => SpreadsheetWrapper
35
+ excel : ( ) => SpreadsheetWrapper
36
+ store : ( path : string ) => Promise < void >
37
+ generateCSV : ( ) => SpreadsheetWrapper
38
+ generateExcel : ( ) => SpreadsheetWrapper
39
+ }
31
40
create : ( data : Content , options : SpreadsheetOptions ) => SpreadsheetContent
32
41
generate : ( data : Content , options : SpreadsheetOptions ) => string | Uint8Array
33
- generateCSV : ( content : Content ) => string | SpreadsheetWrapper
34
- generateExcel : ( content : Content ) => Uint8Array | SpreadsheetWrapper
42
+ generateCSV : ( content : Content ) => SpreadsheetWrapper
43
+ generateExcel : ( content : Content ) => SpreadsheetWrapper
35
44
store : ( spreadsheet : SpreadsheetContent , path : string ) => Promise < void >
36
45
download : ( spreadsheet : SpreadsheetContent , filename : string ) => Response
37
46
}
38
47
39
- export const spreadsheet : Spreadsheet = {
40
- generate : ( data : Content , options : SpreadsheetOptions = { type : 'csv' } ) : string | Uint8Array => {
41
- const generators : Record < SpreadsheetType , ( content : Content ) => string | Uint8Array | SpreadsheetWrapper > = {
42
- csv : spreadsheet . generateCSV ,
43
- excel : spreadsheet . generateExcel ,
44
- }
45
-
46
- const generator = generators [ options . type ]
47
-
48
- if ( ! generator ) {
49
- throw new Error ( `Unsupported spreadsheet type: ${ options . type } ` )
50
- }
51
-
52
- const result = generator ( data )
53
- if ( result instanceof SpreadsheetWrapper ) {
54
- return result . getContent ( )
55
- }
56
- return result
57
- } ,
58
-
59
- create : ( data : Content , options : SpreadsheetOptions = { type : 'csv' } ) : SpreadsheetContent => ( {
60
- content : spreadsheet . generate ( data , options ) ,
61
- type : options . type ,
48
+ export const spreadsheet : Spreadsheet = Object . assign (
49
+ ( data : Content ) => ( {
50
+ csv : ( ) => spreadsheet . generateCSV ( data ) ,
51
+ excel : ( ) => spreadsheet . generateExcel ( data ) ,
52
+ store : async ( path : string ) => {
53
+ const type = path . toLowerCase ( ) . endsWith ( '.csv' ) ? 'csv' : 'excel'
54
+ const content = spreadsheet . generate ( data , { type } )
55
+ await spreadsheet . store ( { content, type } , path )
56
+ } ,
57
+ generateCSV : ( ) => spreadsheet . generateCSV ( data ) ,
58
+ generateExcel : ( ) => spreadsheet . generateExcel ( data ) ,
62
59
} ) ,
63
-
64
- generateCSV : ( content : Content ) : string | SpreadsheetWrapper => {
65
- const csvContent = generateCSVContent ( content )
66
- return new SpreadsheetWrapper ( csvContent , 'csv' )
67
- } ,
68
-
69
- generateExcel : ( content : Content ) : Uint8Array | SpreadsheetWrapper => {
70
- const excelContent = generateExcelContent ( content )
71
- return new SpreadsheetWrapper ( excelContent , 'excel' )
72
- } ,
73
-
74
- store : async ( { content } : SpreadsheetContent , path : string ) : Promise < void > => {
75
- try {
76
- await Bun . write ( path , content )
77
- } catch ( error ) {
78
- throw new Error ( `Failed to store spreadsheet: ${ ( error as Error ) . message } ` )
79
- }
60
+ {
61
+ generate : ( data : Content , options : SpreadsheetOptions = { type : 'csv' } ) : string | Uint8Array => {
62
+ const generators : Record < SpreadsheetType , ( content : Content ) => string | Uint8Array | SpreadsheetWrapper > = {
63
+ csv : spreadsheet . generateCSV ,
64
+ excel : spreadsheet . generateExcel ,
65
+ }
66
+
67
+ const generator = generators [ options . type || 'csv' ]
68
+
69
+ if ( ! generator ) {
70
+ throw new Error ( `Unsupported spreadsheet type: ${ options . type } ` )
71
+ }
72
+
73
+ const result = generator ( data )
74
+ if ( result instanceof SpreadsheetWrapper ) {
75
+ return result . getContent ( )
76
+ }
77
+
78
+ return result
79
+ } ,
80
+
81
+ create : ( data : Content , options : SpreadsheetOptions = { type : 'csv' } ) : SpreadsheetContent => ( {
82
+ content : spreadsheet . generate ( data , options ) ,
83
+ type : options . type || 'csv' ,
84
+ } ) ,
85
+
86
+ generateCSV : ( content : Content ) : SpreadsheetWrapper => {
87
+ const csvContent = generateCSVContent ( content )
88
+ return new SpreadsheetWrapper ( csvContent , 'csv' )
89
+ } ,
90
+
91
+ generateExcel : ( content : Content ) : SpreadsheetWrapper => {
92
+ const excelContent = generateExcelContent ( content )
93
+ return new SpreadsheetWrapper ( excelContent , 'excel' )
94
+ } ,
95
+
96
+ store : async ( { content } : SpreadsheetContent , path : string ) : Promise < void > => {
97
+ try {
98
+ await Bun . write ( path , content )
99
+ } catch ( error ) {
100
+ throw new Error ( `Failed to store spreadsheet: ${ ( error as Error ) . message } ` )
101
+ }
102
+ } ,
103
+
104
+ download : ( { content, type } : SpreadsheetContent , filename : string ) : Response => {
105
+ const mimeType = type === 'csv' ? 'text/csv' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
106
+ const blob = new Blob ( [ content ] , { type : mimeType } )
107
+
108
+ return new Response ( blob , {
109
+ headers : {
110
+ 'Content-Type' : mimeType ,
111
+ 'Content-Disposition' : `attachment; filename="${ filename } "` ,
112
+ } ,
113
+ } )
114
+ } ,
80
115
} ,
81
-
82
- download : ( { content, type } : SpreadsheetContent , filename : string ) : Response => {
83
- const mimeType = type === 'csv' ? 'text/csv' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
84
- const blob = new Blob ( [ content ] , { type : mimeType } )
85
-
86
- return new Response ( blob , {
87
- headers : {
88
- 'Content-Type' : mimeType ,
89
- 'Content-Disposition' : `attachment; filename="${ filename } "` ,
90
- } ,
91
- } )
92
- } ,
93
- }
116
+ )
94
117
95
118
export class SpreadsheetWrapper {
96
119
constructor (
@@ -113,11 +136,13 @@ export class SpreadsheetWrapper {
113
136
114
137
export function createSpreadsheet ( data : Content , options : SpreadsheetOptions = { type : 'csv' } ) : SpreadsheetWrapper {
115
138
const content = spreadsheet . generate ( data , options )
116
- return new SpreadsheetWrapper ( content , options . type )
139
+
140
+ return new SpreadsheetWrapper ( content , options . type || 'csv' )
117
141
}
118
142
119
143
export function generateCSVContent ( content : Content ) : string {
120
144
const rows = [ content . headings , ...content . data ]
145
+
121
146
return rows . map ( ( row ) => row . join ( ',' ) ) . join ( '\n' )
122
147
}
123
148
0 commit comments