diff -r 13555c27b592 -r 5b6d7b640e52 www-thermferm/jqwidgets/jqxexport.js --- a/www-thermferm/jqwidgets/jqxexport.js Thu Apr 25 14:26:47 2024 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3495 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -(function ($) { - window.jqxToDash = function(value) { - return value.split(/(?=[A-Z])/).join('-').toLowerCase(); - } - - class DataExporter { - constructor(exportDetails, groupBy, filterBy, conditionalFormatting) { - const that = this; - - if (!exportDetails) { - exportDetails = {}; - } - - /* - * "style" object definition (all properties are optional): - * - * «any valid CSS property» - applied to whole table - * header (Object) - * «any valid CSS property» - applied to header cells - * «any column name» (Object) - * «any valid CSS property» - applied to particular column header cell - * columns (Object) - * «any valid CSS property» - applied to column cells - * «any column name» (Object) - * «any valid CSS property» - applied to the cells of particular column - * format - applicable to numeric and date columns - * «n» (Object), where «n» is a row index (related to use of "ConditionalFormatting" object) - * background - * border - * color - * rows (Object) - * «any valid CSS property» - applied to rows - * alternationCount - * alternationStart - * alternationEnd - * alternationIndex«n»Color, where «n» is an integer - * alternationIndex«n»BorderColor, where «n» is an integer - * alternationIndex«n»BackgroundColor, where «n» is an integer - * «n» (Object), where «n» is a row index - * «any valid CSS property» - applied to particular row - */ - that.style = exportDetails.style; - - that.header = exportDetails.header; - that.exportHeader = exportDetails.exportHeader || true; - that.hierarchical = exportDetails.hierarchical; - that.expandChar = exportDetails.expandChar || '+'; - that.collapseChar = exportDetails.collapseChar || '-'; - that.pageOrientation = exportDetails.pageOrientation; - - if (!that.hierarchical && groupBy && groupBy.length > 0) { - that.groupBy = groupBy; - } - else { - that.mergedCells = exportDetails.mergedCells; - } - - if (!that.groupBy && filterBy && Object.keys(filterBy).length > 0) { - that.filterBy = filterBy; - } - - if (conditionalFormatting) { - that.conditionalFormatting = conditionalFormatting; - } - - that.timeBetween1900And1970 = new Date(1970, 0, 1).getTime() - new Date(1900, 0, 1).getTime(); - } - - /** - * Generates and downloads a file. - */ - downloadFile(data, type, fileName) { - let file; - - if (!fileName) { - return data; - } - - if (data instanceof Blob) { - file = data; - } - else { - file = new Blob([data], { type: type }); - } - - if (window.navigator.msSaveOrOpenBlob) { // Edge - window.navigator.msSaveOrOpenBlob(file, fileName); - } - else { // Chrome, Firefox, Safari - const a = document.createElement('a'), - url = URL.createObjectURL(file); - - a.href = url; - a.download = fileName; - a.style.position = 'absolute'; - a.style.visibility = 'hidden'; - - document.body.appendChild(a); - - a.click(); - - setTimeout(function () { - document.body.removeChild(a); - window.URL.revokeObjectURL(url); - }, 0); - } - } - - /** - * Exports data. - */ - exportData(data, format, fileName, callback) { - const that = this; - - that.actualHierarchy = that.hierarchical; - format = format.toLowerCase(); - - if (that.exportHeader) { - if (that.header) { - data = data.slice(0); - - if (data.length === 0) { - that.actualHierarchy = false; - } - - that.processComplexHeader(that.header, data, format); - } - else if (data.length === 1) { - that.actualHierarchy = false; - } - } - - if (data.length === 0) { - // eslint-disable-next-line - console.warn('No data to export.'); - return; - } - - if (format === 'xlsx') { - that.xlsxStartIndex = that.complexHeader ? that.complexHeader.length : +that.exportHeader; - } - - if (that.actualHierarchy) { - data = that.processHierarchicalData(data, format); - } - - that.getDatafields(data); - - if (fileName && fileName.slice(fileName.length - format.length - 1, fileName.length) !== '.' + format) { - fileName += '.' + format; - } - - let output = null; - switch (format) { - case 'csv': - output = that.exportToCSVAndTSV(data, { delimiter: ', ', MIME: 'text/csv', toRemove: 2 }, fileName); - break; - case 'html': - output = that.exportToHTML(data, fileName); - break; - case 'jpeg': - case 'png': - that.exportToImage(data, fileName, format, callback); - break; - case 'json': - output = that.exportToJSON(data, fileName); - break; - case 'pdf': - output = that.exportToPDF(data, fileName); - break; - case 'tsv': - output = that.exportToCSVAndTSV(data, { delimiter: '\t', MIME: 'text/tab-separated-values', toRemove: 1 }, fileName); - break; - case 'xlsx': - output = that.exportToXLSX(data, fileName); - break; - case 'xml': - output = that.exportToXML(data, fileName); - break; - } - - if (callback && output) { - callback(output); - } - - delete that.complexHeader; - - return output; - } - - /** - * Exports to CSV and TSV. - */ - exportToCSVAndTSV(data, formatOptions, fileName) { - const that = this, - datafields = that.datafields; - let stringResult = ''; - - for (let i = 0; i < data.length; i++) { - const currentRecord = data[i]; - let stringifiedCurrentRecord = ''; - - for (let j = 0; j < datafields.length; j++) { - if (that.actualHierarchy && j === 0) { - stringifiedCurrentRecord += ('""' + formatOptions.delimiter).repeat(currentRecord._level - 1) + - '"' + currentRecord[datafields[j]] + '"' + formatOptions.delimiter + - ('""' + formatOptions.delimiter).repeat(that.maxLevel - currentRecord._level); - continue; - } - - stringifiedCurrentRecord += '"' + currentRecord[datafields[j]] + '"' + formatOptions.delimiter; - } - - stringifiedCurrentRecord = stringifiedCurrentRecord.slice(0, stringifiedCurrentRecord.length - formatOptions.toRemove) + '\n'; - stringResult += stringifiedCurrentRecord; - } - - return this.downloadFile(stringResult, formatOptions.MIME, fileName); - } - - /** - * Exports to HTML. - */ - exportToHTML(data, fileName) { - const that = this, - datafields = that.datafields, - style = that.style; - let header = '', - startIndex = 0, - html2canvas = ''; - - data = that.processGroupingInformation(data); - that.data = data; - - if (that.exportHeader) { - header = that.getHTMLHeader(datafields, data); - startIndex = 1; - } - - if (arguments[2]) { - const scripts = Array.from(document.getElementsByTagName('script')), - html2canvasScript = scripts.find(script => script.src.indexOf('html2canvas') !== -1); - html2canvas = ``; - } - - let htmlContent = ` - - - - ${html2canvas}${that.toggleableFunctionality()} - - - ${header} - \n`; - - const mergedMainCells = {}, - mergedSecondaryCells = {}, - groupsHandled = []; - - that.getMergedCellsInfo(mergedMainCells, mergedSecondaryCells); - - mainLoop: - for (let i = startIndex; i < data.length; i++) { - const currentRecord = data[i], - row = i - startIndex; - let n = that.getAlternationIndex(row, ' rowN'), - toCollapse = '', - level = '', - groupId = '', - outlineLevel = 0; - - if (that.actualHierarchy) { - if (currentRecord._collapsed) { - toCollapse = ' collapsed'; - } - - level = ` level="${currentRecord._level}"`; - } - else if (that.groupBy) { - for (let k = 0; k < that.groupBy.length; k++) { - const datafield = that.groupBy[k], - currentGroup = currentRecord[datafield], - currentGroupLabel = that.groups[datafield][currentGroup]; - - groupId += currentGroup; - - if (groupsHandled.indexOf(groupId) === -1) { - htmlContent += ` - ${currentGroupLabel} - `; - groupsHandled.push(groupId); - i--; - continue mainLoop; - } - - outlineLevel++; - } - } - - let currentContent = ` ${sign}`; - } - - value = that.getFormattedValue(value, datafield); - - let css = ''; - - if (style && style.columns && style.columns[datafield] && style.columns[datafield][row]) { - const uniqueStyle = style.columns[datafield][row]; - - css += `border-color: ${uniqueStyle.border}; background-color: ${uniqueStyle.background}; color: ${uniqueStyle.color};"`; - } - - if (j === 0 && outlineLevel > 1) { - css += `padding-left: ${(outlineLevel - 1) * 25}px;"`; - } - - if (css) { - css = ` style="${css}"`; - } - - currentContent += ` ${indent + value}\n`; - } - - htmlContent += currentContent + ' \n'; - } - - htmlContent += ` - - -`; - - if (arguments[2]) { - return htmlContent; - } - - return this.downloadFile(htmlContent, 'text/html', fileName); - } - - /** - * Exports to an image (PNG/JPEG). - */ - exportToImage(data, fileName, fileExtension, callback) { - const that = this; - - try { - html2canvas; - } - catch (error) { - throw new Error('jqx-grid: Missing reference to \'html2canvas.min.js\'.'); - } - - let imageData = null; - - const htmlContent = that.exportToHTML(data, fileName, true), - iframe = document.createElement('iframe'); - - iframe.style.position = 'absolute'; - iframe.style.top = 0; - iframe.style.left = 0; - iframe.style.border = 'none'; - iframe.style.width = '100%'; - iframe.style.height = '100%'; - iframe.style.opacity = 0; - - document.body.appendChild(iframe); - - iframe.contentDocument.write(htmlContent); - - function checkIframePopulated() { - if (!iframe.contentDocument.body || !iframe.contentDocument.body.firstElementChild) { - requestAnimationFrame(checkIframePopulated); - } - else { - iframe.contentWindow.html2canvas(iframe.contentDocument.body.firstElementChild).then(canvas => { - const draw = $.jqxDraw(document.createElement('div')); - - imageData = canvas.toDataURL('image/png'); - - if (callback) { - callback(imageData); - } - else { - document.body.appendChild(canvas); - draw.exportImage(undefined, canvas, fileExtension, fileName); - } - - iframe.remove(); - canvas.remove(); - }); - } - } - - checkIframePopulated(); - - return imageData; - } - - /** - * Gets merged cells information (for use in HTML and PDF export). - */ - getMergedCellsInfo(mergedMainCells, mergedSecondaryCells, mapping) { - const that = this; - - if (!that.mergedCells) { - return; - } - - const multipleTables = mapping && mapping[that.datafields.length - 1] !== 0; - - that.mergedCellsPDF = that.mergedCells.slice(0); - - for (let i = 0; i < that.mergedCellsPDF.length; i++) { - const cellDefinition = that.mergedCellsPDF[i]; - let colspan = cellDefinition.colspan, - rowspan = cellDefinition.rowspan; - - if (rowspan < 2 && colspan < 2) { - continue; - } - - const row = cellDefinition.cell[1]; - let col = cellDefinition.cell[0]; - - if (multipleTables && colspan > 1) { - const startTable = mapping[col], - endTable = mapping[col + colspan - 1], - splitCells = []; - - if (endTable > startTable) { - let currentTable = startTable, - currentColumn = col, - overal = 0; - - mainLoop: - for (let i = startTable; i <= endTable; i++) { - let start = currentColumn, - span = 0; - - while (mapping[currentColumn] === currentTable) { - currentColumn++; - overal++; - span++; - - if (overal === colspan) { - splitCells.push({ start: start, span: span }); - break mainLoop; - } - } - - splitCells.push({ start: start, span: span }); - currentTable = mapping[currentColumn]; - } - - colspan = splitCells[0].span; - - for (let i = 1; i < splitCells.length; i++) { - that.mergedCellsPDF.push({ cell: [splitCells[i].start, row], colspan: splitCells[i].span, rowspan: rowspan, originalCell: col }); - } - } - } - - for (let j = col; j < col + colspan; j++) { - for (let k = row; k < row + rowspan; k++) { - const code = j + ',' + k; - - if (j === col && k === row) { - mergedMainCells[code] = { colspan: colspan, rowspan: rowspan, originalCell: cellDefinition.originalCell }; - continue; - } - - mergedSecondaryCells[code] = true; - } - } - } - } - - /** - * Gets alternation index. - */ - getAlternationIndex(row, prefix) { - const that = this; - - if (!that.style) { - return ''; - } - - const rowsDefinition = that.style.rows, - alternationCount = rowsDefinition && rowsDefinition.alternationCount; - - if (alternationCount && - (((rowsDefinition.alternationStart === undefined || row >= rowsDefinition.alternationStart) && - (rowsDefinition.alternationEnd === undefined || row <= rowsDefinition.alternationEnd)) || - rowsDefinition.alternationStart === rowsDefinition.alternationEnd)) { - return prefix + (row % rowsDefinition.alternationCount); - } - - return ''; - } - - /** - * Gets formatted numeric or date value (for use in HTML and PDF export). - */ - getFormattedValue(value, datafield) { - const that = this, - style = that.style; - - if (datafield && style && style.columns && - style.columns[datafield] && style.columns[datafield].format) { - if (typeof value === 'number') { - return that.formatNumber(value, style.columns[datafield].format); - } - else if (value instanceof Date) { - return that.formatDate(value, style.columns[datafield].format); - } - } - else if (value instanceof Date) { - return that.formatDate(value, 'd'); - } - - return value; - } - - /** - * Exports to JSON. - */ - exportToJSON(data, fileName) { - return this.downloadFile(JSON.stringify(data, this.datafields.concat('rows')), 'application/json', fileName); - } - - /** - * Exports to PDF. - */ - exportToPDF(data, fileName) { - const that = this, - datafields = that.datafields, - startIndex = +that.exportHeader, - groupsHandled = [], - mergedMainCells = {}, - mergedSecondaryCells = {}, - mapping = {}, - headerRows = startIndex ? that.complexHeader ? that.complexHeader.length : 1 : 0, - docDefinition = { - pageOrientation: that.pageOrientation || 'portrait' - }; - let header = [], content = [], tables; - - function createTableRow() { - let tableRow = []; - - for (let i = 0; i < tables.length; i++) { - tableRow.push([]); - } - - return tableRow; - } - - data = that.processGroupingInformation(data); - that.data = data; - that.headerRows = headerRows; - that.getPDFStyle(); - - const styleInfo = that.styleInfo; - - tables = styleInfo ? that.wrapPDFColumns(docDefinition, mapping) : [{ body: header, datafields: datafields }]; - - if (startIndex) { - header = that.getPDFHeader(datafields, tables, mapping); - } - - that.getMergedCellsInfo(mergedMainCells, mergedSecondaryCells, mapping); - - mainLoop: - for (let i = startIndex; i < data.length; i++) { - const currentRecord = data[i]; - let groupId = '', - outlineLevel = 0; - - if (that.groupBy) { - for (let k = 0; k < that.groupBy.length; k++) { - const datafield = that.groupBy[k], - currentGroup = currentRecord[datafield], - currentGroupLabel = that.groups[datafield][currentGroup]; - - groupId += currentGroup; - - if (groupsHandled.indexOf(groupId) === -1) { - that.createGroupHeaderRow(tables, { text: currentGroupLabel, style: ['row', 'cell', 'group'], marginLeft: outlineLevel * 7.5 }); - groupsHandled.push(groupId); - i--; - continue mainLoop; - } - - outlineLevel++; - } - } - - const tableRow = createTableRow(), - row = i - startIndex; - let n = that.getAlternationIndex(row, ''); - - for (let j = 0; j < datafields.length; j++) { - const datafield = datafields[j], - entry = { style: ['row', 'row' + row, 'cell', 'cell' + datafield] }, - tableIndex = mapping[j] || 0; - - if (n !== undefined) { - entry.style.splice(1, 0, 'rowN' + n); - } - - if (that.mergedCellsPDF) { - const cellCode = j + ',' + row, - mergeInfo = mergedMainCells[cellCode]; - - if (mergeInfo) { - entry.colSpan = mergeInfo.colspan; - entry.rowSpan = mergeInfo.rowspan; - - if (mergeInfo.originalCell !== undefined) { - entry.text = ''; - entry.style[entry.style.length - 1] = 'cell' + datafields[mergeInfo.originalCell]; - tableRow[tableIndex].push(entry); - continue; - } - } - else if (mergedSecondaryCells[cellCode]) { - tableRow[tableIndex].push({}); - continue; - } - } - - const value = that.getFormattedValue(currentRecord[datafield], datafield); - - entry.text = value.toString(); - that.getUniqueStylePDF(entry, datafield, row); - that.setIndentation(entry, { j: j, currentRecord: currentRecord, value: value, outlineLevel: outlineLevel }); - tableRow[tableIndex].push(entry); - } - - for (let k = 0; k < tables.length; k++) { - tables[k].body.push(tableRow[k]); - } - } - - if (styleInfo) { - for (let i = 0; i < tables.length; i++) { - const body = tables[i].body; - - for (let j = headerRows - 1; j >= 0; j--) { - body.unshift(header[i][j]); - } - - content.push({ - table: { - headerRows: headerRows, - widths: tables[i].widths, - heights: function (row) { - if (styleInfo.heights[row]) { - return styleInfo.heights[row]; - } - - if (styleInfo.defaultHeight) { - return styleInfo.defaultHeight; - } - }, - body: body - }, - pageBreak: 'after' - }); - } - - delete content[tables.length - 1].pageBreak; - docDefinition.styles = styleInfo.styles; - } - else { - const body = tables[0].body; - - for (let j = headerRows - 1; j >= 0; j--) { - body.unshift(header[0][j]); - } - - content = [{ table: { headerRows: headerRows, body: body } }]; - docDefinition.styles = { header: { bold: true }, group: { bold: true } }; - } - - docDefinition.content = content; - pdfMake.createPdf(docDefinition).download(fileName); - - delete that.mergedCellsPDF; - delete that.styleInfo; - } - - /** - * Gets the header content when exporting to PDF. - */ - getPDFStyle() { - const that = this, - style = that.style; - - if (!style) { - return ''; - } - - const sampleRecord = that.data[0], - headerDefinition = style.header, - columnsDefinition = style.columns, - rowsDefinition = style.rows, - styleInfo = { - heights: [], - widths: Array(that.datafields.length).fill('*'), - styles: { - header: {}, - row: {}, - cell: {}, - group: { fillColor: '#FFFFFF', color: '#000000', bold: true } - } - }; - - that.styleInfo = styleInfo; - - function processStyleDefinition(definition, type) { - if (!definition) { - return; - } - - for (let prop in definition) { - if (!definition.hasOwnProperty(prop)) { - continue; - } - - if (sampleRecord[prop] === undefined) { - if (prop === 'height' && type === 'header') { - for (let i = 0; i < that.headerRows; i++) { - styleInfo.heights[i] = (parseInt(definition[prop], 10) / that.headerRows) / 1.57; - } - } - else { - that.storePDFStyle({ prop: prop, value: definition[prop], toUpdate: type }); - } - } - else { - for (let columnProp in definition[prop]) { - if (!isNaN(columnProp) || !definition[prop].hasOwnProperty(columnProp)) { - continue; - } - - const value = definition[prop][columnProp], - index = that.datafields.indexOf(prop); - - if (columnProp === 'width' && styleInfo.widths[index] === '*') { - styleInfo.widths[index] = parseFloat(value); - } - else { - that.storePDFStyle({ prop: columnProp, value: value, toUpdate: type + prop }); - } - } - } - } - } - - processStyleDefinition(headerDefinition, 'header'); - processStyleDefinition(columnsDefinition, 'cell'); - - if (!rowsDefinition) { - return; - } - - for (let prop in rowsDefinition) { - if (!rowsDefinition.hasOwnProperty(prop) || prop.indexOf('alt') !== -1) { - continue; - } - - const value = rowsDefinition[prop]; - - if (!isNaN(prop)) { - for (let rowProp in value) { - if (value.hasOwnProperty(rowProp)) { - if (rowProp === 'height') { - styleInfo.heights[parseFloat(prop) + that.headerRows] = parseFloat(value[rowProp]) / 1.57; - } - else { - that.storePDFStyle({ prop: rowProp, value: value[rowProp], toUpdate: 'row' + prop }); - } - } - } - - continue; - } - - if (prop === 'height') { - styleInfo.defaultHeight = parseFloat(value) / 1.57; - } - else { - that.storePDFStyle({ prop: prop, value: value, toUpdate: 'row' }); - } - } - - if (!rowsDefinition.alternationCount) { - return; - } - - for (let i = 0; i < rowsDefinition.alternationCount; i++) { - const styleN = {}; - - if (rowsDefinition[`alternationIndex${i}Color`]) { - styleN.color = rowsDefinition[`alternationIndex${i}Color`]; - } - - if (rowsDefinition[`alternationIndex${i}BackgroundColor`]) { - styleN.fillColor = rowsDefinition[`alternationIndex${i}BackgroundColor`]; - } - - styleInfo.styles['rowN' + i] = styleN; - } - } - - /** - * Stores style in object to be applied to generated PDF. - */ - storePDFStyle(details) { - const that = this; - let objectToUpdate = that.styleInfo.styles[details.toUpdate]; - - if (!objectToUpdate) { - objectToUpdate = {}; - that.styleInfo.styles[details.toUpdate] = objectToUpdate; - } - - let value = details.value; - - switch (details.prop) { - case 'backgroundColor': - objectToUpdate.fillColor = value; - break; - case 'color': - objectToUpdate.color = value; - break; - case 'fontSize': - objectToUpdate.fontSize = parseFloat(value); - break; - case 'fontStyle': - if (value === 'italic') { - objectToUpdate.italics = true; - } - - break; - case 'fontWeight': - if (value === 'bold') { - objectToUpdate.bold = true; - } - - break; - case 'textAlign': - objectToUpdate.alignment = value; - break; - } - } - - /** - * Enables column wrapping when exporting to PDF. - */ - wrapPDFColumns(docDefinition, mapping) { - const that = this, - styleInfo = this.styleInfo, - maxPerPage = docDefinition.pageOrientation === 'portrait' ? 775 : 1155, // maximum of 775px (portrait) or 1155px (landscape) per A4 page - tables = []; - let currentPage = 0; - - for (let i = 0; i < styleInfo.widths.length; i++) { - let currentWidth = styleInfo.widths[i], - numericWidth = currentWidth; - - if (currentWidth === '*') { - numericWidth = 150; - } - else if (currentWidth >= maxPerPage) { - numericWidth = maxPerPage - currentWidth = '*'; - } - else { - currentWidth /= 1.57; - } - - if (tables[currentPage] === undefined) { - const body = []; - - tables[currentPage] = { - body: body, - width: numericWidth, - widths: [currentWidth], - datafields: [that.datafields[i]] - }; - mapping[i] = currentPage; - continue; - } - - const table = tables[currentPage]; - - if (table.width + numericWidth > maxPerPage) { - currentPage++; - i--; - continue; - } - - mapping[i] = currentPage; - table.width += numericWidth; - table.widths.push(currentWidth); - table.datafields.push(that.datafields[i]); - } - - return tables; - } - - /** - * Gets the header content when exporting to PDF. - */ - getPDFHeader(datafields, tables, mapping) { - const that = this, - headerArray = [], - headerRows = that.headerRows, - headerStructure = that.complexHeader ? that.complexHeader : [Object.values(that.data[0])], - headers = []; - let result = []; - - for (let i = 0; i < headerRows; i++) { - const row = headerStructure[i]; - - for (let k = 0; k < row.length; k++) { - let tableIndex = mapping[k] || 0; - - if (!headers[tableIndex]) { - headers[tableIndex] = []; - } - - if (!headers[tableIndex][i]) { - headers[tableIndex][i] = []; - } - - headers[tableIndex][i].push(row[k]); - } - } - - function processHeader(header, result, table) { - for (let j = 0; j < headerRows; j++) { - const row = header[j]; - const tableRow = []; - - for (let k = 0; k < row.length; k++) { - const currentLabel = row[k]; - let colspan = 1, rowspan = 1; - - if ((row[k - 1] && row[k - 1] === currentLabel) || - (header[j - 1] && (header[j - 1][k] === currentLabel))) { - tableRow.push({}); - continue; - } - - let iterator = k + 1; - - while (row[iterator] && row[iterator] === row[iterator - 1]) { - colspan++; - iterator++; - } - - iterator = j + 1; - - while (header[iterator] && header[iterator][k] === currentLabel) { - rowspan++; - iterator++; - } - - const datafield = j === headerRows - 1 || rowspan + j === headerRows ? - table.datafields[k] : null, - entry = { - text: currentLabel, colSpan: colspan, rowSpan: rowspan - }; - - if (!datafield) { - entry.alignment = 'center'; - entry.style = 'header'; - } - else { - entry.style = ['header', 'header' + datafield]; - } - - tableRow.push(entry); - } - - result.push(tableRow); - } - } - - for (let i = 0; i < tables.length; i++) { - result = []; - processHeader(headers[i], result, tables[i]); - headerArray.push(result); - } - - return headerArray; - } - - /** - * Creates group header rows when exporting to PDF. - */ - createGroupHeaderRow(tables, entryTemplate) { - for (let i = 0; i < tables.length; i++) { - const entry = Object.assign({}, entryTemplate), - colspan = tables[i].datafields.length, - tableRow = [entry]; - - entry.colSpan = colspan; - tableRow.length = colspan; - tableRow.fill({}, 1, colspan - 1); - - tables[i].body.push(tableRow); - } - } - - /** - * Gets unique cell style when exporting to PDF. - */ - getUniqueStylePDF(entry, datafield, row) { - const style = this.style; - - function toHex(background) { - const parts = /rgba\((\d+),(\d+),(\d+)\,(\d*.\d+|\d+)\)/gi.exec(background.replace(/\s/g, '')), - r = parseFloat(parts[1]).toString(16).toUpperCase(), - g = parseFloat(parts[2]).toString(16).toUpperCase(), - b = parseFloat(parts[3]).toString(16).toUpperCase(); - - return '#' + ('0').repeat(2 - r.length) + r + - ('0').repeat(2 - g.length) + g + - ('0').repeat(2 - b.length) + b; - } - - if (!style || !style.columns || !style.columns[datafield]) { - return; - } - - const uniqueStyle = style.columns[datafield][row]; - - if (!uniqueStyle) { - return; - } - - entry.fillColor = toHex(uniqueStyle.background); - entry.color = uniqueStyle.color.toLowerCase(); - } - - /** - * Sets the indentation of a PDF cell. - */ - setIndentation(entry, details) { - if (details.j !== 0) { - return; - } - - const that = this; - - if (that.actualHierarchy) { - const currentRecord = details.currentRecord; - - if (currentRecord._expanded !== undefined) { - entry.marginLeft = 25 * (currentRecord._level - 1); - entry.text = that.collapseChar + ' ' + details.value; - } - else { - entry.marginLeft = 25 * (currentRecord._level - 1) + 6; - } - } - else if (details.outlineLevel > 1) { - entry.marginLeft = (details.outlineLevel - 1) * 7.5; - } - } - - /** - * Exports to XLSX. - */ - exportToXLSX(data, fileName) { - const that = this; - let style = that.style; - - data = that.processGroupingInformation(data, true); - that.data = data; - that.getColumnsArray(); - - that.complexHeaderMergedCells = []; - - if (that.complexHeaderMergeInfo) { - for (let cell in that.complexHeaderMergeInfo) { - if (that.complexHeaderMergeInfo.hasOwnProperty(cell)) { - const currentEntry = that.complexHeaderMergeInfo[cell]; - - if (currentEntry.from[0] === currentEntry.to[0] && - currentEntry.from[1] === currentEntry.to[1]) { - continue; - } - - that.complexHeaderMergedCells.push({ - from: that.columnsArray[currentEntry.from[1]] + (currentEntry.from[0] + 1), - to: that.columnsArray[currentEntry.to[1]] + (currentEntry.to[0] + 1) - }); - } - } - } - - that.getConditionalFormatting(); - - if (!style) { - style = that.generateDefaultStyle(data); - } - - const sharedStrings = that.generateSharedStrings(data), - sharedStringsCollection = sharedStrings.collection, - sharedStringsXML = sharedStrings.xml, - stylesXML = that.generateStyles(style), - sheet1XML = that.groupBy ? that.generateSheet1WithGrouping(data, sharedStringsCollection) : - that.generateSheet1(data, sharedStringsCollection), - auxiliaryFiles = that.generateAuxiliaryFiles(), - - // eslint-disable-next-line - zip = new JSZip(), - _rels = zip.folder('_rels'), - docProps = zip.folder('docProps'), - xl = zip.folder('xl'), - xl_rels = xl.folder('_rels'), - theme = xl.folder('theme'), - worksheets = xl.folder('worksheets'); - - _rels.file('.rels', auxiliaryFiles._relsRels); - docProps.file('app.xml', auxiliaryFiles.docPropsAppXml); - docProps.file('core.xml', auxiliaryFiles.docPropsCoreXml); - xl_rels.file('workbook.xml.rels', auxiliaryFiles.xl_relsWorkbookXmlRels); - theme.file('theme1.xml', auxiliaryFiles.xlThemeTheme1Xml); - worksheets.file('sheet1.xml', sheet1XML); - xl.file('sharedStrings.xml', sharedStringsXML); - xl.file('styles.xml', stylesXML); - xl.file('workbook.xml', auxiliaryFiles.xlWorkbookXml); - zip.file('[Content_Types].xml', auxiliaryFiles.Content_TypesXml); - - zip.generateAsync({ - type: 'blob', - mimeType: - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - }) - .then(function (content) { - return that.downloadFile(content, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', fileName); - }); - - delete that.conditionalFormattingXLSX; - delete that.complexHeaderMergeInfo; - delete that.defaultRowHeight; - delete that.rowHeight; - } - - /** - * Processes grouping information. - */ - processGroupingInformation(data, xlsx) { - const that = this; - - if (!that.groupBy) { - return data; - } - - let header; - - data = data.slice(0); - - if (that.exportHeader) { - if (xlsx && that.complexHeader) { - header = data.slice(0, that.complexHeader.length); - data.splice(0, that.complexHeader.length); - } - else { - header = [data[0]]; - data.splice(0, 1); - } - } - - if (data.length > 1) { - const getCompareFunction = function (a, knownDataType) { - // gets data type of column (not necessary if the Grid provides this information) - const dataType = knownDataType || typeof a; - let compareFunction; - - switch (dataType) { - case 'string': - compareFunction = new Intl.Collator().compare; - break; - case 'number': - compareFunction = function (a, b) { - return a - b; - }; - break; - case 'boolean': - case 'bool': - compareFunction = function (a, b) { - if (a === b) { - return 0; - } - else if (a === false) { - return -1; - } - else { - return 1; - } - }; - break; - case 'date': - case 'time': - case 'dateTime': - if (a instanceof Date) { - compareFunction = function (a, b) { - return a.compare(b); - }; - } - break; - case 'object': - if (a instanceof Date) { - compareFunction = function (a, b) { - return a.getTime() - b.getTime(); - }; - } - - - break; - } - - return compareFunction; - } - - const sortByMultipleColumns = function (dataSource, sortColumns, directions, customSortingCallback) { - if (!dataSource || !(Array.isArray(dataSource)) || dataSource.length === 0 || - !sortColumns || Array.isArray(sortColumns) && sortColumns.length === 0) { - return; - } - - if (typeof sortColumns === 'string') { - sortColumns = [sortColumns]; - } - - const directionCoefficients = [], - compareFunctions = []; - - if (directions === undefined) { - directions = []; - } - - for (let i = 0; i < sortColumns.length; i++) { - if (directions[i] === undefined || directions[i] === 'asc' || directions[i] === 'ascending') { - directionCoefficients[i] = 1; - } - else { - directionCoefficients[i] = -1; - } - - compareFunctions[i] = getCompareFunction(dataSource[0][sortColumns[i]]); - } - - if (customSortingCallback) { - customSortingCallback(dataSource, sortColumns, directions, compareFunctions); - return; - } - - dataSource.sort(function (a, b) { - for (let i = 0; i < sortColumns.length; i++) { - const result = compareFunctions[i](a[sortColumns[i]], b[sortColumns[i]]); - - if (result === 0) { - if (sortColumns[i + 1]) { - continue; - } - else if (a._index !== undefined) { - // makes sorting stable - return (a._index - b._index) * directionCoefficients[i]; - } - - return 0; - } - - return result * directionCoefficients[i]; - } - }); - } - - sortByMultipleColumns(data, that.groupBy); - } - - if (header) { - data = header.concat(data); - } - - that.getGroupLabels(data); - - return data; - } - - /** - * Exports to XML. - */ - exportToXML(data, fileName) { - const datafields = this.datafields.slice(0); - let xmlContent = '\n\n'; - - if (datafields.indexOf('rows') === -1) { - datafields.push('rows'); - } - - function recursion(records, indent) { - let content = ''; - - for (let i = 0; i < records.length; i++) { - const currentRecord = records[i]; - - content += indent + '\n'; - - for (let j = 0; j < datafields.length; j++) { - const datafield = datafields[j]; - - if (datafield === 'rows') { - if (!currentRecord.rows) { - continue; - } - - content += `${indent} \n${recursion(currentRecord.rows, indent + ' ')}${indent} \n`; - continue; - } - - content += indent + ` <${datafield}>${currentRecord[datafield]}\n`; - } - - content += indent + '\n'; - } - - return content; - } - - xmlContent += recursion(data, ' ') + '
'; - - return this.downloadFile(xmlContent, 'application/xml', fileName); - } - - /** - * Formats a date. - */ - formatDate(value, format) { - var date = $.jqx.formatDate(value, format); - - return date; - } - - /** - * Formats a number. - */ - formatNumber(value, format) { - var number = $.jqx.formatNumber(value, format); - - return number; - } - - /** - * Generates auxiliary files necessary for XLSX. - */ - generateAuxiliaryFiles() { - // _rels\.rels - const _relsRels = ` -`; - - // docProps\app.xml - const docPropsAppXml = ` -Microsoft Excel0falseWorksheets1Sheet1falsefalsefalse16.0300`; - - // docProps\core.xml - const now = new Date().toISOString(), - docPropsCoreXml = ` -Smart HTML ElementsSmart HTML Elements${now}${now}`; - - // xl\_rels\workbook.xml.rels - const xl_relsWorkbookXmlRels = ` -`; - - // xl\theme\theme1.xml - const xlThemeTheme1Xml = ` -`; - - // xl\workbook.xml - const xlWorkbookXml = ` -`; - - // [Content_Types].xml - const Content_TypesXml = ` -`; - - return { - _relsRels: _relsRels, - docPropsAppXml: docPropsAppXml, - docPropsCoreXml: docPropsCoreXml, - xl_relsWorkbookXmlRels: xl_relsWorkbookXmlRels, - xlThemeTheme1Xml: xlThemeTheme1Xml, - xlWorkbookXml: xlWorkbookXml, - Content_TypesXml: Content_TypesXml - }; - } - - /** - * Generates default style object (for use in XLSX export). - */ - generateDefaultStyle(data) { - const that = this, - defaultStyle = {}, - datafields = that.datafields, - firstRecord = that.complexHeader ? data[that.complexHeader.length] : data[+that.exportHeader]; - - if (!firstRecord) { - return defaultStyle; - } - - for (let i = 0; i < datafields.length; i++) { - const sampleValue = firstRecord[datafields[i]]; - - if (sampleValue instanceof Date) { - if (!defaultStyle.columns) { - defaultStyle.columns = []; - } - - defaultStyle.columns[datafields[i]] = { format: 'd' }; - } - } - - return defaultStyle; - } - - /** - * Generates group row. - */ - generateGroupRow(details) { - const rowNumber = details.rowNumber, - from = 'A' + rowNumber, - recordXML = ` - - ${details.sharedStringIndex} - - \n`; - - details.mergedCells.push({ from: from, to: this.columnsArray[details.numberOfColumns - 1] + rowNumber }); - - return recordXML; - } - - /** - * Generates sharedStrings.xml. - */ - generateSharedStrings(data) { - const that = this, - datafields = that.datafields, - collection = []; - let xml = '', - count = 0, - uniqueCount = 0; - - function addSharedString(currentValue) { - count++; - - if (collection.indexOf(currentValue) === -1) { - uniqueCount++; - collection.push(currentValue); - - currentValue = currentValue.replace(/&(?!amp;)/g, '&'); - currentValue = currentValue.replace(/'/g, '''); - currentValue = currentValue.replace(/"/g, '"'); - currentValue = currentValue.replace(/>/g, '>'); - currentValue = currentValue.replace(/${currentValue}`; - } - } - - for (let i = 0; i < data.length; i++) { - const currentRecord = data[i]; - - for (let j = 0; j < datafields.length; j++) { - let currentValue = currentRecord[datafields[j]]; - - if (typeof currentValue !== 'string') { - continue; - } - - addSharedString(currentValue); - } - } - - if (that.groupLabels) { - for (let i = 0; i < that.groupLabels.length; i++) { - addSharedString(that.groupLabels[i]); - } - } - - xml = ` -${xml}`; - - return { collection: collection, xml: xml }; - } - - /** - * Generates sheet1.xml. - */ - generateSheet1(data, sharedStrings) { - const that = this, - numberOfColumns = that.columnsArray.length, - numberOfRows = data.length, - dimensionEnd = that.columnsArray[numberOfColumns - 1] + numberOfRows, - datafields = that.datafields, - autoFilter = that.getFilters(), - mergedCells = [].concat(that.complexHeaderMergedCells); - - let xmlContent = ` - - - - - - - ${that.getCustomColumnWidths()} - \n`; - - function r(col, row) { - return that.columnsArray[col] + row; - } - - for (let i = 0; i <= data.length; i++) { - const currentRecord = data[i], - rowNumber = i + 1; - let collapsed = ''; - - if (that.actualHierarchy) { - const previousRecord = data[i - 1]; - - if (previousRecord && previousRecord._collapsed && - (!currentRecord || previousRecord._level > currentRecord._level)) { - collapsed = ' collapsed="true"'; - } - } - - if (i === data.length) { - if (collapsed) { - xmlContent += ` ${that.conditionalFormattingXLSX.conditions}${autoFilter}${that.getMergedCells(mergedCells)} - - -`; - - return xmlContent; - } - - /** - * Generates sheet1.xml with grouping. - */ - generateSheet1WithGrouping(data, sharedStrings) { - const that = this, - numberOfColumns = that.columnsArray.length, - numberOfRows = data.length, - dimensionEnd = that.columnsArray[numberOfColumns - 1] + numberOfRows, - datafields = that.datafields, - mergedCells = [].concat(that.complexHeaderMergedCells); - - let xmlContent = ` - - - - - - ${that.getCustomColumnWidths()} - \n`, - rowNumberCorrection = 0, - groupsHandled = []; - - function r(col, row) { - return that.columnsArray[col] + row; - } - - mainLoop: - for (let i = 0; i < data.length; i++) { - const currentRecord = data[i], - rowNumber = i + 1 + rowNumberCorrection; - let outlineLevel = 0, - outlineXML = ''; - - if (!that.exportHeader || - (!that.complexHeader && i !== 0) || - (that.complexHeader && i >= that.complexHeader.length)) { - let groupId = ''; - - for (let k = 0; k < that.groupBy.length; k++) { - const datafield = that.groupBy[k], - currentGroup = currentRecord[datafield], - currentGroupLabel = that.groups[datafield][currentGroup]; - - groupId += currentGroup; - - if (groupsHandled.indexOf(groupId) === -1) { - let sharedStringIndex = sharedStrings.indexOf(currentGroupLabel); - - xmlContent += that.generateGroupRow({ - rowNumber: rowNumber, - outlineLevel: outlineLevel, - numberOfColumns: numberOfColumns, - sharedStringIndex: sharedStringIndex, - mergedCells: mergedCells - }); - groupsHandled.push(groupId); - i--; - rowNumberCorrection++; - continue mainLoop; - } - - outlineLevel++; - } - - outlineXML = ` outlineLevel="${outlineLevel}"`; - } - - let recordXML = ` \n`; - - for (let j = 0; j < datafields.length; j++) { - const s = that.getXLSXCellStyle(r(j, i + 1)); - - recordXML += that.getActualCellData(currentRecord[datafields[j]], { r: r(j, rowNumber), s: s }, sharedStrings); - } - - recordXML += ' \n'; - xmlContent += recordXML; - } - - xmlContent += ` ${that.getMergedCells(mergedCells)} - - -`; - - return xmlContent; - } - - /** - * Gets actual spreadsheet cell data. - */ - getActualCellData(currentValue, details, sharedStrings) { - const r = details.r, - s = details.s || ' s="0"'; - - if (typeof currentValue === 'string') { - return ` - ${sharedStrings.indexOf(currentValue)} - \n`; - } - - if (typeof currentValue === 'boolean') { - return ` - ${+currentValue} - \n`; - } - - if (currentValue instanceof Date) { - const excelDate = (currentValue.getTime() + this.timeBetween1900And1970) / 86400000 + 2; - - return ` - ${excelDate} - \n`; - } - - // numeric cells - return ` - ${currentValue} - \n`; - } - - /** - * Gets column labels. - */ - getColumnsArray() { - const that = this, - numberOfColumns = that.datafields.length, - columnsCollection = []; - - function getIterator(i) { - if (i < 26) { - return ''; - } - - return String.fromCharCode(64 + Math.floor(i / 26)); - } - - for (let i = 0; i < numberOfColumns; i++) { - columnsCollection.push(getIterator(i) + String.fromCharCode(65 + (i < 26 ? i : i % 26))); - } - - that.columnsArray = columnsCollection; - } - - /** - * Gets column style. - */ - getColumnStyle() { - const that = this, - style = that.style; - - if (!style) { - return ` .header { border: 1px solid black; padding: 5px; } - .column { border: 1px solid black; padding: 5px; } - .group { background-color: #FFFFFF; color: #000000; font-weight: bold; }`; - } - - const styles = { - header: 'border: 1px solid black; padding: 5px; ', - column: 'white-space: nowrap; overflow: hidden; border: 1px solid black; padding: 5px; ', - group: 'background-color: #FFFFFF; color: #000000; font-weight: bold; ' - }, - sampleRecord = that.data[0]; - let generatedStyle = ''; - - const headerDefinition = style.header || {}; - - for (let prop in headerDefinition) { - if (!headerDefinition.hasOwnProperty(prop)) { - continue; - } - - const value = headerDefinition[prop]; - - if (sampleRecord[prop]) { - if (!styles['header' + prop]) { - styles['header' + prop] = ''; - } - - for (let columnProp in value) { - if (value.hasOwnProperty(columnProp)) { - const css = window.jqxToDash(columnProp) + ': ' + value[columnProp] + '; '; - - styles['header' + prop] += css; - - if (columnProp === 'width') { - if (!styles['column' + prop]) { - styles['column' + prop] = ''; - } - - styles['column' + prop] += css; - } - } - } - - continue; - } - - if (prop === 'height' && that.complexHeader) { - styles.header += 'height: ' + parseInt(headerDefinition[prop], 10) / that.complexHeader.length + 'px; '; - } - else { - styles.header += window.jqxToDash(prop) + ': ' + headerDefinition[prop] + '; '; - } - } - - const columnsDefinition = style.columns || {}; - - for (let prop in columnsDefinition) { - if (!columnsDefinition.hasOwnProperty(prop)) { - continue; - } - - const value = columnsDefinition[prop]; - - if (sampleRecord[prop]) { - if (!styles['column' + prop]) { - styles['column' + prop] = ''; - } - - for (let columnProp in value) { - if (isNaN(columnProp) && value.hasOwnProperty(columnProp) && columnProp !== 'format') { - styles['column' + prop] += window.jqxToDash(columnProp) + ': ' + value[columnProp] + '; '; - } - } - - continue; - } - - styles.column += window.jqxToDash(prop) + ': ' + value + '; '; - } - - for (let prop in styles) { - if (styles.hasOwnProperty(prop)) { - generatedStyle += ` .${prop} { ${styles[prop]}}\n`; - } - } - - return generatedStyle; - } - - /** - * Gets custom column widths. - */ - getCustomColumnWidths() { - const that = this; - - if (!that.style || !that.columnWidth || that.columnWidth.length === 0) { - return ''; - } - - let xml = '\n \n'; - - for (let i = 0; i < that.columnWidth.length; i++) { - let width = that.columnWidth[i]; - - if (width !== undefined) { - width = Math.round(parseFloat(width)) / 11; - xml += ` \n`; - } - } - - xml += ' '; - - return xml; - } - - /** - * Returns customFilter tag. - */ - getCustomFilter(value, condition) { - let operator = 'equal', - val; - - if (value instanceof Date) { - value = (value.getTime() + this.timeBetween1900And1970) / 86400000 + 2; - } - - condition = condition.toUpperCase(); - - switch (condition) { - case 'EMPTY': - val = ''; - break; - case 'NOT_EMPTY': - val = ''; - operator = 'notEqual'; - break; - case 'CONTAINS': - case 'CONTAINS_CASE_SENSITIVE': - val = `*${value}*`; - break; - case 'DOES_NOT_CONTAIN': - case 'DOES_NOT_CONTAIN_CASE_SENSITIVE': - val = `*${value}*`; - operator = 'notEqual'; - break; - case 'STARTS_WITH': - case 'STARTS_WITH_CASE_SENSITIVE': - val = `${value}*`; - break; - case 'ENDS_WITH': - case 'ENDS_WITH_CASE_SENSITIVE': - val = `*${value}`; - break; - case 'EQUAL': - case 'EQUAL_CASE_SENSITIVE': - val = value; - break; - case 'NULL': - val = null; - break; - case 'NOT_NULL': - val = null; - operator = 'notEqual'; - break; - case 'NOT_EQUAL': - val = value; - operator = 'notEqual'; - break; - case 'LESS_THAN': - val = value; - operator = 'lessThan'; - break; - case 'LESS_THAN_OR_EQUAL': - val = value; - operator = 'lessThanOrEqual'; - break; - case 'GREATER_THAN': - val = value; - operator = 'greaterThan'; - break; - case 'GREATER_THAN_OR_EQUAL': - val = value; - operator = 'greaterThanOrEqual'; - break; - } - - return ` \n`; - } - - /** - * Gets custom row height. - */ - getCustomRowHeight(row) { - const that = this; - - if (that.style) { - return that.rowHeight[row] || that.defaultRowHeight || ''; - } - - return ''; - } - - /** - * Gets datafields. - */ - getDatafields(data) { - const that = this, - sampleRecord = data[0], - datafields = []; - - for (let prop in sampleRecord) { - if (sampleRecord.hasOwnProperty(prop) && prop.charAt(0) !== '_') { - datafields.push(prop); - } - } - - that.datafields = datafields; - } - - /** - * Returns autoFilter XML. - */ - getFilters() { - const that = this, - filterBy = that.filterBy; - - if (!filterBy) { - return ''; - } - - let xml = ''; - - for (let datafield in filterBy) { - if (filterBy.hasOwnProperty(datafield)) { - const colId = that.datafields.indexOf(datafield); - - if (colId === -1) { - continue; - } - - const filterDetails = filterBy[datafield], - filters = filterDetails.filters; - - xml += ` - \n`; - - for (let i = 0; i < filters.length; i++) { - xml += that.getCustomFilter(filters[i].value, filters[i].condition); - } - - xml += ` - `; - } - } - - if (!xml) { - return ''; - } - - xml = `\n \n${xml}\n `; - return xml; - } - - /** - * Gets group labels based on data. - */ - getGroupLabels(data) { - const that = this, - startIndex = that.xlsxStartIndex !== undefined ? that.xlsxStartIndex : +that.exportHeader, - groups = {}, - groupLabels = []; - - for (let i = startIndex; i < data.length; i++) { - const currentRecord = data[i]; - - for (let j = 0; j < that.groupBy.length; j++) { - const datafield = that.groupBy[j], - currentValue = currentRecord[datafield]; - let group = groups[datafield]; - - if (group === undefined) { - groups[datafield] = {}; - group = groups[datafield]; - } - - if (group[currentValue] === undefined) { - group[currentValue] = (that.exportHeader ? data[startIndex - 1][datafield] : datafield) + ': ' + currentValue; - groupLabels.push(group[currentValue]); - } - } - } - - that.groups = groups; - that.groupLabels = groupLabels; - } - - /** - * Gets the header content when exporting to HTML. - */ - getHTMLHeader(datafields, data) { - const that = this; - let header = '\n \n'; - - if (!that.complexHeader) { - header += ' \n'; - - for (let j = 0; j < datafields.length; j++) { - const datafield = datafields[j]; - - header += ` ${data[0][datafield]}\n`; - } - - header += ' \n '; - return header; - } - - for (let j = 0; j < that.complexHeader.length; j++) { - const row = that.complexHeader[j]; - - header += ' \n'; - - for (let k = 0; k < row.length; k++) { - const currentLabel = row[k]; - let colspan = 1, rowspan = 1; - - if ((row[k - 1] && row[k - 1] === currentLabel) || - (that.complexHeader[j - 1] && (that.complexHeader[j - 1][k] === currentLabel))) { - continue; - } - - let iterator = k + 1; - - while (row[iterator] && row[iterator] === row[iterator - 1]) { - colspan++; - iterator++; - } - - iterator = j + 1; - - while (that.complexHeader[iterator] && that.complexHeader[iterator][k] === currentLabel) { - rowspan++; - iterator++; - } - - const datafield = j === that.complexHeader.length - 1 || rowspan + j === that.complexHeader.length ? - ' header' + datafields[k] : ''; - - header += ` ${currentLabel}\n`; - } - - header += ' \n'; - } - - header += ' '; - return header; - } - - /** - * Gets conditional formatting XML. - */ - getConditionalFormatting() { - const that = this, - conditionalFormatting = that.conditionalFormatting; - - if (!conditionalFormatting) { - that.conditionalFormattingXLSX = { conditions: '', styles: '' }; - return; - } - - const dxfCodes = []; - let conditionsXml = '', - stylesXml = ''; - - for (let i = conditionalFormatting.length - 1; i >= 0; i--) { - const columnFormat = conditionalFormatting[i], - columnLetter = that.columnsArray[that.datafields.indexOf(columnFormat.column)], - startCell = columnLetter + (that.xlsxStartIndex + 1), - sqref = startCell + ':' + columnLetter + (that.data.length), - dxfCode = columnFormat.background + columnFormat.color, - attr = that.getConditionalAttributes(columnFormat, startCell); - let dxfId = dxfCodes.indexOf(dxfCode); - - if (dxfId === -1) { - const newDxf = ` - - - - - - - - - - - - \n`; - - stylesXml += newDxf; - dxfId = dxfCodes.length; - dxfCodes.push(dxfCode); - } - - conditionsXml += ` - -${attr.formula} - \n`; - } - - stylesXml = ` \n${stylesXml} `; - - that.conditionalFormattingXLSX = { conditions: conditionsXml, styles: stylesXml }; - } - - /** - * Gets conditional formatting XML attributes. - */ - getConditionalAttributes(columnFormat, startCell) { - let condition = columnFormat.condition, - comparator = columnFormat.comparator, - text = '', - rank = 0, - percent = 0, - bottom = 0, - equalAverage = 0, - aboveAverage = 0, - operator = '', - timePeriod = '', - type = '', - formula = ''; - - switch (condition) { - case 'equal': - operator = 'equal'; - type = 'cellIs'; - formula = ` ${comparator}\n`; - break; - case 'lessThan': - operator = 'lessThan'; - type = 'cellIs'; - formula = ` ${comparator}\n`; - break; - case 'greaterThan': - operator = 'greaterThan'; - type = 'cellIs'; - formula = ` ${comparator}\n`; - break; - case 'notEqual': - operator = 'notEqual'; - type = 'cellIs'; - formula = ` ${comparator}\n`; - break; - case 'between': - operator = 'between'; - type = 'cellIs'; - formula = ` ${columnFormat.min} - ${columnFormat.max}\n`; - break; - case 'duplicate': - type = 'duplicateValues'; - formula = ' 0\n'; - break; - case 'topNItems': - rank = comparator; - type = 'top10'; - break; - case 'bottomNItems': - rank = comparator; - bottom = 1; - type = 'top10'; - break; - case 'topNPercent': - rank = comparator; - percent = 1; - type = 'top10'; - break; - case 'bottomNPercent': - rank = comparator; - percent = 1; - bottom = 1; - type = 'top10'; - break; - case 'aboveAverage': - aboveAverage = 1; - type = 'aboveAverage'; - formula = ' 0\n'; - break; - case 'belowAverage': - type = 'aboveAverage'; - formula = ' 0\n'; - break; - case 'contains': - text = comparator; - operator = 'containsText'; - type = 'containsText'; - formula = ` NOT(ISERROR(SEARCH("${comparator}",${startCell})))\n`; - break; - case 'doesNotContain': - text = comparator; - operator = 'notContains'; - type = 'notContainsText'; - formula = ` ISERROR(SEARCH("${comparator}",${startCell}))\n`; - break; - case 'dateOccur': - timePeriod = ` timePeriod="${comparator}"`; - type = 'timePeriod'; - break; - } - - if (operator) { - operator = ` operator="${operator}" `; - } - - return { - text: text, - rank: rank, - percent: percent, - bottom: bottom, - equalAverage: equalAverage, - aboveAverage: aboveAverage, - operator: operator, - timePeriod: timePeriod, - type: type, - formula: formula - } - } - - /** - * Gets merged cells XML. - */ - getMergedCells(mergedCells) { - const that = this; - - let mergeCellsXml = ''; - - for (let i = 0; i < mergedCells.length; i++) { - if (mergedCells[i].from === mergedCells[i].to) { - continue; - } - - mergeCellsXml += `\n \n`; - } - - if (that.mergedCells) { - for (let i = 0; i < that.mergedCells.length; i++) { - const cellDefinition = that.mergedCells[i]; - - if (cellDefinition.rowspan < 2 && cellDefinition.colspan < 2) { - continue; - } - - const from = that.columnsArray[cellDefinition.cell[0]] + (cellDefinition.cell[1] + that.xlsxStartIndex + 1), - to = that.columnsArray[cellDefinition.cell[0] + cellDefinition.colspan - 1] + (cellDefinition.cell[1] + that.xlsxStartIndex + cellDefinition.rowspan); - - mergeCellsXml += `\n \n`; - } - } - - if (mergeCellsXml) { - mergeCellsXml = `\n ${mergeCellsXml} `; - } - - return mergeCellsXml; - } - - /** - * Gets numFmt index. - */ - getNumFmtIndex(format, numFmts) { - let index = numFmts.collection.indexOf(format); - - if (index === -1) { - index = numFmts.collection.length + 100; - numFmts.collection.push(format); - numFmts.xml += ``; - } - else { - index += 100; - } - - return index; - } - - /** - * Returns outlineLevel. - */ - getOutlineLevel(record) { - if (!this.actualHierarchy || record._level === 1) { - return ''; - } - - return ` outlineLevel="${record._level - 1}"`; - } - - /** - * Gets row style. - */ - getRowStyle() { - const that = this, - style = that.style; - - if (!style) { - return ''; - } - - const rowsDefinition = style.rows; - - if (!rowsDefinition) { - return ''; - } - - const styles = { - row: '' - }; - let generatedStyle = ''; - - for (let prop in rowsDefinition) { - if (!rowsDefinition.hasOwnProperty(prop) || - prop === 'alternationCount' || - prop === 'alternationStart' || - prop === 'alternationEnd') { - continue; - } - - const value = rowsDefinition[prop]; - - if (prop.indexOf('alt') !== -1) { - const i = prop.slice(16, 17), - property = prop.slice(17); - - if (!styles['rowN' + i]) { - styles['rowN' + i] = ''; - } - - if (property === 'Color') { - styles['rowN' + i] += 'color : ' + value + '; '; - } - else if (property === 'BorderColor') { - styles['rowN' + i] += 'border-color : ' + value + '; '; - } - else { - styles['rowN' + i] += 'background-color : ' + value + '; '; - } - - continue; - } - - if (!isNaN(prop)) { - if (!styles['row' + prop]) { - styles['row' + prop] = ''; - } - - for (let rowProp in value) { - if (value.hasOwnProperty(rowProp)) { - styles['row' + prop] += window.jqxToDash(rowProp) + ': ' + value[rowProp] + '; '; - } - } - - continue; - } - - styles.row += window.jqxToDash(prop) + ': ' + rowsDefinition[prop] + '; '; - } - - let keys = Object.keys(styles); - - keys.sort(function (a, b) { - if (a === 'row') { - return -1; - } - - if (b === 'row') { - return 1; - } - - const aIsNum = !isNaN(a.slice(3)), - bIsNum = !isNaN(b.slice(3)); - - if (aIsNum && !bIsNum) { - return 1; - } - - if (!aIsNum && bIsNum) { - return -1; - } - - return +(a < b); - }); - - for (let i = 0; i < keys.length; i++) { - generatedStyle += ` .${keys[i]} { ${styles[keys[i]]}}\n`; - } - - return generatedStyle; - } - - /** - * Gets table style. - */ - getTableStyle() { - const that = this, - style = that.style; - - if (!style) { - return ' style="table-layout: fixed; border: 1px solid black; border-collapse: collapse;"'; - } - - let generatedStyle = 'table-layout: fixed; '; - - for (let prop in style) { - if (style.hasOwnProperty(prop) && ['header', 'columns', 'rows'].indexOf(prop) === -1) { - generatedStyle += window.jqxToDash(prop) + ': ' + style[prop] + '; '; - } - } - - if (generatedStyle) { - generatedStyle = ' style="' + generatedStyle + '"'; - } - - return generatedStyle; - } - - /** - * Gets the "s" (style) attribute of an XLSX cell. - */ - getXLSXCellStyle(r) { - const that = this; - - if (that.cellStyleMapping[r] !== undefined) { - return ` s="${that.cellStyleMapping[r]}"`; - } - - return ''; - } - - /** - * Gets the "s" (style) attribute of an XLSX cell. - */ - getXLSXFormat(format, cellValue) { - if (typeof cellValue === 'number') { - let precision = parseFloat(format.slice(1)) || 0, - precisionCode = precision > 0 ? '.' + ('0').repeat(precision) : ''; - - format = format.slice(0, 1); - - switch (format) { - case 'C': - case 'c': - return '\$#,0' + precisionCode; - case 'D': - case 'd': - if (precision) { - return ('0').repeat(precision); - } - - return '0'; - case 'E': - case 'e': - return '0' + precisionCode + format + '000'; - case 'F': - case 'f': - return '0' + precisionCode; - case 'N': - case 'n': - return '#,0' + precisionCode; - case 'P': - case 'p': - return '#,0' + precisionCode + ' %'; - default: - return; - } - } - else if (cellValue instanceof Date) { - switch (format) { - case 'd': - return 'm/d/yyyy'; - case 'D': - return 'nnnnmmmm dd, yyyy'; - case 't': - return 'h:m AM/PM'; - case 'T': - return 'h:mm:ss AM/PM'; - case 'f': - return 'nnnnmmmm dd, yyyy h:m AM/PM'; - case 'F': - return 'nnnnmmmm dd, yyyy h:mm:ss AM/PM'; - case 'M': - return 'mmmm d'; - case 'Y': - return 'yyyy mmmm'; - case 'FP': - case 'PP': - return 'yyyy-mm-dd hh:mm:ss'; - case 'FT': - case 'PT': - return 'hh:mm:ss'; - } - - format = format.replace(/f|u|n|p|e|a|x|o/gi, ''); - format = format.replace(/tt/gi, 'AM/PM'); - format = format.replace(/:{2,}|:\s|:$|\.$/g, ''); - format = format.trim(); - return format; - } - } - - /** - * Processes column styles. - */ - processColumnStyle(style) { - const that = this, - headerDefinition = style.header, - columnsDefinition = style.columns, - sampleRecord = that.data[0], - startIndex = that.xlsxStartIndex; - - that.columnWidth = []; - - if (startIndex && headerDefinition) { - for (let i = 0; i < that.columnsArray.length; i++) { - const columnLetter = that.columnsArray[i], - cell = columnLetter + startIndex, - columnSpecific = headerDefinition[that.datafields[i]]; - - for (let prop in headerDefinition) { - if (headerDefinition.hasOwnProperty(prop) && sampleRecord[prop] === undefined) { - if (that.complexHeader) { - for (let j = 0; j < that.complexHeader.length; j++) { - if (prop === 'height') { - that.rowHeight[j] = ` ht="${(parseFloat(headerDefinition.height) / that.complexHeader.length) / 2}"`; - continue; - } - else { - that.storeCellStyle(columnLetter + (j + 1), prop, headerDefinition[prop]); - } - } - } - else { - if (prop === 'height') { - that.rowHeight[0] = ` ht="${parseFloat(headerDefinition.height) / 2}"`; - continue; - } - - that.storeCellStyle(cell, prop, headerDefinition[prop]); - } - } - } - - if (!columnSpecific) { - continue; - } - - for (let prop in columnSpecific) { - if (columnSpecific.hasOwnProperty(prop)) { - if (prop === 'width') { - that.columnWidth[i] = columnSpecific.width; - continue; - } - - that.storeCellStyle(cell, prop, columnSpecific[prop]); - } - } - } - } - else if (headerDefinition) { - for (let i = 0; i < that.columnsArray.length; i++) { - const columnSpecific = headerDefinition[that.datafields[i]]; - - if (columnSpecific && columnSpecific.width !== undefined) { - that.columnWidth[i] = columnSpecific.width; - } - } - } - - if (!columnsDefinition) { - return ''; - } - - for (let i = startIndex; i < that.data.length; i++) { - for (let j = 0; j < that.columnsArray.length; j++) { - const columnLetter = that.columnsArray[j], - cell = columnLetter + (i + 1), - datafield = that.datafields[j], - columnSpecific = columnsDefinition[datafield]; - - for (let prop in columnsDefinition) { - if (columnsDefinition.hasOwnProperty(prop) && sampleRecord[prop] === undefined) { - that.storeCellStyle(cell, prop, columnsDefinition[prop]); - } - } - - if (!columnSpecific) { - continue; - } - - for (let prop in columnSpecific) { - if (!isNaN(prop) || !columnSpecific.hasOwnProperty(prop)) { - continue; - } - - that.storeCellStyle(cell, prop, columnSpecific[prop], that.data[i][datafield]); - } - } - } - } - - /** - * Processes complex header object. - */ - processComplexHeader(header, data, format) { - const that = this, - flatHeader = {}, - processGrouping = ['html', 'jpeg', 'pdf', 'png', 'xlsx'].indexOf(format) !== -1 && header.columngroups, - datafieldMapping = [], - columnGroupHierarchy = {}, - complexHeader = []; - let headerDepth = 0; - - function getColumnGroup(columnGroup) { - for (let i = 0; i < header.columngroups.length; i++) { - const currentGroupDefinition = header.columngroups[i]; - - if (currentGroupDefinition.name === columnGroup) { - return currentGroupDefinition; - } - } - } - - function getColumnGroupHierarchy(groupDefinition) { - const columnGroups = []; - - while (groupDefinition) { - columnGroups.unshift(groupDefinition.label); - - if (groupDefinition.parentGroup) { - groupDefinition = getColumnGroup(groupDefinition.parentGroup); - } - else { - return columnGroups; - } - } - } - - if (processGrouping) { - for (let i = 0; i < header.columngroups.length; i++) { - const currentGroupDefinition = header.columngroups[i], - groupHierarchy = getColumnGroupHierarchy(currentGroupDefinition); - - columnGroupHierarchy[currentGroupDefinition.name] = groupHierarchy; - headerDepth = Math.max(headerDepth, groupHierarchy.length); - } - - headerDepth++; - - for (let i = 0; i < headerDepth; i++) { - complexHeader[i] = []; - } - } - - for (let i = 0; i < header.columns.length; i++) { - const currentColumn = header.columns[i]; - - flatHeader[currentColumn.dataField] = currentColumn.label; - - if (!processGrouping) { - continue; - } - - datafieldMapping[i] = currentColumn.dataField; - complexHeader[headerDepth - 1][i] = currentColumn.label; - - if (!currentColumn.columnGroup) { - continue; - } - - const columnGroups = columnGroupHierarchy[currentColumn.columnGroup]; - - for (let j = 0; j < columnGroups.length; j++) { - complexHeader[j][i] = columnGroups[j]; - } - } - - if (complexHeader.length > 1) { - const numberOfDatafields = Object.keys(flatHeader).length; - - for (let i = 0; i < headerDepth - 1; i++) { - const entry = {}; - - for (let j = 0; j < numberOfDatafields; j++) { - if (complexHeader[i][j] === undefined) { - let iterator = i + 1; - - while (complexHeader[iterator][j] === undefined) { - iterator++; - } - - complexHeader[i][j] = complexHeader[iterator][j]; - } - - entry[datafieldMapping[j]] = complexHeader[i][j]; - } - - if (format === 'xlsx') { - data.splice(i, 0, entry); - } - } - - that.complexHeader = complexHeader; - - if (format !== 'xlsx') { - data.unshift(flatHeader); - } - else { - data.splice(headerDepth - 1, 0, flatHeader); - - const toMerge = {}; - - for (let i = 0; i < headerDepth; i++) { - for (let j = 0; j < numberOfDatafields; j++) { - const label = complexHeader[i][j]; - - if (!toMerge[label]) { - toMerge[label] = { from: [i, j] }; - toMerge[label].to = toMerge[label].from; - } - else { - toMerge[label].to = [i, j]; - } - } - } - - that.complexHeaderMergeInfo = toMerge; - } - } - else { - data.unshift(flatHeader); - } - } - - /** - * Processes hierarchical data. - */ - processHierarchicalData(data, format) { - const that = this, - startIndex = format !== 'xlsx' ? +that.exportHeader : that.xlsxStartIndex, - siblingGroups = {}, - processedData = []; - let maxLevel = 0, - actualHierarchy = false; - - function process(parentKey, level, collapsed) { - const group = siblingGroups[parentKey]; - - maxLevel = Math.max(maxLevel, level); - - if (group === undefined) { - return; - } - - for (let i = 0; i < group.length; i++) { - const currentRecord = group[i], - keyDataField = currentRecord._keyDataField; - - currentRecord._collapsed = collapsed; - currentRecord._level = level; - processedData.push(currentRecord); - - if (siblingGroups[keyDataField]) { - actualHierarchy = true; - currentRecord._expanded = currentRecord._expanded !== undefined ? currentRecord._expanded : true; - process(keyDataField, level + 1, collapsed || !currentRecord._expanded); - } - } - } - - function processJSONXML(parentKey, level, parent) { - const group = siblingGroups[parentKey]; - - maxLevel = Math.max(maxLevel, level); - - if (group === undefined) { - return; - } - - for (let i = 0; i < group.length; i++) { - const currentRecord = group[i], - keyDataField = currentRecord._keyDataField; - let cleanedRecord; - - if (format === 'json') { - cleanedRecord = {}; - - for (let prop in currentRecord) { - if (currentRecord.hasOwnProperty(prop) && prop.charAt(0) !== '_') { - cleanedRecord[prop] = currentRecord[prop]; - } - } - } - else { - cleanedRecord = Object.assign({}, currentRecord); - } - - parent.push(cleanedRecord); - - if (siblingGroups[keyDataField]) { - actualHierarchy = true; - cleanedRecord.rows = []; - processJSONXML(keyDataField, level + 1, cleanedRecord.rows); - } - } - } - - if (data[startIndex]._keyDataField === undefined) { - return that.processNestedData(data, format, startIndex); - } - - for (let i = startIndex; i < data.length; i++) { - const currentRecord = Object.assign({}, data[i]), - parentKey = currentRecord._parentDataField; - - if (siblingGroups[parentKey] === undefined) { - siblingGroups[parentKey] = [currentRecord]; - } - else { - siblingGroups[parentKey].push(currentRecord); - } - } - - if (startIndex) { - for (let i = 0; i < startIndex; i++) { - processedData.push(Object.assign({}, data[i])); - - if (['json', 'pdf', 'xml'].indexOf(format) === -1) { - processedData[i]._level = 1; - } - } - } - - if (format !== 'json' && format !== 'xml') { - process(null, 1, false); - } - else { - processJSONXML(null, 1, processedData); - } - - if (!actualHierarchy) { - that.actualHierarchy = false; - } - - that.maxLevel = maxLevel; - return processedData; - } - - /** - * Processes nested hierarchical data. - */ - processNestedData(data, format, startIndex) { - const that = this, - processedData = []; - let maxLevel = 0, - actualHierarchy = false; - - function process(start, children, level, collapsed) { - maxLevel = Math.max(maxLevel, level); - - for (let i = start; i < children.length; i++) { - const currentRecord = Object.assign({}, children[i]); - - currentRecord._collapsed = collapsed; - currentRecord._level = level; - processedData.push(currentRecord); - - if (currentRecord.children && currentRecord.children.length > 0) { - actualHierarchy = true; - currentRecord._expanded = currentRecord._expanded !== undefined ? currentRecord._expanded : true; - process(0, currentRecord.children, level + 1, collapsed || !currentRecord._expanded); - } - - delete currentRecord.children; - } - } - - function processJSONXML(start, children, rows, level) { - maxLevel = Math.max(maxLevel, level); - - for (let i = start; i < children.length; i++) { - const currentRecord = Object.assign({}, children[i]); - - if (level === 1) { - processedData[i] = currentRecord; - } - else { - rows[i] = currentRecord; - } - - if (currentRecord.children && currentRecord.children.length > 0) { - actualHierarchy = true; - currentRecord.rows = []; - processJSONXML(0, currentRecord.children, currentRecord.rows, level + 1); - } - - delete currentRecord.children; - } - } - - if (startIndex) { - for (let i = 0; i < startIndex; i++) { - processedData.push(Object.assign({}, data[i])); - - if (['json', 'pdf', 'xml'].indexOf(format) === -1) { - processedData[i]._level = 1; - } - } - } - - if (format !== 'json' && format !== 'xml') { - process(startIndex, data, 1, false); - } - else { - processJSONXML(startIndex, data, undefined, 1); - } - - if (!actualHierarchy) { - that.actualHierarchy = false; - } - - that.maxLevel = maxLevel; - return processedData; - } - - /** - * Processes row styles. - */ - processRowStyle(style) { - const that = this, - rowsDefinition = style.rows; - - that.rowHeight = []; - - if (!rowsDefinition) { - return; - } - - const startIndex = that.xlsxStartIndex; - - function applyToRowCells(row, prop, value) { - for (let j = 0; j < that.columnsArray.length; j++) { - const currentCell = that.columnsArray[j] + (row + 1 + startIndex); - - that.storeCellStyle(currentCell, prop, value); - } - } - - if (rowsDefinition.height) { - that.defaultRowHeight = ` ht="${parseFloat(rowsDefinition.height) / 2}"`; - } - - for (let i = startIndex; i < that.data.length; i++) { - const row = i - startIndex; - - for (let prop in rowsDefinition) { - if (rowsDefinition.hasOwnProperty(prop) && - prop.indexOf('alt') === -1 && - isNaN(prop) && - prop !== 'height') { - applyToRowCells(row, prop, rowsDefinition[prop]); - } - } - - if (rowsDefinition.alternationCount && - (((rowsDefinition.alternationStart === undefined || row >= rowsDefinition.alternationStart) && - (rowsDefinition.alternationEnd === undefined || row <= rowsDefinition.alternationEnd)) || - rowsDefinition.alternationStart === rowsDefinition.alternationEnd)) { - const start = rowsDefinition.alternationStart || 0, - i = (row - start) % rowsDefinition.alternationCount; - - if (rowsDefinition[`alternationIndex${i}Color`]) { - applyToRowCells(row, 'color', rowsDefinition[`alternationIndex${i}Color`]); - } - - if (rowsDefinition[`alternationIndex${i}BorderColor`]) { - applyToRowCells(row, 'borderColor', rowsDefinition[`alternationIndex${i}BorderColor`]); - } - - if (rowsDefinition[`alternationIndex${i}BackgroundColor`]) { - applyToRowCells(row, 'backgroundColor', rowsDefinition[`alternationIndex${i}BackgroundColor`]); - } - } - - if (rowsDefinition[row]) { - for (let prop in rowsDefinition[row]) { - if (rowsDefinition[row].hasOwnProperty(prop)) { - if (prop === 'height') { - that.rowHeight[i] = ` ht="${parseFloat(rowsDefinition[row].height) / 2}"`; - continue; - } - - applyToRowCells(row, prop, rowsDefinition[row][prop]); - } - } - } - } - } - - /** - * Stores cell style in "styleMap" object. - */ - storeCellStyle(cell, prop, value) { - const that = this, - cellMap = that.styleMap[cell]; - - switch (prop) { - case 'backgroundColor': - cellMap.fills.fgColor = value; - break; - case 'color': - cellMap.fonts.color = value; - break; - case 'fontFamily': - cellMap.fonts.name = value.replace(/"/g, '\''); - break; - case 'fontSize': - cellMap.fonts.sz = parseFloat(value); - break; - case 'fontStyle': - if (value === 'italic') { - cellMap.fonts.i = true; - } - else { - delete cellMap.fonts.i; - } - - break; - case 'fontWeight': - if (value === 'bold') { - cellMap.fonts.b = true; - } - else { - delete cellMap.fonts.b; - } - - break; - case 'numFmt': { - cellMap.numFmt = value; - break; - } - case 'textAlign': - cellMap.alignment.horizontal = value; - break; - case 'textDecoration': - if (value === 'underline') { - cellMap.fonts.u = true; - } - else { - delete cellMap.fonts.u; - } - - break; - case 'verticalAlign': - if (value === 'middle') { - value = 'center'; - } - - cellMap.alignment.vertical = value; - break; - } - } - - /** - * Returns an Alpha Red Green Blue color value. - */ - toARGB(color) { - color = color.replace(/\s/g, ''); - - const rgbResult = /rgb\((\d+),(\d+),(\d+)\)/gi.exec(color); - - if (rgbResult !== null) { - const r = parseFloat(rgbResult[1]).toString(16).toUpperCase(), - g = parseFloat(rgbResult[2]).toString(16).toUpperCase(), - b = parseFloat(rgbResult[3]).toString(16).toUpperCase(); - - return 'FF' + ('0').repeat(2 - r.length) + r + - ('0').repeat(2 - g.length) + g + - ('0').repeat(2 - b.length) + b; - } - - const rgbaResult = /rgba\((\d+),(\d+),(\d+)\,(\d*.\d+|\d+)\)/gi.exec(color); - - if (rgbaResult !== null) { - const a = Math.round(parseFloat(rgbaResult[4]) * 255).toString(16).toUpperCase(), - r = parseFloat(rgbaResult[1]).toString(16).toUpperCase(), - g = parseFloat(rgbaResult[2]).toString(16).toUpperCase(), - b = parseFloat(rgbaResult[3]).toString(16).toUpperCase(); - - return ('0').repeat(2 - a.length) + a + - ('0').repeat(2 - r.length) + r + - ('0').repeat(2 - g.length) + g + - ('0').repeat(2 - b.length) + b; - } - - const shortHexResult = /^#(.)(.)(.)$/gi.exec(color); - - if (shortHexResult !== null) { - const r = shortHexResult[1].toUpperCase(), - g = shortHexResult[2].toUpperCase(), - b = shortHexResult[3].toUpperCase(); - - return 'FF' + r + r + g + g + b + b; - } - - return 'FF' + color.toUpperCase().slice(1); - } - - /** - * Adds toggleable functionality. - */ - toggleableFunctionality() { - const that = this; - - if (!that.actualHierarchy) { - return ''; - } - - return `\n - `; - } - - /** - * Generates styles.xml. - */ - generateStyles(style) { - const that = this; - - that.cellStyleMapping = {}; - - if (Object.keys(style).length === 0 && !that.complexHeader) { - // default style - return ` -${that.conditionalFormattingXLSX.styles || ''}`; - } - - that.styleMap = {}; - - for (let i = 0; i < that.data.length; i++) { - for (let j = 0; j < that.columnsArray.length; j++) { - that.styleMap[that.columnsArray[j] + (i + 1)] = { - numFmts: {}, fonts: {}, fills: {}, borders: {}, alignment: {} - } - } - } - - if (style && style.columns) { - for (let i = 0; i < that.columnsArray.length; i++) { - const datafield = that.datafields[i]; - - if (!style.columns[datafield] || !style.columns[datafield].format) { - continue; - } - - const XLSXFormat = that.getXLSXFormat(style.columns[datafield].format, that.data[that.data.length - 1][datafield]); - - if (XLSXFormat) { - style.columns[datafield].numFmt = XLSXFormat; - } - } - } - - that.processRowStyle(style); - that.processColumnStyle(style); - - const cellAliases = {}; - - for (let i = 0; i < that.complexHeaderMergedCells.length; i++) { - const currentCell = that.complexHeaderMergedCells[i]; - - if (parseFloat(currentCell.to[1]) === that.complexHeader.length) { - cellAliases[currentCell.to] = currentCell.from; - continue; - } - - that.styleMap[currentCell.from].alignment.horizontal = 'center'; - that.styleMap[currentCell.from].alignment.vertical = 'center'; - } - - const fonts = { - xml: '', - collection: ['default'] - }, - fills = { - xml: '', - collection: ['default', 'gray125'] - }, - numFmts = { - xml: '', - collection: [] - }, - cellXfs = { - xml: '', - collection: ['default'] - }; - - for (let i = 0; i < that.data.length; i++) { // iterate rows - for (let j = 0; j < that.columnsArray.length; j++) { // iterate columns - const currentCell = that.columnsArray[j] + (i + 1), - currentCellStyle = that.styleMap[currentCell]; - let currentFont = '', currentFill = '', currentAlignment = '', - currentFontCode = [], currentFillCode = [], currentAlignmentCode = [], xf = []; - - for (let prop in currentCellStyle.fonts) { - if (currentCellStyle.fonts.hasOwnProperty(prop)) { - const value = currentCellStyle.fonts[prop]; - - switch (prop) { - case 'color': - currentFontCode[0] = value; - currentFont += ``; - break; - case 'name': - currentFontCode[1] = value; - currentFont += ``; - break; - case 'sz': - currentFontCode[2] = value; - currentFont += ``; - break; - case 'i': - currentFontCode[3] = value; - currentFont += ''; - break; - case 'b': - currentFontCode[4] = value; - currentFont += ''; - break; - case 'u': - currentFontCode[5] = value; - currentFont += ''; - break; - } - } - } - - for (let prop in currentCellStyle.fills) { - if (currentCellStyle.fills.hasOwnProperty(prop)) { - const value = currentCellStyle.fills[prop]; - - switch (prop) { - case 'fgColor': - currentFillCode[0] = value; - currentFill += ``; - break; - } - } - } - - for (let prop in currentCellStyle.alignment) { - if (currentCellStyle.alignment.hasOwnProperty(prop)) { - const value = currentCellStyle.alignment[prop]; - - switch (prop) { - case 'horizontal': - currentAlignmentCode[0] = value; - currentAlignment += `horizontal="${value}" `; - break; - case 'vertical': - currentAlignmentCode[1] = value; - currentAlignment += `vertical="${value}" `; - break; - } - } - } - - currentFontCode = currentFontCode.toString(); - currentFillCode = currentFillCode.toString(); - - if (currentFont !== '') { - let fontIndex = fonts.collection.indexOf(currentFontCode); - - if (fontIndex === -1) { - fontIndex = fonts.collection.length; - - fonts.xml += '' + currentFont + ''; - fonts.collection.push(currentFontCode); - } - - xf[0] = fontIndex; - } - - if (currentFill !== '') { - let fillIndex = fills.collection.indexOf(currentFillCode); - - if (fillIndex === -1) { - fillIndex = fills.collection.length; - - fills.xml += '' + currentFill + ''; - fills.collection.push(currentFillCode); - } - - xf[1] = fillIndex; - } - - if (currentAlignmentCode.length > 0) { - xf[2] = currentAlignment; - } - - if (currentCellStyle.numFmt !== undefined) { - xf[3] = that.getNumFmtIndex(currentCellStyle.numFmt, numFmts); - } - - const xfCode = xf.toString(); - - if (xfCode !== '') { - let xfIndex = cellXfs.collection.indexOf(xfCode); - - if (xfIndex === -1) { - let newXfXML = '`; - } - else { - newXfXML += ' borderId="1"/>'; - } - - cellXfs.xml += newXfXML; - cellXfs.collection.push(xfCode); - } - - that.cellStyleMapping[cellAliases[currentCell] || currentCell] = xfIndex; - } - } - } - - if (numFmts.collection.length) { - numFmts.xml = `${numFmts.xml}`; - } - - return ` -${numFmts.xml}${fonts.xml}${fills.xml}${cellXfs.xml}${that.conditionalFormattingXLSX.styles}`; - } - } - - if ($.jqx && $.jqx.dataAdapter) { - $.jqx.dataAdapter.DataExporter = DataExporter; - } -})(jqxBaseFramework);