@@ -27,30 +27,75 @@ ExcelHandler.prototype.read = function(file, callback) {
2727
2828// Export data to excel
2929ExcelHandler . prototype . write = function ( data , fileName ) {
30- fileName = fileName || 'Pipeline.xlsx' ;
31- function s2ab ( s ) {
32- var buf = new ArrayBuffer ( s . length ) ;
33- var view = new Uint8Array ( buf ) ;
34- for ( var i = 0 ; i != s . length ; ++ i ) view [ i ] = s . charCodeAt ( i ) & 0xFF ;
35- return buf ;
36- }
37- const wb = XLSX . utils . book_new ( ) ;
38- for ( let sheetName in data ) {
39- const ws = XLSX . utils . aoa_to_sheet ( data [ sheetName ] ) ;
40- XLSX . utils . book_append_sheet ( wb , ws , sheetName ) ;
41- }
42- // const ws = XLSX.utils.aoa_to_sheet(data['Reference']);
43- // XLSX.utils.book_append_sheet(wb, ws, 'Reference');
44-
45- const fileContent = XLSX . write ( wb , { bookType :'xlsx' , bookSST :true , type : 'binary' } ) ;
46- let link = document . createElement ( "A" ) ;
47- const blob = new Blob ( [ s2ab ( fileContent ) ] , { type :"" } )
48- link . href = window . URL . createObjectURL ( blob ) ;
49- link . download = fileName ;
50- link . target = '_blank' ;
51- document . body . appendChild ( link ) ;
52- link . click ( ) ;
53- document . body . removeChild ( link ) ;
30+ const self = this ;
31+ fileName = fileName || 'Pipeline' ;
32+ XlsxPopulate
33+ . fromBlankAsync ( )
34+ . then ( function ( workbook ) {
35+ // Create sheets
36+ workbook . sheet ( 0 ) . name ( 'Metadata' ) ;
37+ workbook . addSheet ( 'Reference' ) ;
38+ for ( let sheetName in data ) {
39+ const sheet = workbook . sheet ( sheetName ) ;
40+ let columnCount = 0 ;
41+ let lineCount = 0 ;
42+ for ( let l = 0 ; l < data [ sheetName ] . length ; l ++ ) {
43+ let line = data [ sheetName ] [ l ] ;
44+ let styles = {
45+ 'border' : {
46+ top : { style : "thin" } ,
47+ left : { style : "thin" } ,
48+ bottom : { style : "thin" } ,
49+ right : { style : "thin" }
50+ } ,
51+ 'wrapText' : true } ;
52+ if ( l == 0 ) {
53+ lineCount = data [ sheetName ] . length ;
54+ columnCount = line . length ;
55+ }
56+ for ( let c = 0 ; c < line . length ; c ++ ) {
57+ // l0-c0 to A1, l0-c1 to B1
58+ let val = line [ c ] ;
59+ let cellNo = String . fromCharCode ( 65 + c ) + ( l + 1 ) ;
60+ sheet . cell ( cellNo ) . value ( val ) . style ( styles ) ;
61+ if ( l == 0 ) {
62+ let fillStyle = ( c < 3 ) ? { 'fill' : '4285f4' } : { 'fill' : 'a5a5a5' } ;
63+ sheet . cell ( cellNo ) . style ( fillStyle ) ;
64+ } else {
65+ if ( c == 4 && val . length > 0 ) {
66+ sheet . cell ( cellNo ) . value ( moment ( val ) . format ( 'YYYY/MM/DD HH:mm' ) )
67+ }
68+ }
69+ }
70+ }
71+ // Rejust cell width to fit data
72+ for ( let c = 0 ; c < columnCount ; c ++ ) {
73+ let cellChar = String . fromCharCode ( 65 + c ) ;
74+ // A1:A20
75+ const maxLength = sheet . range ( cellChar + '1:' + cellChar + lineCount )
76+ . reduce ( function ( max , cell ) {
77+ const value = cell . value ( ) ;
78+ if ( value === undefined ) return max ;
79+ // set length to 2x if has japanese string
80+ const vLen = self . getBytes ( value . toString ( ) ) ;
81+ return Math . max ( max , vLen ) ;
82+ } , 0 ) ;
83+ sheet . column ( cellChar ) . width ( maxLength + 5 ) ;
84+ }
85+ }
86+ return workbook . outputAsync ( ) ;
87+ } )
88+ . then ( function ( blob ) {
89+ let link = document . createElement ( 'A' ) ;
90+ //const blob = new Blob([s2ab(fileContent)],{type:""})
91+ link . href = window . URL . createObjectURL ( blob ) ;
92+ link . download = fileName + '.xlsx' ; ;
93+ link . target = '_blank' ;
94+ document . body . appendChild ( link ) ;
95+ link . click ( ) ;
96+ document . body . removeChild ( link ) ;
97+ } ) ;
98+
5499}
55100
56101// Read and convert xlsx to json
@@ -112,4 +157,17 @@ ExcelHandler.prototype.handleCodePoints = function(array) {
112157 index += CHUNK_SIZE ;
113158 }
114159 return result ;
160+ }
161+ // 'abcde' → 5, 'あいうえお' → 10
162+ ExcelHandler . prototype . getBytes = function ( txt ) {
163+ var length = 0 ;
164+ for ( var i = 0 ; i < txt . length ; i ++ ) {
165+ var c = txt . charCodeAt ( i ) ;
166+ if ( ( c >= 0x0 && c < 0x81 ) || ( c === 0xf8f0 ) || ( c >= 0xff61 && c < 0xffa0 ) || ( c >= 0xf8f1 && c < 0xf8f4 ) ) {
167+ length += 1 ;
168+ } else {
169+ length += 2 ;
170+ }
171+ }
172+ return length ;
115173}
0 commit comments