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
JavaScript
/* 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);
}