diff --git a/README.md b/README.md index 89bb46f..5346973 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,25 @@ table.onPageAdd(function (table, row, ev) { ## Changelogs +### Col span + +You can customize the single cells width by defining the "columnSpan" property and defining an object instead of a plain text content. + +```js + const tableBody = [ + { + columnA: "firstRowFirstCell", + columnB: "firstRowSecondCell" + }, + { + columnA: { + content:"secondRowUniqueCell", + colSpan: 2 + } + } + ] +``` + ### 0.4.0 Thank you, contributors! diff --git a/voilab-table.js b/voilab-table.js index 393a853..1004828 100644 --- a/voilab-table.js +++ b/voilab-table.js @@ -81,10 +81,19 @@ var lodash = require('lodash'), top: 0 }, data = row._renderedContent.data[column.id] || '', + colSpan = row._renderedContent.colSpan[column.id] || 1, renderer = isHeader ? column.headerRenderer : column.renderer, y = pos.y, x = pos.x; + if(colSpan && colSpan > 1) { + const columnIndex = self.getColumns().indexOf(column); + const nextCells = self.getColumns().slice(columnIndex, columnIndex+colSpan); + width = nextCells.reduce((sum,col)=>{ + return sum + col.width; + },0); + } + // Top and bottom padding (only if valign is not set) if (!column.valign) { if (isHeader) { @@ -152,14 +161,31 @@ var lodash = require('lodash'), pos.y = self.pdf.y || self.pdf.page.margins.top; } - lodash.forEach(self.getColumns(), function (column) { - if ((!isHeader && column.fill) || (isHeader && column.headerFill)) { - addCellBackground(self, column, row, pos, index, isHeader); + // check if the column at the given index of the current row must be drawn or not (maybe because the previous cell has a colSpan > 1) + const skippedCell = (row, index) => { + if(index === 0){ + return false; } - if ((!isHeader && column.border) || (isHeader && column.headerBorder)) { - addCellBorder(self, column, row, pos, isHeader); + const previousCells = self.getColumns().slice(0, index).map(col=>row[col.id]); + let toSkip = false; + previousCells.forEach((cell,cellIndex) => { + if(cell && cell.colSpan && cell.colSpan + cellIndex > index){ + toSkip = true; + } + }) + return toSkip; + }; + + lodash.forEach(self.getColumns(), function (column, index) { + if(!skippedCell(row, index)){ + if ((!isHeader && column.fill) || (isHeader && column.headerFill)) { + addCellBackground(self, column, row, pos, index, isHeader); + } + if ((!isHeader && column.border) || (isHeader && column.headerBorder)) { + addCellBorder(self, column, row, pos, isHeader); + } + addCell(self, column, row, pos, isHeader); } - addCell(self, column, row, pos, isHeader); }); self.pdf.y = pos.y + row._renderedContent.height; @@ -168,7 +194,7 @@ var lodash = require('lodash'), setRowHeight = function (self, row, isHeader) { var max_height = 0; - row._renderedContent = {data: {}, dataHeight: {}, contentHeight: {}}; + row._renderedContent = {data: {}, dataHeight: {}, contentHeight: {}, colSpan: {}}; lodash.forEach(self.getColumns(), function (column) { var renderer = isHeader ? column.headerRenderer : column.renderer, @@ -194,7 +220,8 @@ var lodash = require('lodash'), // backup content so we don't need to call the renderer a second // time when really rendering the column - row._renderedContent.data[column.id] = content; + row._renderedContent.data[column.id] = Object.isObject(content) ? content.content : content; + row._renderedContent.colSpan[column.id] = Object.isObject(content) ? content.colSpan : 1; row._renderedContent.dataHeight[column.id] = height; // check max row height