UNPKG

alasql

Version:

AlaSQL.js - JavaScript SQL database library for relational and graph data manipulation with support of localStorage, IndexedDB, and Excel

332 lines (278 loc) 8.9 kB
alasql.into.XLSXML = function(filename, opts, data, columns, cb) { // If filename is not defined then output to the result if(typeof filename == 'object') { opts = filename; filename = undefined; } // Set sheets var sheets = {}; if(opts && opts.sheets) { sheets = opts.sheets; } else { sheets.Sheet1 = opts; }; // File is ready to save var res = alasql.utils.saveFile(filename,toXML()); if(cb) res = cb(res); return res; function toXML() { var s1 = '<?xml version="1.0"?> \ <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" \ xmlns:o="urn:schemas-microsoft-com:office:office" \ xmlns:x="urn:schemas-microsoft-com:office:excel" \ xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" \ xmlns:html="http://www.w3.org/TR/REC-html40"> \ <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> \ </DocumentProperties> \ <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office"> \ <AllowPNG/> \ </OfficeDocumentSettings> \ <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"> \ <ActiveSheet>0</ActiveSheet> \ </ExcelWorkbook> \ <Styles> \ <Style ss:ID="Default" ss:Name="Normal"> \ <Alignment ss:Vertical="Bottom"/> \ <Borders/> \ <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#000000"/> \ <Interior/> \ <NumberFormat/> \ <Protection/> \ </Style>'; var s2 = ''; // for styles var s3 = ' </Styles>'; var styles = {}; // hash based storage for styles var stylesn = 62; // First style // Generate style function hstyle(st) { // Prepare string var s = ''; for(var key in st) { s += '<'+key; for(var attr in st[key]) { s += ' '; if(attr.substr(0,2) == 'x:') { s += attr; } else { s += 'ss:'; } s += attr+'="'+st[key][attr]+'"'; } s += '/>'; } var hh = hash(s); // Store in hash if(styles[hh]) { } else { styles[hh] = {styleid:stylesn}; s2 += '<Style ss:ID="s'+stylesn+'">'; s2 += s; s2 += '</Style>'; stylesn++; } return 's'+styles[hh].styleid; } for (var sheetid in sheets) { var sheet = sheets[sheetid]; // If columns defined in sheet, then take them if(typeof sheet.columns != 'undefined') { columns = sheet.columns; } else { // Autogenerate columns if they are passed as parameters if(columns.length == 0 && data.length > 0) { if(typeof data[0] == 'object') { if(data[0] instanceof Array) { columns = data[0].map(function(d,columnidx){ return {columnid:columnidx}; }); } else { columns = Object.keys(data[0]).map(function(columnid){ return {columnid:columnid}; }); } } } }; // Prepare columns columns.forEach(function(column,columnidx){ if(typeof sheet.column != 'undefined') { extend(column,sheet.column); } if(typeof column.width == 'undefined') { if(sheet.column && (typeof sheet.column.width !='undefined')) { column.width = sheet.column.width; } else { column.width = 120; } } if(typeof column.width == 'number') column.width = column.width; if(typeof column.columnid == 'undefined') column.columnid = columnidx; if(typeof column.title == 'undefined') column.title = ""+column.columnid; if(sheet.headers && sheet.headers instanceof Array) column.title = sheet.headers[idx]; }); // Header s3 +='<Worksheet ss:Name="'+sheetid+'"> \ <Table ss:ExpandedColumnCount="'+columns.length +'" ss:ExpandedRowCount="'+((sheet.headers?1:0)+Math.min(data.length,sheet.limit||data.length)) +'" x:FullColumns="1" \ x:FullRows="1" ss:DefaultColumnWidth="65" ss:DefaultRowHeight="15">'; columns.forEach(function (column,columnidx) { s3 += '<Column ss:Index="'+(columnidx+1) +'" ss:AutoFitWidth="0" ss:Width="'+column.width+'"/>' }); // Headers if(sheet.headers) { s3 += '<Row ss:AutoFitHeight="0">'; // TODO: Skip columns to body // Headers columns.forEach(function (column,columnidx) { s3 += '<Cell '; if(typeof column.style != 'undefined') { var st = {}; if(typeof column.style == 'function') { extend(st,column.style(sheet,column,columnidx)); } else { extend(st,column.style); } s3 += 'ss:StyleID="'+hstyle(st)+'"'; } s3 += '><Data ss:Type="String">'; // Column title if(typeof column.title != 'undefined') { if(typeof column.title == 'function') { s3 += column.title(sheet,column,columnidx); } else { s3 += column.title; } } s3 += '</Data></Cell>'; }); s3 += '</Row>'; }; // Data if(data && data.length > 0) { // Loop over data rows data.forEach(function(row,rowidx){ // Limit number of rows on the sheet if(rowidx>sheet.limit) return; // Extend row properties var srow = {}; extend(srow,sheet.row); if(sheet.rows && sheet.rows[rowidx]) { extend(srow,sheet.rows[rowidx]); } s3 += '<Row '; // Row style fromdefault sheet if(typeof srow != 'undefined') { var st = {}; if(typeof srow.style != 'undefined') { if(typeof srow.style == 'function') { extend(st,srow.style(sheet,row,rowidx)); } else { extend(st,srow.style); } s3 += 'ss:StyleID="'+hstyle(st)+'"'; } }; s3 += '>';//'ss:AutoFitHeight="0">' // Data columns.forEach(function (column,columnidx) { // Parameters var cell = {}; extend(cell,sheet.cell); extend(cell,srow.cell); if(typeof sheet.column != 'undefined') { extend(cell,sheet.column.cell); } extend(cell,column.cell); if(sheet.cells && sheet.cells[rowidx] && sheet.cells[rowidx][columnidx]) { extend(cell,sheet.cells[rowidx][columnidx]); }; // Create value var value = row[column.columnid]; if(typeof cell.value == 'function') { value = cell.value(value,sheet,row,column,cell,rowidx,columnidx); } // Define cell type var typeid = cell.typeid; if(typeof typeid == 'function') { typeid = typeid(value,sheet,row,column,cell,rowidx,columnidx); } if(typeof typeid == 'undefined') { if(typeof value == 'number') typeid = 'number'; else if(typeof value == 'string') typeid = 'string'; else if(typeof value == 'boolean') typeid = 'boolean'; else if(typeof value == 'object') { if(value instanceof Date) typeid = 'date'; } }; var Type = 'String'; if(typeid == 'number') Type = 'Number'; else if(typeid == 'date') Type = 'Date'; // TODO: What else? // Prepare Data types styles var typestyle = ''; if(typeid == 'money') { typestyle = 'mso-number-format:\"\\#\\,\\#\\#0\\\\ _р_\\.\";white-space:normal;'; } else if(typeid == 'number') { typestyle = ' '; } else if (typeid == 'date') { typestyle = 'mso-number-format:\"Short Date\";'; } else { // FOr other types is saved if( opts.types && opts.types[typeid] && opts.types[typeid].typestyle) { typestyle = opts.types[typeid].typestyle; } } // TODO Replace with extend... typestyle = typestyle || 'mso-number-format:\"\\@\";'; // Default type style s3 += '<Cell '; if(false) { s += "<td style='" + typestyle+"' " ; } // Row style fromdefault sheet var st = {}; if(typeof cell.style != 'undefined') { if(typeof cell.style == 'function') { extend(st,cell.style(value,sheet,row,column,rowidx,columnidx)); } else { extend(st,cell.style); } s3 += 'ss:StyleID="'+hstyle(st)+'"'; } s3 += '>'; s3+='<Data ss:Type="'+Type+'">'; // TODO Replace with extend... var format = cell.format; if(typeof value == 'undefined') { s3 += ''; } else if(typeof format != 'undefined') { if(typeof format == 'function') { s3 += format(value); } else if(typeof format == 'string') { s3 += value; // TODO - add string format } else { throw new Error('Unknown format type. Should be function or string'); } } else { if(typeid == 'number' || typeid == 'date') { s3 += value.toString(); } else if(typeid == 'money') { s3 += (+value).toFixed(2); } else { s3 += value; } } // s3 += row[column.columnid]; s3 += '</Data></Cell>'; }); s3 += '</Row>'; }); } // Finish s3 += '</Table></Worksheet>'; }; s3 +='</Workbook>'; return s1+s2+s3; }; };