UNPKG

jqwidgets-framework

Version:

jQWidgets is an advanced Angular, Vue, Blazor, React, Web Components, jquery, ASP .NET MVC, Custom Elements and HTML5 UI framework.

1,220 lines (1,000 loc) 223 kB
/* tslint:disable */ /* eslint-disable */ (function () { if (typeof document === 'undefined') { return; } (function ($) { window.jqxToDash = function (value) { return value.split(/(?=[A-Z])/).join('-').toLowerCase(); } var LINE_SEPARATOR2 = "\r\n"; function returnAttributeIfPopulated(key, value, booleanTransformer) { if (!value && value !== "" && value !== 0) { return ""; } let xmlValue = value; if (typeof value === "boolean") { if (booleanTransformer) { xmlValue = booleanTransformer(value); } } return ` ${key}="${xmlValue}"`; } var XmlFactory = class { static createHeader(headerElement = {}) { const headerStart = "<?"; const headerEnd = "?>"; const keys = ["version"]; if (!headerElement.version) { headerElement.version = "1.0"; } if (headerElement.encoding) { keys.push("encoding"); } if (headerElement.standalone) { keys.push("standalone"); } const att = keys.map((key) => `${key}="${headerElement[key]}"`).join(" "); return `${headerStart}xml ${att} ${headerEnd}`; } static createXml(xmlElement, booleanTransformer) { let props = ""; if (xmlElement.properties) { if (xmlElement.properties.prefixedAttributes) { xmlElement.properties.prefixedAttributes.forEach((prefixedSet) => { Object.keys(prefixedSet.map).forEach((key) => { props += returnAttributeIfPopulated( prefixedSet.prefix + key, prefixedSet.map[key], booleanTransformer ); }); }); } if (xmlElement.properties.rawMap) { Object.keys(xmlElement.properties.rawMap).forEach((key) => { props += returnAttributeIfPopulated(key, xmlElement.properties.rawMap[key], booleanTransformer); }); } } let result = "<" + xmlElement.name + props; if (!xmlElement.children && xmlElement.textNode == null) { return result + "/>" + LINE_SEPARATOR2; } if (xmlElement.textNode != null) { return result + ">" + xmlElement.textNode + "</" + xmlElement.name + ">" + LINE_SEPARATOR2; } result += ">" + LINE_SEPARATOR2; if (xmlElement.children) { xmlElement.children.forEach((it) => { result += this.createXml(it, booleanTransformer); }); } return result + "</" + xmlElement.name + ">" + LINE_SEPARATOR2; } }; 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 !== undefined ? exportDetails.exportHeader : true; that.hierarchical = exportDetails.hierarchical; that.expandChar = exportDetails.expandChar || '+'; that.collapseChar = exportDetails.collapseChar || '-'; that.pageOrientation = exportDetails.pageOrientation; that.allowNull = exportDetails.allowNull || false; that.spreadsheets = exportDetails.spreadsheets || null; that._media = []; 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, 0, 0, 0).getTime() - new Date(1900, 0, 1, 0, 0, 0).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); }, 100); } } /** * 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; const offset = that.headerContent ? that.headerContent.length : 0; that.xlsxStartIndex = that.xlsxStartIndex + offset; } 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;charset=utf-8;', 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, callback); break; case 'xml': output = that.exportToXML(data, fileName); break; case 'md': output = that.exportToMD(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; } if (!fileName) { return stringResult; } const bom = '\uFEFF'; const csvContent = bom + stringResult; return this.downloadFile(csvContent, 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 = `<script type="text/javascript" src="${html2canvasScript.src}"></script>`; } let htmlContent = `<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style type="text/css"> ${that.getRowStyle()}${that.getColumnStyle()} </style>${html2canvas}${that.toggleableFunctionality()} </head> <body> <table${that.getTableStyle()}>${header} <tbody>\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 += ` <tr class="row"> <td class="column group" style="padding-left: ${outlineLevel * 25}px;" colspan="${that.datafields.length}">${currentGroupLabel}</td> </tr>`; groupsHandled.push(groupId); i--; continue mainLoop; } outlineLevel++; } } let currentContent = ` <tr class="row row${row}${n}${toCollapse}"${level}`; if (!fileName) { currentContent += ' style="page-break-inside: avoid;"' } currentContent += '>\n'; for (let j = 0; j < datafields.length; j++) { const cellCode = j + ',' + (row); let colspan = 1, rowspan = 1; if (mergedMainCells[cellCode]) { colspan = mergedMainCells[cellCode].colspan; rowspan = mergedMainCells[cellCode].rowspan; } else if (mergedSecondaryCells[cellCode]) { continue; } const datafield = datafields[j]; let value = currentRecord[datafield], indent = ''; if (that.actualHierarchy && j === 0) { let sign = ''; if (currentRecord._expanded) { sign = that.collapseChar; } else if (currentRecord._expanded === false) { sign = that.expandChar; } indent = `<div class="toggle-element" style="margin-left: ${25 * (currentRecord._level - 1) + 5}px;" expanded>${sign}</div>`; } value = that.getFormattedValue(value, datafield); if (typeof value === 'string' && (value.indexOf('base64') >= 0 || value.indexOf('.svg') >= 0 || value.indexOf('.png') >= 0 || value.indexOf('.jpeg') >= 0)) { value = `<img height="30" src="${value}"/>`; } 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 += ` <td class="column column${datafield}"${css} colspan="${colspan}" rowspan="${rowspan}">${indent + value}</td>\n`; } htmlContent += currentContent + ' </tr>\n'; } htmlContent += ` </tbody> </table> </body> </html>`; 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; iframe.style.pointerEvents = 'none'; 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 = new JQX.Utilities.Draw(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 (value === null) { return that.allowNull ? 'null' : ''; } 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); } /** * Export to Markdown(MD) * @param {string} data - the data to export * @param {string} fileName - the name of the file * @returns */ exportToMD(data, fileName) { const that = this, dataFields = that.datafields; let text = ''; for (let i = 0, max = data.length; i < max; i += 1) { for (let j = 0, max = dataFields.length; j < max; j += 1) { const dataField = data[i][dataFields[j]]; if (typeof dataField === 'string') { text += dataField; } } } return that.downloadFile(text, 'application/text', fileName); } /** * Exports to PDF. */ exportToPDF(data, fileName) { try { pdfMake; } catch (error) { throw new Error('Missing reference to \'pdfmake.min.js\'.'); } 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; if (!fileName) { const output = pdfMake.createPdf(docDefinition); delete that.mergedCellsPDF; delete that.styleInfo; return output; } 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 (!Object.prototype.hasOwnProperty.call(definition, 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.4; } } else { that.storePDFStyle({ prop: prop, value: definition[prop], toUpdate: type }); } } else { for (let columnProp in definition[prop]) { if (!isNaN(columnProp) || !Object.prototype.hasOwnProperty.call(definition[prop], columnProp)) { continue; } const value = definition[prop][columnProp], index = that.datafields.indexOf(prop); if (columnProp === 'width' && styleInfo.widths[index] === '*') { styleInfo.widths[index] = 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 (!Object.prototype.hasOwnProperty.call(rowsDefinition, prop) || prop.indexOf('alt') !== -1) { continue; } const value = rowsDefinition[prop]; if (!isNaN(prop)) { for (let rowProp in value) { if (Object.prototype.hasOwnProperty.call(value, rowProp)) { if (rowProp === 'height') { styleInfo.heights[parseFloat(prop) + that.headerRows] = parseFloat(value[rowProp]) / 1.4; } else { that.storePDFStyle({ prop: rowProp, value: value[rowProp], toUpdate: 'row' + prop }); } } } continue; } if (prop === 'height') { styleInfo.defaultHeight = parseFloat(value) / 1.4; } 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' ? 655 : 1155, // maximum of 655px (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; if (currentWidth === '*') { numericWidth = maxPerPage / 6; } else if (typeof currentWidth === 'string' && currentWidth.indexOf('%') !== -1) { numericWidth = Math.min(maxPerPage, Math.floor((parseFloat(currentWidth) / 100) * maxPerPage)); if (numericWidth === maxPerPage) { currentWidth = '*'; } } else { currentWidth = parseFloat(currentWidth); if (currentWidth >= maxPerPage) { numericWidth = maxPerPage currentWidth = '*'; } else { numericWidth = currentWidth; currentWidth /= 1.4; } } 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, headers = [], headerDataFields = []; let result = [], headerStructure, headerDataFieldStructure; if (that.complexHeader) { headerStructure = that.complexHeader; headerDataFieldStructure = that.complexDataFieldsHeader; } else { headerStructure = [Object.values(that.data[0])]; headerDataFieldStructure = headerStructure; } for (let i = 0; i < headerRows; i++) { const row = headerStructure[i], rowDataField = headerDataFieldStructure[i]; for (let k = 0; k < row.length; k++) { let tableIndex = mapping[k] || 0; if (!headers[tableIndex]) { headers[tableIndex] = []; headerDataFields[tableIndex] = []; } if (!headers[tableIndex][i]) { headers[tableIndex][i] = []; headerDataFields[tableIndex][i] = []; } headers[tableIndex][i].push(row[k]); headerDataFields[tableIndex][i].push(rowDataField[k]); } } function processHeader(header, headerDataField, result, table) { for (let j = 0; j < headerRows; j++) { const row = header[j], rowDataField = headerDataField[j]; const tableRow = []; for (let k = 0; k < row.length; k++) { const currentDataField = rowDataField[k]; let colspan = 1, rowspan = 1; if ((rowDataField[k - 1] && rowDataField[k - 1] === currentDataField) || (headerDataField[j - 1] && (headerDataField[j - 1][k] === currentDataField))) { tableRow.push({}); continue; } let iterator = k + 1; while (rowDataField[iterator] && rowDataField[iterator] === rowDataField[iterator - 1]) { colspan++; iterator++; } iterator = j + 1; while (headerDataField[iterator] && headerDataField[iterator][k] === currentDataField) { rowspan++; iterator++; } const datafield = j === headerRows - 1 || rowspan + j === headerRows ? table.datafields[k] : null, entry = { text: row[k], 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], headerDataFields[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); }