jspdf-autotable
Advanced tools
Comparing version 2.0.17 to 2.0.18
@@ -14,6 +14,6 @@ { | ||
"pdf", | ||
"table" | ||
"table", | ||
"jspdf" | ||
], | ||
"license": "MIT", | ||
"ignore": [] | ||
"license": "MIT" | ||
} |
51
build.js
var fs = require('fs'); | ||
var rollup = require('rollup'); | ||
var babel = require('rollup-plugin-babel'); | ||
var uglify = require("uglify-js"); | ||
switch(process.argv[2]) { | ||
case 'updateVersion': | ||
updateVersion(); | ||
switch (process.argv[2]) { | ||
case 'develop': | ||
build(false); | ||
break; | ||
case 'build': | ||
build(true); | ||
break; | ||
default: | ||
@@ -12,12 +18,33 @@ throw "Invalid type argument"; | ||
/** | ||
* Updates the plugin version in the dist files | ||
* Build the src version of jspdf-autotable | ||
*/ | ||
function updateVersion() { | ||
var v = require('./package.json').version; | ||
var distFiles = ['dist/jspdf.plugin.autotable.js', 'dist/jspdf.plugin.autotable.src.js']; | ||
for (var file of distFiles) { | ||
var lf = fs.readFileSync(file, 'utf8'); | ||
lf = lf.replace('__VERSION__', 'v' + v); | ||
fs.writeFileSync(file, lf); | ||
} | ||
function build(dist) { | ||
rollup.rollup({ | ||
entry: './src/main.js', | ||
plugins: [babel({presets: ["es2015-rollup"]})] | ||
}).then(function (bundle) { | ||
var code = bundle.generate({ | ||
format: 'iife', | ||
banner: '/** \n' + | ||
' * jsPDF AutoTable plugin v' + require('./package.json').version + '\n' + | ||
' * Copyright (c) 2014 Simon Bengtsson, https://github.com/simonbengtsson/jsPDF-AutoTable \n' + | ||
' * \n' + | ||
' * Licensed under the MIT License. \n' + | ||
' * http://opensource.org/licenses/mit-license \n' + | ||
' * \n' + | ||
' * @preserve \n' + | ||
' */' | ||
}).code; | ||
if (dist) { | ||
var minified = uglify.minify(code, {fromString: true, output: {comments: /@preserve|@license/i}}).code; | ||
fs.writeFileSync('./dist/jspdf.plugin.autotable.js', minified); | ||
fs.writeFileSync('./dist/jspdf.plugin.autotable.src.js', code); | ||
} | ||
fs.writeFileSync( './examples/libs/jspdf.plugin.autotable.src.js', code); | ||
console.log('Done'); | ||
}, function(err) { | ||
console.error(err); | ||
}); | ||
} |
@@ -1,10 +0,10 @@ | ||
/** | ||
* jsPDF AutoTable plugin v2.0.17 | ||
* Copyright (c) 2014 Simon Bengtsson, https://github.com/simonbengtsson/jsPDF-AutoTable | ||
* | ||
* Licensed under the MIT License. | ||
* http://opensource.org/licenses/mit-license | ||
* | ||
* @preserve | ||
/** | ||
* jsPDF AutoTable plugin v2.0.18 | ||
* Copyright (c) 2014 Simon Bengtsson, https://github.com/simonbengtsson/jsPDF-AutoTable | ||
* | ||
* Licensed under the MIT License. | ||
* http://opensource.org/licenses/mit-license | ||
* | ||
* @preserve | ||
*/ | ||
"use strict";function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}(function(API){"use strict";var FONT_ROW_RATIO=1.15;var doc,cursor,settings,pageCount,table;var defaultStyles={cellPadding:5,fontSize:10,font:"helvetica",lineColor:200,lineWidth:.1,fontStyle:"normal",overflow:"ellipsize",fillColor:255,textColor:20,halign:"left",valign:"top",fillStyle:"F",rowHeight:20,columnWidth:"auto"};var themes={striped:{table:{fillColor:255,textColor:80,fontStyle:"normal",fillStyle:"F"},header:{textColor:255,fillColor:[41,128,185],rowHeight:23,fontStyle:"bold"},body:{},alternateRow:{fillColor:245}},grid:{table:{fillColor:255,textColor:80,fontStyle:"normal",lineWidth:.1,fillStyle:"DF"},header:{textColor:255,fillColor:[26,188,156],rowHeight:23,fillStyle:"F",fontStyle:"bold"},body:{},alternateRow:{}},plain:{header:{fontStyle:"bold"}}};var defaultOptions=function defaultOptions(){return{theme:"striped",styles:{},headerStyles:{},bodyStyles:{},alternateRowStyles:{},columnStyles:{},startY:false,margin:40,pageBreak:"auto",tableWidth:"auto",createdHeaderCell:function createdHeaderCell(cell,data){},createdCell:function createdCell(cell,data){},drawHeaderRow:function drawHeaderRow(row,data){},drawRow:function drawRow(row,data){},drawHeaderCell:function drawHeaderCell(cell,data){},drawCell:function drawCell(cell,data){},beforePageContent:function beforePageContent(data){},afterPageContent:function afterPageContent(data){}}};API.autoTable=function(headers,data,options){validateInput(headers,data,options);doc=this;settings=initOptions(options||{});pageCount=1;cursor={y:settings.startY===false?settings.margin.top:settings.startY};var userStyles={textColor:30,fontSize:doc.internal.getFontSize(),fontStyle:doc.internal.getFont().fontStyle};createModels(headers,data);calculateWidths();var firstRowHeight=table.rows[0]&&settings.pageBreak==="auto"?table.rows[0].height:0;var minTableBottomPos=settings.startY+settings.margin.bottom+table.headerRow.height+firstRowHeight;if(settings.pageBreak==="avoid"){minTableBottomPos+=table.height}if(settings.pageBreak==="always"&&settings.startY!==false||settings.startY!==false&&minTableBottomPos>doc.internal.pageSize.height){doc.addPage();cursor.y=settings.margin.top}applyStyles(userStyles);settings.beforePageContent(hooksData());if(settings.drawHeaderRow(table.headerRow,hooksData({row:table.headerRow}))!==false){printRow(table.headerRow,settings.drawHeaderCell)}applyStyles(userStyles);printRows();settings.afterPageContent(hooksData());applyStyles(userStyles);return this};API.autoTableEndPosY=function(){if(typeof cursor==="undefined"||typeof cursor.y==="undefined"){return 0}return cursor.y};API.autoTableHtmlToJson=function(tableElem,includeHiddenRows){includeHiddenRows=includeHiddenRows||false;var header=tableElem.rows[0];var result={columns:[],rows:[]};for(var k=0;k<header.cells.length;k++){var cell=header.cells[k];result.columns.push(typeof cell!=="undefined"?cell.textContent:"")}for(var i=1;i<tableElem.rows.length;i++){var tableRow=tableElem.rows[i];var style=window.getComputedStyle(tableRow);if(includeHiddenRows||style.display!=="none"){var rowData=[];for(var j=0;j<header.cells.length;j++){rowData.push(typeof tableRow.cells[j]!=="undefined"?tableRow.cells[j].textContent:"")}result.rows.push(rowData)}}result.data=result.rows;return result};API.autoTableText=function(text,x,y,styles){if(typeof x!=="number"||typeof y!=="number"){console.error("The x and y parameters are required. Missing for the text: ",text)}var fontSize=doc.internal.getFontSize()/doc.internal.scaleFactor;var lineHeightProportion=FONT_ROW_RATIO;var splitRegex=/\r\n|\r|\n/g;var splittedText=null;var lineCount=1;if(styles.valign==="middle"||styles.valign==="bottom"||styles.halign==="center"||styles.halign==="right"){splittedText=typeof text==="string"?text.split(splitRegex):text;lineCount=splittedText.length||1}y+=fontSize*(2-lineHeightProportion);if(styles.valign==="middle")y-=lineCount/2*fontSize;else if(styles.valign==="bottom")y-=lineCount*fontSize;if(styles.halign==="center"||styles.halign==="right"){var alignSize=fontSize;if(styles.halign==="center")alignSize*=.5;if(lineCount>=1){for(var iLine=0;iLine<splittedText.length;iLine++){doc.text(splittedText[iLine],x-doc.getStringUnitWidth(splittedText[iLine])*alignSize,y);y+=fontSize}return doc}x-=doc.getStringUnitWidth(text)*alignSize}doc.text(text,x,y);return doc};function validateInput(headers,data,options){if(!headers||typeof headers!=="object"){console.error("The headers should be an object or array, is: "+typeof headers)}if(!data||typeof data!=="object"){console.error("The data should be an object or array, is: "+typeof data)}if(!!options&&typeof options!=="object"){console.error("The data should be an object or array, is: "+typeof data)}if(!Array.prototype.forEach){console.error("The current browser does not support Array.prototype.forEach which is required for "+"jsPDF-AutoTable. You can try polyfilling it by including this script "+"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill")}}function initOptions(userOptions){var settings=extend(defaultOptions(),userOptions);if(typeof settings.extendWidth!=="undefined"){settings.tableWidth=settings.extendWidth?"auto":"wrap";console.error("Use of deprecated option: extendWidth, use tableWidth instead.")}if(typeof settings.margins!=="undefined"){if(typeof settings.margin==="undefined")settings.margin=settings.margins;console.error("Use of deprecated option: margins, use margin instead.")}[["padding","cellPadding"],["lineHeight","rowHeight"],"fontSize","overflow"].forEach(function(o){var deprecatedOption=typeof o==="string"?o:o[0];var style=typeof o==="string"?o:o[1];if(typeof settings[deprecatedOption]!=="undefined"){if(typeof settings.styles[style]==="undefined"){settings.styles[style]=settings[deprecatedOption]}console.error("Use of deprecated option: "+deprecatedOption+", use the style "+style+" instead.")}});var marginSetting=settings.margin;settings.margin={};if(typeof marginSetting.horizontal==="number"){marginSetting.right=marginSetting.horizontal;marginSetting.left=marginSetting.horizontal}if(typeof marginSetting.vertical==="number"){marginSetting.top=marginSetting.vertical;marginSetting.bottom=marginSetting.vertical}["top","right","bottom","left"].forEach(function(side,i){if(typeof marginSetting==="number"){settings.margin[side]=marginSetting}else{var key=Array.isArray(marginSetting)?i:side;settings.margin[side]=typeof marginSetting[key]==="number"?marginSetting[key]:40}});return settings}function createModels(inputHeaders,inputData){table=new Table;table.x=settings.margin.left;var splitRegex=/\r\n|\r|\n/g;var headerRow=new Row(inputHeaders);headerRow.index=-1;var themeStyles=extend(defaultStyles,themes[settings.theme].table,themes[settings.theme].header);headerRow.styles=extend(themeStyles,settings.styles,settings.headerStyles);inputHeaders.forEach(function(rawColumn,dataKey){if(typeof rawColumn==="object"){dataKey=typeof rawColumn.dataKey!=="undefined"?rawColumn.dataKey:rawColumn.key}if(typeof rawColumn.width!=="undefined"){console.error("Use of deprecated option: column.width, use column.styles.columnWidth instead.")}var col=new Column(dataKey);col.styles=settings.columnStyles[col.dataKey]||{};table.columns.push(col);var cell=new Cell;cell.raw=typeof rawColumn==="object"?rawColumn.title:rawColumn;cell.styles=extend(headerRow.styles);cell.text=""+cell.raw;cell.contentWidth=cell.styles.cellPadding*2+getStringWidth(cell.text,cell.styles);cell.text=cell.text.split(splitRegex);headerRow.cells[dataKey]=cell;settings.createdHeaderCell(cell,{column:col,row:headerRow,settings:settings})});table.headerRow=headerRow;inputData.forEach(function(rawRow,i){var row=new Row(rawRow);var isAlternate=i%2===0;var themeStyles=extend(defaultStyles,themes[settings.theme].table,isAlternate?themes[settings.theme].alternateRow:{});var userStyles=extend(settings.styles,settings.bodyStyles,isAlternate?settings.alternateRowStyles:{});row.styles=extend(themeStyles,userStyles);row.index=i;table.columns.forEach(function(column){var cell=new Cell;cell.raw=rawRow[column.dataKey];cell.styles=extend(row.styles,column.styles);cell.text=typeof cell.raw!=="undefined"?""+cell.raw:"";row.cells[column.dataKey]=cell;settings.createdCell(cell,hooksData({column:column,row:row}));cell.contentWidth=cell.styles.cellPadding*2+getStringWidth(cell.text,cell.styles);cell.text=cell.text.split(splitRegex)});table.rows.push(row)})}function calculateWidths(){var tableContentWidth=0;table.columns.forEach(function(column){column.contentWidth=table.headerRow.cells[column.dataKey].contentWidth;table.rows.forEach(function(row){var cellWidth=row.cells[column.dataKey].contentWidth;if(cellWidth>column.contentWidth){column.contentWidth=cellWidth}});column.width=column.contentWidth;tableContentWidth+=column.contentWidth});table.contentWidth=tableContentWidth;var maxTableWidth=doc.internal.pageSize.width-settings.margin.left-settings.margin.right;var preferredTableWidth=maxTableWidth;if(typeof settings.tableWidth==="number"){preferredTableWidth=settings.tableWidth}else if(settings.tableWidth==="wrap"){preferredTableWidth=table.contentWidth}table.width=preferredTableWidth<maxTableWidth?preferredTableWidth:maxTableWidth;var dynamicColumns=[];var dynamicColumnsContentWidth=0;var fairWidth=table.width/table.columns.length;var staticWidth=0;table.columns.forEach(function(column){var colStyles=extend(defaultStyles,themes[settings.theme].table,settings.styles,column.styles);if(colStyles.columnWidth==="wrap"){column.width=column.contentWidth}else if(typeof colStyles.columnWidth==="number"){column.width=colStyles.columnWidth}else if(colStyles.columnWidth==="auto"||true){if(column.contentWidth<=fairWidth&&table.contentWidth>table.width){column.width=column.contentWidth}else{dynamicColumns.push(column);dynamicColumnsContentWidth+=column.contentWidth;column.width=0}}staticWidth+=column.width});distributeWidth(dynamicColumns,staticWidth,dynamicColumnsContentWidth,fairWidth);table.height=0;var all=table.rows.concat(table.headerRow);all.forEach(function(row,i){var lineBreakCount=0;var cursorX=table.x;table.columns.forEach(function(col){var cell=row.cells[col.dataKey];col.x=cursorX;applyStyles(cell.styles);var textSpace=col.width-cell.styles.cellPadding*2;if(cell.styles.overflow==="linebreak"){cell.text=doc.splitTextToSize(cell.text,textSpace+1,{fontSize:cell.styles.fontSize})}else if(cell.styles.overflow==="ellipsize"){cell.text=ellipsize(cell.text,textSpace,cell.styles)}else if(cell.styles.overflow==="visible"){}else if(cell.styles.overflow==="hidden"){cell.text=ellipsize(cell.text,textSpace,cell.styles,"")}else if(typeof cell.styles.overflow==="function"){cell.text=cell.styles.overflow(cell.text,textSpace)}else{console.error("Unrecognized overflow type: "+cell.styles.overflow)}var count=Array.isArray(cell.text)?cell.text.length-1:0;if(count>lineBreakCount){lineBreakCount=count}cursorX+=col.width});row.heightStyle=row.styles.rowHeight;row.height=row.heightStyle+lineBreakCount*row.styles.fontSize*FONT_ROW_RATIO;table.height+=row.height})}function distributeWidth(dynamicColumns,staticWidth,dynamicColumnsContentWidth,fairWidth){var extraWidth=table.width-staticWidth-dynamicColumnsContentWidth;for(var i=0;i<dynamicColumns.length;i++){var col=dynamicColumns[i];var ratio=col.contentWidth/dynamicColumnsContentWidth;var isNoneDynamic=col.contentWidth+extraWidth*ratio<fairWidth;if(extraWidth<0&&isNoneDynamic){dynamicColumns.splice(i,1);dynamicColumnsContentWidth-=col.contentWidth;col.width=fairWidth;staticWidth+=col.width;distributeWidth(dynamicColumns,staticWidth,dynamicColumnsContentWidth,fairWidth);break}else{col.width=col.contentWidth+extraWidth*ratio}}}function printRows(){table.rows.forEach(function(row,i){if(isNewPage(row.height)){var samePageThreshold=3;addPage()}row.y=cursor.y;if(settings.drawRow(row,hooksData({row:row}))!==false){printRow(row,settings.drawCell)}})}function addPage(){settings.afterPageContent(hooksData());doc.addPage();pageCount++;cursor={x:settings.margin.left,y:settings.margin.top};settings.beforePageContent(hooksData());if(settings.drawHeaderRow(table.headerRow,hooksData({row:table.headerRow}))!==false){printRow(table.headerRow,settings.drawHeaderCell)}}function isNewPage(rowHeight){var afterRowPos=cursor.y+rowHeight+settings.margin.bottom;return afterRowPos>=doc.internal.pageSize.height}function printRow(row,hookHandler){for(var i=0;i<table.columns.length;i++){var column=table.columns[i];var cell=row.cells[column.dataKey];if(!cell){continue}applyStyles(cell.styles);cell.x=column.x;cell.y=cursor.y;cell.height=row.height;cell.width=column.width;if(cell.styles.valign==="top"){cell.textPos.y=cursor.y+cell.styles.cellPadding}else if(cell.styles.valign==="bottom"){cell.textPos.y=cursor.y+row.height-cell.styles.cellPadding}else{cell.textPos.y=cursor.y+row.height/2}if(cell.styles.halign==="right"){cell.textPos.x=cell.x+cell.width-cell.styles.cellPadding}else if(cell.styles.halign==="center"){cell.textPos.x=cell.x+cell.width/2}else{cell.textPos.x=cell.x+cell.styles.cellPadding}var data=hooksData({column:column,row:row});if(hookHandler(cell,data)!==false){doc.rect(cell.x,cell.y,cell.width,cell.height,cell.styles.fillStyle);doc.autoTableText(cell.text,cell.textPos.x,cell.textPos.y,{halign:cell.styles.halign,valign:cell.styles.valign})}}cursor.y+=row.height}function applyStyles(styles){var arr=[{func:doc.setFillColor,value:styles.fillColor},{func:doc.setTextColor,value:styles.textColor},{func:doc.setFontStyle,value:styles.fontStyle},{func:doc.setDrawColor,value:styles.lineColor},{func:doc.setLineWidth,value:styles.lineWidth},{func:doc.setFont,value:styles.font},{func:doc.setFontSize,value:styles.fontSize}];arr.forEach(function(obj){if(typeof obj.value!=="undefined"){if(obj.value.constructor===Array){obj.func.apply(this,obj.value)}else{obj.func(obj.value)}}})}function hooksData(additionalData){additionalData=additionalData||{};var data={pageCount:pageCount,settings:settings,table:table,cursor:cursor};for(var prop in additionalData){if(additionalData.hasOwnProperty(prop)){data[prop]=additionalData[prop]}}return data}function ellipsize(text,width,styles,ellipsizeStr){ellipsizeStr=typeof ellipsizeStr!=="undefined"?ellipsizeStr:"...";if(Array.isArray(text)){text.forEach(function(str,i){text[i]=ellipsize(str,width,styles,ellipsizeStr)});return text}if(width>=getStringWidth(text,styles)){return text}while(width<getStringWidth(text+ellipsizeStr,styles)){if(text.length<2){break}text=text.substring(0,text.length-1)}return text.trim()+ellipsizeStr}function getStringWidth(text,styles){applyStyles(styles);var w=doc.getStringUnitWidth(text);return w*styles.fontSize}function extend(defaults){var extended={};var prop;for(prop in defaults){if(defaults.hasOwnProperty(prop)){extended[prop]=defaults[prop]}}for(var i=1;i<arguments.length;i++){var options=arguments[i];for(prop in options){if(options.hasOwnProperty(prop)){if(typeof options[prop]==="object"&&!Array.isArray(options[prop])){extended[prop]=options[prop]}else{extended[prop]=options[prop]}}}}return extended}})(jsPDF.API);var Table=function Table(){_classCallCheck(this,Table);this.height=0;this.width=0;this.x=0;this.y=0;this.contentWidth=0;this.rows=[];this.columns=[];this.headerRow=null;this.settings={}};var Row=function Row(raw){_classCallCheck(this,Row);this.raw=raw||{};this.index=0;this.styles={};this.cells={};this.height=0;this.y=0};var Cell=function Cell(raw){_classCallCheck(this,Cell);this.raw=raw;this.styles={};this.text="";this.contentWidth=0;this.textPos={};this.height=0;this.width=0;this.x=0;this.y=0};var Column=function Column(dataKey){_classCallCheck(this,Column);this.dataKey=dataKey;this.options={};this.styles={};this.contentWidth=0;this.width=0;this.x=0}; | ||
!function(){"use strict";function t(){return{theme:"striped",styles:{},headerStyles:{},bodyStyles:{},alternateRowStyles:{},columnStyles:{},startY:!1,margin:40,pageBreak:"auto",tableWidth:"auto",createdHeaderCell:function(t,e){},createdCell:function(t,e){},drawHeaderRow:function(t,e){},drawRow:function(t,e){},drawHeaderCell:function(t,e){},drawCell:function(t,e){},beforePageContent:function(t){},afterPageContent:function(t){}}}function e(){return{cellPadding:5,fontSize:10,font:"helvetica",lineColor:200,lineWidth:.1,fontStyle:"normal",overflow:"ellipsize",fillColor:255,textColor:20,halign:"left",valign:"top",fillStyle:"F",rowHeight:20,columnWidth:"auto"}}var n={};n["typeof"]="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},n.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},n.createClass=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}();var o=function d(){n.classCallCheck(this,d),this.height=0,this.width=0,this.contentWidth=0,this.rows=[],this.columns=[],this.headerRow=null,this.settings={},this.pageCount=1},i=function f(t){n.classCallCheck(this,f),this.raw=t||{},this.index=0,this.styles={},this.cells={},this.height=0,this.y=0},r=function c(t){n.classCallCheck(this,c),this.raw=t,this.styles={},this.text="",this.contentWidth=0,this.textPos={},this.height=0,this.width=0,this.x=0,this.y=0},l=function y(t){n.classCallCheck(this,y),this.dataKey=t,this.options={},this.styles={},this.contentWidth=0,this.width=0,this.x=0},a=1.15,s={striped:{table:{fillColor:255,textColor:80,fontStyle:"normal",fillStyle:"F"},header:{textColor:255,fillColor:[41,128,185],rowHeight:23,fontStyle:"bold"},body:{},alternateRow:{fillColor:245}},grid:{table:{fillColor:255,textColor:80,fontStyle:"normal",lineWidth:.1,fillStyle:"DF"},header:{textColor:255,fillColor:[26,188,156],rowHeight:23,fillStyle:"F",fontStyle:"bold"},body:{},alternateRow:{}},plain:{header:{fontStyle:"bold"}}},h=function(){function o(){n.classCallCheck(this,o)}return n.createClass(o,null,[{key:"initSettings",value:function(e){var n=Object.assign({},t(),e);"undefined"!=typeof n.extendWidth&&(n.tableWidth=n.extendWidth?"auto":"wrap",console.error("Use of deprecated option: extendWidth, use tableWidth instead.")),"undefined"!=typeof n.margins&&("undefined"==typeof n.margin&&(n.margin=n.margins),console.error("Use of deprecated option: margins, use margin instead.")),[["padding","cellPadding"],["lineHeight","rowHeight"],"fontSize","overflow"].forEach(function(t){var e="string"==typeof t?t:t[0],o="string"==typeof t?t:t[1];"undefined"!=typeof n[e]&&("undefined"==typeof n.styles[o]&&(n.styles[o]=n[e]),console.error("Use of deprecated option: "+e+", use the style "+o+" instead."))});var o=n.margin;return n.margin={},"number"==typeof o.horizontal&&(o.right=o.horizontal,o.left=o.horizontal),"number"==typeof o.vertical&&(o.top=o.vertical,o.bottom=o.vertical),["top","right","bottom","left"].forEach(function(t,e){if("number"==typeof o)n.margin[t]=o;else{var i=Array.isArray(o)?e:t;n.margin[t]="number"==typeof o[i]?o[i]:40}}),n}},{key:"styles",value:function(t){return t.unshift(e()),t.unshift({}),Object.assign.apply(this,t)}}]),o}();!function(t){function e(t,e,o){t&&"object"===("undefined"==typeof t?"undefined":n["typeof"](t))||console.error("The headers should be an object or array, is: "+("undefined"==typeof t?"undefined":n["typeof"](t))),e&&"object"===("undefined"==typeof e?"undefined":n["typeof"](e))||console.error("The data should be an object or array, is: "+("undefined"==typeof e?"undefined":n["typeof"](e))),o&&"object"!==("undefined"==typeof o?"undefined":n["typeof"](o))&&console.error("The data should be an object or array, is: "+("undefined"==typeof e?"undefined":n["typeof"](e))),Array.prototype.forEach||console.error("The current browser does not support Array.prototype.forEach which is required for jsPDF-AutoTable. You can try polyfilling it by including this script https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill")}function d(t,e){j=new o;var a=/\r\n|\r|\n/g,d=new i(t);d.index=-1;var f=h.styles([s[P.theme].table,s[P.theme].header]);d.styles=Object.assign({},f,P.styles,P.headerStyles),t.forEach(function(t,e){"object"===("undefined"==typeof t?"undefined":n["typeof"](t))&&(e="undefined"!=typeof t.dataKey?t.dataKey:t.key),"undefined"!=typeof t.width&&console.error("Use of deprecated option: column.width, use column.styles.columnWidth instead.");var o=new l(e);o.styles=P.columnStyles[o.dataKey]||{},j.columns.push(o);var i=new r;i.raw="object"===("undefined"==typeof t?"undefined":n["typeof"](t))?t.title:t,i.styles=Object.assign({},d.styles),i.text=""+i.raw,i.contentWidth=2*i.styles.cellPadding+m(i.text,i.styles),i.text=i.text.split(a),d.cells[e]=i,P.createdHeaderCell(i,{column:o,row:d,settings:P})}),j.headerRow=d,e.forEach(function(t,e){var n=new i(t),o=e%2===0,l=h.styles([s[P.theme].table,o?s[P.theme].alternateRow:{}]),d=Object.assign({},P.styles,P.bodyStyles,o?P.alternateRowStyles:{});n.styles=Object.assign({},l,d),n.index=e,j.columns.forEach(function(e){var o=new r;o.raw=t[e.dataKey],o.styles=Object.assign({},n.styles,e.styles),o.text="undefined"!=typeof o.raw?""+o.raw:"",n.cells[e.dataKey]=o,P.createdCell(o,b({column:e,row:n})),o.contentWidth=2*o.styles.cellPadding+m(o.text,o.styles),o.text=o.text.split(a)}),j.rows.push(n)})}function f(t,e){var n=0;j.columns.forEach(function(t){t.contentWidth=j.headerRow.cells[t.dataKey].contentWidth,j.rows.forEach(function(e){var n=e.cells[t.dataKey].contentWidth;n>t.contentWidth&&(t.contentWidth=n)}),t.width=t.contentWidth,n+=t.contentWidth}),j.contentWidth=n;var o=e-P.margin.left-P.margin.right,i=o;"number"==typeof P.tableWidth?i=P.tableWidth:"wrap"===P.tableWidth&&(i=j.contentWidth),j.width=o>i?i:o;var r=[],l=0,d=j.width/j.columns.length,f=0;j.columns.forEach(function(t){var e=h.styles([s[P.theme].table,P.styles,t.styles]);"wrap"===e.columnWidth?t.width=t.contentWidth:"number"==typeof e.columnWidth?t.width=e.columnWidth:("auto"===e.columnWidth,t.contentWidth<=d&&j.contentWidth>j.width?t.width=t.contentWidth:(r.push(t),l+=t.contentWidth,t.width=0)),f+=t.width}),c(r,f,l,d),j.height=0;var y=j.rows.concat(j.headerRow);y.forEach(function(e,n){var o=0;j.columns.forEach(function(n){var i=e.cells[n.dataKey];w(i.styles);var r=n.width-2*i.styles.cellPadding;"linebreak"===i.styles.overflow?i.text=t.splitTextToSize(i.text,r+1,{fontSize:i.styles.fontSize}):"ellipsize"===i.styles.overflow?i.text=v(i.text,r,i.styles):"visible"===i.styles.overflow||("hidden"===i.styles.overflow?i.text=v(i.text,r,i.styles,""):"function"==typeof i.styles.overflow?i.text=i.styles.overflow(i.text,r):console.error("Unrecognized overflow type: "+i.styles.overflow));var l=Array.isArray(i.text)?i.text.length-1:0;l>o&&(o=l)}),e.heightStyle=e.styles.rowHeight,e.height=e.heightStyle+o*e.styles.fontSize*a,j.height+=e.height})}function c(t,e,n,o){for(var i=j.width-e-n,r=0;r<t.length;r++){var l=t[r],a=l.contentWidth/n,s=l.contentWidth+i*a<o;if(0>i&&s){t.splice(r,1),n-=l.contentWidth,l.width=o,e+=l.width,c(t,e,n,o);break}l.width=l.contentWidth+i*a}}function y(t){P.afterPageContent(b()),t(),j.pageCount++,C={x:P.margin.left,y:P.margin.top},P.beforePageContent(b()),P.drawHeaderRow(j.headerRow,b({row:j.headerRow}))!==!1&&p(j.headerRow,P.drawHeaderCell)}function u(t){var e=C.y+t+P.margin.bottom;return e>=W.height}function g(t){j.rows.forEach(function(e,n){if(u(e.height)){y(t)}e.y=C.y,P.drawRow(e,b({row:e}))!==!1&&p(e,P.drawCell)})}function p(t,e){C.x=P.margin.left;for(var n=0;n<j.columns.length;n++){var o=j.columns[n],i=t.cells[o.dataKey];if(i){w(i.styles),i.x=C.x,i.y=C.y,i.height=t.height,i.width=o.width,"top"===i.styles.valign?i.textPos.y=C.y+i.styles.cellPadding:"bottom"===i.styles.valign?i.textPos.y=C.y+t.height-i.styles.cellPadding:i.textPos.y=C.y+t.height/2,"right"===i.styles.halign?i.textPos.x=i.x+i.width-i.styles.cellPadding:"center"===i.styles.halign?i.textPos.x=i.x+i.width/2:i.textPos.x=i.x+i.styles.cellPadding;var r=b({column:o,row:t});e(i,r)!==!1&&(x.rect(i.x,i.y,i.width,i.height,i.styles.fillStyle),x.autoTableText(i.text,i.textPos.x,i.textPos.y,{halign:i.styles.halign,valign:i.styles.valign})),C.x+=i.width}}C.y+=t.height}function w(t){Object.keys(S).forEach(function(e){var n=t[e],o=S[e];"undefined"!=typeof n&&(n.constructor===Array?o.apply(this,n):o(n))})}function b(t){return Object.assign({pageCount:j.pageCount,settings:P,table:j,cursor:C},t||{})}function m(t,e){w(e);var n=x.getStringUnitWidth(t);return n*e.fontSize}function v(t,e,n,o){if(o="undefined"!=typeof o?o:"...",Array.isArray(t))return t.forEach(function(i,r){t[r]=v(i,e,n,o)}),t;if(e>=m(t,n))return t;for(;e<m(t+o,n)&&!(t.length<2);)t=t.substring(0,t.length-1);return t.trim()+o}var x,C,S,W,P,j;t.autoTable=function(t,n,o){e(t,n,o),x=this,W=x.internal.pageSize,S={fillColor:x.setFillColor,textColor:x.setTextColor,fontStyle:x.setFontStyle,lineColor:x.setDrawColor,lineWidth:x.setLineWidth,font:x.setFont,fontSize:x.setFontSize},P=h.initSettings(o||{}),C={x:P.margin.left,y:P.startY===!1?P.margin.top:P.startY};var i={textColor:30,fontSize:x.internal.getFontSize(),fontStyle:x.internal.getFont().fontStyle};d(t,n),f(this,W.width);var r=j.rows[0]&&"auto"===P.pageBreak?j.rows[0].height:0,l=P.startY+P.margin.bottom+j.headerRow.height+r;return"avoid"===P.pageBreak&&(l+=j.height),("always"===P.pageBreak&&P.startY!==!1||P.startY!==!1&&l>W.height)&&(this.addPage(this.addPage),C.y=P.margin.top),w(i),P.beforePageContent(b()),P.drawHeaderRow(j.headerRow,b({row:j.headerRow}))!==!1&&p(j.headerRow,P.drawHeaderCell),w(i),g(this.addPage),P.afterPageContent(b()),w(i),this},t.autoTableEndPosY=function(){return"undefined"==typeof C||"undefined"==typeof C.y?0:C.y},t.autoTableHtmlToJson=function(t,e){e=e||!1;for(var n=t.rows[0],o={columns:[],rows:[]},i=0;i<n.cells.length;i++){var r=n.cells[i];o.columns.push("undefined"!=typeof r?r.textContent:"")}for(var l=1;l<t.rows.length;l++){var a=t.rows[l],s=window.getComputedStyle(a);if(e||"none"!==s.display){for(var h=[],d=0;d<n.cells.length;d++)h.push("undefined"!=typeof a.cells[d]?a.cells[d].textContent:"");o.rows.push(h)}}return o.data=o.rows,o},t.autoTableText=function(t,e,n,o){("number"!=typeof e||"number"!=typeof n)&&console.error("The x and y parameters are required. Missing for the text: ",t);var i=this.internal.getFontSize()/this.internal.scaleFactor,r=a,l=/\r\n|\r|\n/g,s=null,h=1;if(("middle"===o.valign||"bottom"===o.valign||"center"===o.halign||"right"===o.halign)&&(s="string"==typeof t?t.split(l):t,h=s.length||1),n+=i*(2-r),"middle"===o.valign?n-=h/2*i:"bottom"===o.valign&&(n-=h*i),"center"===o.halign||"right"===o.halign){var d=i;if("center"===o.halign&&(d*=.5),h>=1){for(var f=0;f<s.length;f++)this.text(s[f],e-this.getStringUnitWidth(s[f])*d,n),n+=i;return x}e-=this.getStringUnitWidth(t)*d}return this.text(t,e,n),this}}(jsPDF.API),"function"!=typeof Object.assign&&!function(){Object.assign=function(t){if(void 0===t||null===t)throw new TypeError("Cannot convert undefined or null to object");for(var e=Object(t),n=1;n<arguments.length;n++){var o=arguments[n];if(void 0!==o&&null!==o)for(var i in o)o.hasOwnProperty(i)&&(e[i]=o[i])}return e}}()}(); |
@@ -1,59 +0,107 @@ | ||
/** | ||
* jsPDF AutoTable plugin v2.0.17 | ||
* Copyright (c) 2014 Simon Bengtsson, https://github.com/simonbengtsson/jsPDF-AutoTable | ||
* | ||
* Licensed under the MIT License. | ||
* http://opensource.org/licenses/mit-license | ||
* | ||
* @preserve | ||
/** | ||
* jsPDF AutoTable plugin v2.0.18 | ||
* Copyright (c) 2014 Simon Bengtsson, https://github.com/simonbengtsson/jsPDF-AutoTable | ||
* | ||
* Licensed under the MIT License. | ||
* http://opensource.org/licenses/mit-license | ||
* | ||
* @preserve | ||
*/ | ||
'use strict'; | ||
(function () { | ||
'use strict'; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
var babelHelpers = {}; | ||
babelHelpers.typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { | ||
return typeof obj; | ||
} : function (obj) { | ||
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; | ||
}; | ||
(function (API) { | ||
'use strict'; | ||
babelHelpers.classCallCheck = function (instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
}; | ||
// Ratio between font size and font height. The number comes from jspdf's source code | ||
var FONT_ROW_RATIO = 1.15; | ||
babelHelpers.createClass = function () { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
var doc, // The current jspdf instance | ||
cursor, // An object keeping track of the x and y position of the next table cell to draw | ||
settings, // Default options merged with user options | ||
pageCount, // The page count the current table spans | ||
table; // The current Table instance | ||
return function (Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
}; | ||
}(); | ||
// Base style for all themes | ||
var defaultStyles = { | ||
cellPadding: 5, | ||
fontSize: 10, | ||
font: "helvetica", // helvetica, times, courier | ||
lineColor: 200, | ||
lineWidth: 0.1, | ||
fontStyle: 'normal', // normal, bold, italic, bolditalic | ||
overflow: 'ellipsize', // visible, hidden, ellipsize or linebreak | ||
fillColor: 255, | ||
textColor: 20, | ||
halign: 'left', // left, center, right | ||
valign: 'top', // top, middle, bottom | ||
fillStyle: 'F', // 'S', 'F' or 'DF' (stroke, fill or fill then stroke) | ||
rowHeight: 20, | ||
columnWidth: 'auto' | ||
babelHelpers; | ||
var Table = function Table() { | ||
babelHelpers.classCallCheck(this, Table); | ||
this.height = 0; | ||
this.width = 0; | ||
this.contentWidth = 0; | ||
this.rows = []; | ||
this.columns = []; | ||
this.headerRow = null; | ||
this.settings = {}; | ||
this.pageCount = 1; | ||
}; | ||
// Styles for the themes | ||
var Row = function Row(raw) { | ||
babelHelpers.classCallCheck(this, Row); | ||
this.raw = raw || {}; | ||
this.index = 0; | ||
this.styles = {}; | ||
this.cells = {}; | ||
this.height = 0; | ||
this.y = 0; | ||
}; | ||
var Cell = function Cell(raw) { | ||
babelHelpers.classCallCheck(this, Cell); | ||
this.raw = raw; | ||
this.styles = {}; | ||
this.text = ''; | ||
this.contentWidth = 0; | ||
this.textPos = {}; | ||
this.height = 0; | ||
this.width = 0; | ||
this.x = 0; | ||
this.y = 0; | ||
}; | ||
var Column = function Column(dataKey) { | ||
babelHelpers.classCallCheck(this, Column); | ||
this.dataKey = dataKey; | ||
this.options = {}; | ||
this.styles = {}; | ||
this.contentWidth = 0; | ||
this.width = 0; | ||
this.x = 0; | ||
}; | ||
/** | ||
* Ratio between font size and font height. The number comes from jspdf's source code | ||
*/ | ||
var FONT_ROW_RATIO = 1.15; | ||
/** | ||
* Styles for the themes (overriding the default styles) | ||
*/ | ||
var themes = { | ||
'striped': { | ||
table: { | ||
fillColor: 255, | ||
textColor: 80, | ||
fontStyle: 'normal', | ||
fillStyle: 'F' | ||
}, | ||
header: { | ||
textColor: 255, | ||
fillColor: [41, 128, 185], | ||
rowHeight: 23, | ||
fontStyle: 'bold' | ||
}, | ||
table: { fillColor: 255, textColor: 80, fontStyle: 'normal', fillStyle: 'F' }, | ||
header: { textColor: 255, fillColor: [41, 128, 185], rowHeight: 23, fontStyle: 'bold' }, | ||
body: {}, | ||
@@ -63,25 +111,13 @@ alternateRow: { fillColor: 245 } | ||
'grid': { | ||
table: { | ||
fillColor: 255, | ||
textColor: 80, | ||
fontStyle: 'normal', | ||
lineWidth: 0.1, | ||
fillStyle: 'DF' | ||
}, | ||
header: { | ||
textColor: 255, | ||
fillColor: [26, 188, 156], | ||
rowHeight: 23, | ||
fillStyle: 'F', | ||
fontStyle: 'bold' | ||
}, | ||
table: { fillColor: 255, textColor: 80, fontStyle: 'normal', lineWidth: 0.1, fillStyle: 'DF' }, | ||
header: { textColor: 255, fillColor: [26, 188, 156], rowHeight: 23, fillStyle: 'F', fontStyle: 'bold' }, | ||
body: {}, | ||
alternateRow: {} | ||
}, | ||
'plain': { header: { fontStyle: 'bold' } } | ||
'plain': { | ||
header: { fontStyle: 'bold' } | ||
} | ||
}; | ||
// See README.md for documentation of the options | ||
// See examples.js for usage examples | ||
var defaultOptions = function defaultOptions() { | ||
function getDefaults() { | ||
return { | ||
@@ -112,618 +148,622 @@ // Styling | ||
}; | ||
}; | ||
} | ||
/** | ||
* Create a table from a set of rows and columns. | ||
* | ||
* @param {Object[]|String[]} headers Either as an array of objects or array of strings | ||
* @param {Object[][]|String[][]} data Either as an array of objects or array of strings | ||
* @param {Object} [options={}] Options that will override the default ones | ||
*/ | ||
API.autoTable = function (headers, data, options) { | ||
validateInput(headers, data, options); | ||
doc = this; | ||
settings = initOptions(options || {}); | ||
pageCount = 1; | ||
// Base style for all themes | ||
function defaultStyles() { | ||
return { | ||
cellPadding: 5, | ||
fontSize: 10, | ||
font: "helvetica", // helvetica, times, courier | ||
lineColor: 200, | ||
lineWidth: 0.1, | ||
fontStyle: 'normal', // normal, bold, italic, bolditalic | ||
overflow: 'ellipsize', // visible, hidden, ellipsize or linebreak | ||
fillColor: 255, | ||
textColor: 20, | ||
halign: 'left', // left, center, right | ||
valign: 'top', // top, middle, bottom | ||
fillStyle: 'F', // 'S', 'F' or 'DF' (stroke, fill or fill then stroke) | ||
rowHeight: 20, | ||
columnWidth: 'auto' | ||
}; | ||
} | ||
// Need a cursor y as it needs to be reset after each page (row.y can't do that) | ||
cursor = { y: settings.startY === false ? settings.margin.top : settings.startY }; | ||
var Config = function () { | ||
function Config() { | ||
babelHelpers.classCallCheck(this, Config); | ||
} | ||
var userStyles = { | ||
textColor: 30, // Setting text color to dark gray as it can't be obtained from jsPDF | ||
fontSize: doc.internal.getFontSize(), | ||
fontStyle: doc.internal.getFont().fontStyle | ||
}; | ||
babelHelpers.createClass(Config, null, [{ | ||
key: 'initSettings', | ||
value: function initSettings(userOptions) { | ||
var settings = Object.assign({}, getDefaults(), userOptions); | ||
// Create the table model with its columns, rows and cells | ||
createModels(headers, data); | ||
calculateWidths(); | ||
// Options | ||
if (typeof settings.extendWidth !== 'undefined') { | ||
settings.tableWidth = settings.extendWidth ? 'auto' : 'wrap'; | ||
console.error("Use of deprecated option: extendWidth, use tableWidth instead."); | ||
} | ||
if (typeof settings.margins !== 'undefined') { | ||
if (typeof settings.margin === 'undefined') settings.margin = settings.margins; | ||
console.error("Use of deprecated option: margins, use margin instead."); | ||
} | ||
// Page break if there is room for only the first data row | ||
var firstRowHeight = table.rows[0] && settings.pageBreak === 'auto' ? table.rows[0].height : 0; | ||
var minTableBottomPos = settings.startY + settings.margin.bottom + table.headerRow.height + firstRowHeight; | ||
if (settings.pageBreak === 'avoid') { | ||
minTableBottomPos += table.height; | ||
} | ||
if (settings.pageBreak === 'always' && settings.startY !== false || settings.startY !== false && minTableBottomPos > doc.internal.pageSize.height) { | ||
doc.addPage(); | ||
cursor.y = settings.margin.top; | ||
} | ||
[['padding', 'cellPadding'], ['lineHeight', 'rowHeight'], 'fontSize', 'overflow'].forEach(function (o) { | ||
var deprecatedOption = typeof o === 'string' ? o : o[0]; | ||
var style = typeof o === 'string' ? o : o[1]; | ||
if (typeof settings[deprecatedOption] !== 'undefined') { | ||
if (typeof settings.styles[style] === 'undefined') { | ||
settings.styles[style] = settings[deprecatedOption]; | ||
} | ||
console.error("Use of deprecated option: " + deprecatedOption + ", use the style " + style + " instead."); | ||
} | ||
}); | ||
applyStyles(userStyles); | ||
settings.beforePageContent(hooksData()); | ||
if (settings.drawHeaderRow(table.headerRow, hooksData({ row: table.headerRow })) !== false) { | ||
printRow(table.headerRow, settings.drawHeaderCell); | ||
} | ||
applyStyles(userStyles); | ||
printRows(); | ||
settings.afterPageContent(hooksData()); | ||
// Unifying | ||
var marginSetting = settings.margin; | ||
settings.margin = {}; | ||
if (typeof marginSetting.horizontal === 'number') { | ||
marginSetting.right = marginSetting.horizontal; | ||
marginSetting.left = marginSetting.horizontal; | ||
} | ||
if (typeof marginSetting.vertical === 'number') { | ||
marginSetting.top = marginSetting.vertical; | ||
marginSetting.bottom = marginSetting.vertical; | ||
} | ||
['top', 'right', 'bottom', 'left'].forEach(function (side, i) { | ||
if (typeof marginSetting === 'number') { | ||
settings.margin[side] = marginSetting; | ||
} else { | ||
var key = Array.isArray(marginSetting) ? i : side; | ||
settings.margin[side] = typeof marginSetting[key] === 'number' ? marginSetting[key] : 40; | ||
} | ||
}); | ||
applyStyles(userStyles); | ||
return settings; | ||
} | ||
}, { | ||
key: 'styles', | ||
value: function styles(_styles) { | ||
_styles.unshift(defaultStyles()); | ||
_styles.unshift({}); | ||
return Object.assign.apply(this, _styles); | ||
} | ||
}]); | ||
return Config; | ||
}(); | ||
return this; | ||
}; | ||
(function (API) { | ||
'use strict'; | ||
/** | ||
* Returns the Y position of the last drawn cell | ||
* @returns int | ||
*/ | ||
API.autoTableEndPosY = function () { | ||
if (typeof cursor === 'undefined' || typeof cursor.y === 'undefined') { | ||
return 0; | ||
} | ||
return cursor.y; | ||
}; | ||
var doc, // The current jspdf instance | ||
cursor, // An object keeping track of the x and y position of the next table cell to draw | ||
styleModifiers, pageSize, settings, // Default options merged with user options | ||
table; // The current Table instance | ||
/** | ||
* Parses an html table | ||
* | ||
* @param tableElem Html table element | ||
* @param includeHiddenRows Defaults to false | ||
* @returns Object Object with two properties, columns and rows | ||
*/ | ||
API.autoTableHtmlToJson = function (tableElem, includeHiddenRows) { | ||
includeHiddenRows = includeHiddenRows || false; | ||
/** | ||
* Create a table from a set of rows and columns. | ||
* | ||
* @param {Object[]|String[]} headers Either as an array of objects or array of strings | ||
* @param {Object[][]|String[][]} data Either as an array of objects or array of strings | ||
* @param {Object} [options={}] Options that will override the default ones | ||
*/ | ||
API.autoTable = function (headers, data, options) { | ||
validateInput(headers, data, options); | ||
doc = this; | ||
var header = tableElem.rows[0]; | ||
var result = { columns: [], rows: [] }; | ||
pageSize = doc.internal.pageSize; | ||
styleModifiers = { | ||
fillColor: doc.setFillColor, | ||
textColor: doc.setTextColor, | ||
fontStyle: doc.setFontStyle, | ||
lineColor: doc.setDrawColor, | ||
lineWidth: doc.setLineWidth, | ||
font: doc.setFont, | ||
fontSize: doc.setFontSize | ||
}; | ||
for (var k = 0; k < header.cells.length; k++) { | ||
var cell = header.cells[k]; | ||
result.columns.push(typeof cell !== 'undefined' ? cell.textContent : ''); | ||
} | ||
settings = Config.initSettings(options || {}); | ||
for (var i = 1; i < tableElem.rows.length; i++) { | ||
var tableRow = tableElem.rows[i]; | ||
var style = window.getComputedStyle(tableRow); | ||
if (includeHiddenRows || style.display !== 'none') { | ||
var rowData = []; | ||
for (var j = 0; j < header.cells.length; j++) { | ||
rowData.push(typeof tableRow.cells[j] !== 'undefined' ? tableRow.cells[j].textContent : ''); | ||
} | ||
result.rows.push(rowData); | ||
// Need a cursor y as it needs to be reset after each page (row.y can't do that) | ||
// Also prefer cursor to column.x as the cursor is easier to modify in the hooks | ||
cursor = { | ||
x: settings.margin.left, | ||
y: settings.startY === false ? settings.margin.top : settings.startY | ||
}; | ||
var userStyles = { | ||
textColor: 30, // Setting text color to dark gray as it can't be obtained from jsPDF | ||
fontSize: doc.internal.getFontSize(), | ||
fontStyle: doc.internal.getFont().fontStyle | ||
}; | ||
// Create the table model with its columns, rows and cells | ||
createModels(headers, data); | ||
calculateWidths(this, pageSize.width); | ||
// Page break if there is room for only the first data row | ||
var firstRowHeight = table.rows[0] && settings.pageBreak === 'auto' ? table.rows[0].height : 0; | ||
var minTableBottomPos = settings.startY + settings.margin.bottom + table.headerRow.height + firstRowHeight; | ||
if (settings.pageBreak === 'avoid') { | ||
minTableBottomPos += table.height; | ||
} | ||
} | ||
if (settings.pageBreak === 'always' && settings.startY !== false || settings.startY !== false && minTableBottomPos > pageSize.height) { | ||
this.addPage(this.addPage); | ||
cursor.y = settings.margin.top; | ||
} | ||
result.data = result.rows; // Deprecated | ||
return result; | ||
}; | ||
applyStyles(userStyles); | ||
settings.beforePageContent(hooksData()); | ||
if (settings.drawHeaderRow(table.headerRow, hooksData({ row: table.headerRow })) !== false) { | ||
printRow(table.headerRow, settings.drawHeaderCell); | ||
} | ||
applyStyles(userStyles); | ||
printRows(this.addPage); | ||
settings.afterPageContent(hooksData()); | ||
/** | ||
* Improved text function with halign and valign support | ||
* Inspiration from: http://stackoverflow.com/questions/28327510/align-text-right-using-jspdf/28433113#28433113 | ||
*/ | ||
API.autoTableText = function (text, x, y, styles) { | ||
if (typeof x !== 'number' || typeof y !== 'number') { | ||
console.error('The x and y parameters are required. Missing for the text: ', text); | ||
} | ||
var fontSize = doc.internal.getFontSize() / doc.internal.scaleFactor; | ||
applyStyles(userStyles); | ||
// As defined in jsPDF source code | ||
var lineHeightProportion = FONT_ROW_RATIO; | ||
return this; | ||
}; | ||
var splitRegex = /\r\n|\r|\n/g; | ||
var splittedText = null; | ||
var lineCount = 1; | ||
if (styles.valign === 'middle' || styles.valign === 'bottom' || styles.halign === 'center' || styles.halign === 'right') { | ||
splittedText = typeof text === 'string' ? text.split(splitRegex) : text; | ||
/** | ||
* Returns the Y position of the last drawn cell | ||
* @returns int | ||
*/ | ||
API.autoTableEndPosY = function () { | ||
if (typeof cursor === 'undefined' || typeof cursor.y === 'undefined') { | ||
return 0; | ||
} | ||
return cursor.y; | ||
}; | ||
lineCount = splittedText.length || 1; | ||
} | ||
/** | ||
* Parses an html table | ||
* | ||
* @param tableElem Html table element | ||
* @param includeHiddenRows Defaults to false | ||
* @returns Object Object with two properties, columns and rows | ||
*/ | ||
API.autoTableHtmlToJson = function (tableElem, includeHiddenRows) { | ||
includeHiddenRows = includeHiddenRows || false; | ||
// Align the top | ||
y += fontSize * (2 - lineHeightProportion); | ||
var header = tableElem.rows[0]; | ||
var result = { columns: [], rows: [] }; | ||
if (styles.valign === 'middle') y -= lineCount / 2 * fontSize;else if (styles.valign === 'bottom') y -= lineCount * fontSize; | ||
for (var k = 0; k < header.cells.length; k++) { | ||
var cell = header.cells[k]; | ||
result.columns.push(typeof cell !== 'undefined' ? cell.textContent : ''); | ||
} | ||
if (styles.halign === 'center' || styles.halign === 'right') { | ||
var alignSize = fontSize; | ||
if (styles.halign === 'center') alignSize *= 0.5; | ||
if (lineCount >= 1) { | ||
for (var iLine = 0; iLine < splittedText.length; iLine++) { | ||
doc.text(splittedText[iLine], x - doc.getStringUnitWidth(splittedText[iLine]) * alignSize, y); | ||
y += fontSize; | ||
for (var i = 1; i < tableElem.rows.length; i++) { | ||
var tableRow = tableElem.rows[i]; | ||
var style = window.getComputedStyle(tableRow); | ||
if (includeHiddenRows || style.display !== 'none') { | ||
var rowData = []; | ||
for (var j = 0; j < header.cells.length; j++) { | ||
rowData.push(typeof tableRow.cells[j] !== 'undefined' ? tableRow.cells[j].textContent : ''); | ||
} | ||
result.rows.push(rowData); | ||
} | ||
return doc; | ||
} | ||
x -= doc.getStringUnitWidth(text) * alignSize; | ||
} | ||
doc.text(text, x, y); | ||
return doc; | ||
}; | ||
result.data = result.rows; // Deprecated | ||
return result; | ||
}; | ||
function validateInput(headers, data, options) { | ||
if (!headers || typeof headers !== 'object') { | ||
console.error("The headers should be an object or array, is: " + typeof headers); | ||
} | ||
/** | ||
* Improved text function with halign and valign support | ||
* Inspiration from: http://stackoverflow.com/questions/28327510/align-text-right-using-jspdf/28433113#28433113 | ||
*/ | ||
API.autoTableText = function (text, x, y, styles) { | ||
if (typeof x !== 'number' || typeof y !== 'number') { | ||
console.error('The x and y parameters are required. Missing for the text: ', text); | ||
} | ||
var fontSize = this.internal.getFontSize() / this.internal.scaleFactor; | ||
if (!data || typeof data !== 'object') { | ||
console.error("The data should be an object or array, is: " + typeof data); | ||
} | ||
// As defined in jsPDF source code | ||
var lineHeightProportion = FONT_ROW_RATIO; | ||
if (!!options && typeof options !== 'object') { | ||
console.error("The data should be an object or array, is: " + typeof data); | ||
} | ||
var splitRegex = /\r\n|\r|\n/g; | ||
var splittedText = null; | ||
var lineCount = 1; | ||
if (styles.valign === 'middle' || styles.valign === 'bottom' || styles.halign === 'center' || styles.halign === 'right') { | ||
splittedText = typeof text === 'string' ? text.split(splitRegex) : text; | ||
if (!Array.prototype.forEach) { | ||
console.error("The current browser does not support Array.prototype.forEach which is required for " + "jsPDF-AutoTable. You can try polyfilling it by including this script " + "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill"); | ||
} | ||
} | ||
lineCount = splittedText.length || 1; | ||
} | ||
function initOptions(userOptions) { | ||
var settings = extend(defaultOptions(), userOptions); | ||
// Align the top | ||
y += fontSize * (2 - lineHeightProportion); | ||
// Options | ||
if (typeof settings.extendWidth !== 'undefined') { | ||
settings.tableWidth = settings.extendWidth ? 'auto' : 'wrap'; | ||
console.error("Use of deprecated option: extendWidth, use tableWidth instead."); | ||
} | ||
if (typeof settings.margins !== 'undefined') { | ||
if (typeof settings.margin === 'undefined') settings.margin = settings.margins; | ||
console.error("Use of deprecated option: margins, use margin instead."); | ||
} | ||
if (styles.valign === 'middle') y -= lineCount / 2 * fontSize;else if (styles.valign === 'bottom') y -= lineCount * fontSize; | ||
[['padding', 'cellPadding'], ['lineHeight', 'rowHeight'], 'fontSize', 'overflow'].forEach(function (o) { | ||
var deprecatedOption = typeof o === 'string' ? o : o[0]; | ||
var style = typeof o === 'string' ? o : o[1]; | ||
if (typeof settings[deprecatedOption] !== 'undefined') { | ||
if (typeof settings.styles[style] === 'undefined') { | ||
settings.styles[style] = settings[deprecatedOption]; | ||
if (styles.halign === 'center' || styles.halign === 'right') { | ||
var alignSize = fontSize; | ||
if (styles.halign === 'center') alignSize *= 0.5; | ||
if (lineCount >= 1) { | ||
for (var iLine = 0; iLine < splittedText.length; iLine++) { | ||
this.text(splittedText[iLine], x - this.getStringUnitWidth(splittedText[iLine]) * alignSize, y); | ||
y += fontSize; | ||
} | ||
return doc; | ||
} | ||
console.error("Use of deprecated option: " + deprecatedOption + ", use the style " + style + " instead."); | ||
x -= this.getStringUnitWidth(text) * alignSize; | ||
} | ||
}); | ||
// Unifying | ||
var marginSetting = settings.margin; | ||
settings.margin = {}; | ||
if (typeof marginSetting.horizontal === 'number') { | ||
marginSetting.right = marginSetting.horizontal; | ||
marginSetting.left = marginSetting.horizontal; | ||
} | ||
if (typeof marginSetting.vertical === 'number') { | ||
marginSetting.top = marginSetting.vertical; | ||
marginSetting.bottom = marginSetting.vertical; | ||
} | ||
['top', 'right', 'bottom', 'left'].forEach(function (side, i) { | ||
if (typeof marginSetting === 'number') { | ||
settings.margin[side] = marginSetting; | ||
} else { | ||
var key = Array.isArray(marginSetting) ? i : side; | ||
settings.margin[side] = typeof marginSetting[key] === 'number' ? marginSetting[key] : 40; | ||
this.text(text, x, y); | ||
return this; | ||
}; | ||
function validateInput(headers, data, options) { | ||
if (!headers || (typeof headers === 'undefined' ? 'undefined' : babelHelpers.typeof(headers)) !== 'object') { | ||
console.error("The headers should be an object or array, is: " + (typeof headers === 'undefined' ? 'undefined' : babelHelpers.typeof(headers))); | ||
} | ||
}); | ||
return settings; | ||
} | ||
if (!data || (typeof data === 'undefined' ? 'undefined' : babelHelpers.typeof(data)) !== 'object') { | ||
console.error("The data should be an object or array, is: " + (typeof data === 'undefined' ? 'undefined' : babelHelpers.typeof(data))); | ||
} | ||
/** | ||
* Create models from the user input | ||
* | ||
* @param inputHeaders | ||
* @param inputData | ||
*/ | ||
function createModels(inputHeaders, inputData) { | ||
table = new Table(); | ||
table.x = settings.margin.left; | ||
if (!!options && (typeof options === 'undefined' ? 'undefined' : babelHelpers.typeof(options)) !== 'object') { | ||
console.error("The data should be an object or array, is: " + (typeof data === 'undefined' ? 'undefined' : babelHelpers.typeof(data))); | ||
} | ||
var splitRegex = /\r\n|\r|\n/g; | ||
if (!Array.prototype.forEach) { | ||
console.error("The current browser does not support Array.prototype.forEach which is required for " + "jsPDF-AutoTable. You can try polyfilling it by including this script " + "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill"); | ||
} | ||
} | ||
// Header row and columns | ||
var headerRow = new Row(inputHeaders); | ||
headerRow.index = -1; | ||
/** | ||
* Create models from the user input | ||
* | ||
* @param inputHeaders | ||
* @param inputData | ||
*/ | ||
function createModels(inputHeaders, inputData) { | ||
table = new Table(); | ||
var themeStyles = extend(defaultStyles, themes[settings.theme].table, themes[settings.theme].header); | ||
headerRow.styles = extend(themeStyles, settings.styles, settings.headerStyles); | ||
var splitRegex = /\r\n|\r|\n/g; | ||
// Columns and header row | ||
inputHeaders.forEach(function (rawColumn, dataKey) { | ||
if (typeof rawColumn === 'object') { | ||
dataKey = typeof rawColumn.dataKey !== 'undefined' ? rawColumn.dataKey : rawColumn.key; | ||
} | ||
// Header row and columns | ||
var headerRow = new Row(inputHeaders); | ||
headerRow.index = -1; | ||
if (typeof rawColumn.width !== 'undefined') { | ||
console.error("Use of deprecated option: column.width, use column.styles.columnWidth instead."); | ||
} | ||
var themeStyles = Config.styles([themes[settings.theme].table, themes[settings.theme].header]); | ||
headerRow.styles = Object.assign({}, themeStyles, settings.styles, settings.headerStyles); | ||
var col = new Column(dataKey); | ||
col.styles = settings.columnStyles[col.dataKey] || {}; | ||
table.columns.push(col); | ||
// Columns and header row | ||
inputHeaders.forEach(function (rawColumn, dataKey) { | ||
if ((typeof rawColumn === 'undefined' ? 'undefined' : babelHelpers.typeof(rawColumn)) === 'object') { | ||
dataKey = typeof rawColumn.dataKey !== 'undefined' ? rawColumn.dataKey : rawColumn.key; | ||
} | ||
var cell = new Cell(); | ||
cell.raw = typeof rawColumn === 'object' ? rawColumn.title : rawColumn; | ||
cell.styles = extend(headerRow.styles); | ||
cell.text = '' + cell.raw; | ||
cell.contentWidth = cell.styles.cellPadding * 2 + getStringWidth(cell.text, cell.styles); | ||
cell.text = cell.text.split(splitRegex); | ||
if (typeof rawColumn.width !== 'undefined') { | ||
console.error("Use of deprecated option: column.width, use column.styles.columnWidth instead."); | ||
} | ||
headerRow.cells[dataKey] = cell; | ||
settings.createdHeaderCell(cell, { column: col, row: headerRow, settings: settings }); | ||
}); | ||
table.headerRow = headerRow; | ||
var col = new Column(dataKey); | ||
col.styles = settings.columnStyles[col.dataKey] || {}; | ||
table.columns.push(col); | ||
// Rows och cells | ||
inputData.forEach(function (rawRow, i) { | ||
var row = new Row(rawRow); | ||
var isAlternate = i % 2 === 0; | ||
var themeStyles = extend(defaultStyles, themes[settings.theme].table, isAlternate ? themes[settings.theme].alternateRow : {}); | ||
var userStyles = extend(settings.styles, settings.bodyStyles, isAlternate ? settings.alternateRowStyles : {}); | ||
row.styles = extend(themeStyles, userStyles); | ||
row.index = i; | ||
table.columns.forEach(function (column) { | ||
var cell = new Cell(); | ||
cell.raw = rawRow[column.dataKey]; | ||
cell.styles = extend(row.styles, column.styles); | ||
cell.text = typeof cell.raw !== 'undefined' ? '' + cell.raw : ''; // Stringify 0 and false, but not undefined | ||
row.cells[column.dataKey] = cell; | ||
settings.createdCell(cell, hooksData({ column: column, row: row })); | ||
cell.raw = (typeof rawColumn === 'undefined' ? 'undefined' : babelHelpers.typeof(rawColumn)) === 'object' ? rawColumn.title : rawColumn; | ||
cell.styles = Object.assign({}, headerRow.styles); | ||
cell.text = '' + cell.raw; | ||
cell.contentWidth = cell.styles.cellPadding * 2 + getStringWidth(cell.text, cell.styles); | ||
cell.text = cell.text.split(splitRegex); | ||
headerRow.cells[dataKey] = cell; | ||
settings.createdHeaderCell(cell, { column: col, row: headerRow, settings: settings }); | ||
}); | ||
table.rows.push(row); | ||
}); | ||
} | ||
table.headerRow = headerRow; | ||
/** | ||
* Calculate the column widths | ||
*/ | ||
function calculateWidths() { | ||
// Column and table content width | ||
var tableContentWidth = 0; | ||
table.columns.forEach(function (column) { | ||
column.contentWidth = table.headerRow.cells[column.dataKey].contentWidth; | ||
table.rows.forEach(function (row) { | ||
var cellWidth = row.cells[column.dataKey].contentWidth; | ||
if (cellWidth > column.contentWidth) { | ||
column.contentWidth = cellWidth; | ||
} | ||
// Rows och cells | ||
inputData.forEach(function (rawRow, i) { | ||
var row = new Row(rawRow); | ||
var isAlternate = i % 2 === 0; | ||
var themeStyles = Config.styles([themes[settings.theme].table, isAlternate ? themes[settings.theme].alternateRow : {}]); | ||
var userStyles = Object.assign({}, settings.styles, settings.bodyStyles, isAlternate ? settings.alternateRowStyles : {}); | ||
row.styles = Object.assign({}, themeStyles, userStyles); | ||
row.index = i; | ||
table.columns.forEach(function (column) { | ||
var cell = new Cell(); | ||
cell.raw = rawRow[column.dataKey]; | ||
cell.styles = Object.assign({}, row.styles, column.styles); | ||
cell.text = typeof cell.raw !== 'undefined' ? '' + cell.raw : ''; // Stringify 0 and false, but not undefined | ||
row.cells[column.dataKey] = cell; | ||
settings.createdCell(cell, hooksData({ column: column, row: row })); | ||
cell.contentWidth = cell.styles.cellPadding * 2 + getStringWidth(cell.text, cell.styles); | ||
cell.text = cell.text.split(splitRegex); | ||
}); | ||
table.rows.push(row); | ||
}); | ||
column.width = column.contentWidth; | ||
tableContentWidth += column.contentWidth; | ||
}); | ||
table.contentWidth = tableContentWidth; | ||
var maxTableWidth = doc.internal.pageSize.width - settings.margin.left - settings.margin.right; | ||
var preferredTableWidth = maxTableWidth; // settings.tableWidth === 'auto' | ||
if (typeof settings.tableWidth === 'number') { | ||
preferredTableWidth = settings.tableWidth; | ||
} else if (settings.tableWidth === 'wrap') { | ||
preferredTableWidth = table.contentWidth; | ||
} | ||
table.width = preferredTableWidth < maxTableWidth ? preferredTableWidth : maxTableWidth; | ||
// To avoid subjecting columns with little content with the chosen overflow method, | ||
// never shrink a column more than the table divided by column count (its "fair part") | ||
var dynamicColumns = []; | ||
var dynamicColumnsContentWidth = 0; | ||
var fairWidth = table.width / table.columns.length; | ||
var staticWidth = 0; | ||
table.columns.forEach(function (column) { | ||
var colStyles = extend(defaultStyles, themes[settings.theme].table, settings.styles, column.styles); | ||
if (colStyles.columnWidth === 'wrap') { | ||
/** | ||
* Calculate the column widths | ||
*/ | ||
function calculateWidths(doc, pageWidth) { | ||
// Column and table content width | ||
var tableContentWidth = 0; | ||
table.columns.forEach(function (column) { | ||
column.contentWidth = table.headerRow.cells[column.dataKey].contentWidth; | ||
table.rows.forEach(function (row) { | ||
var cellWidth = row.cells[column.dataKey].contentWidth; | ||
if (cellWidth > column.contentWidth) { | ||
column.contentWidth = cellWidth; | ||
} | ||
}); | ||
column.width = column.contentWidth; | ||
} else if (typeof colStyles.columnWidth === 'number') { | ||
column.width = colStyles.columnWidth; | ||
} else if (colStyles.columnWidth === 'auto' || true) { | ||
if (column.contentWidth <= fairWidth && table.contentWidth > table.width) { | ||
column.width = column.contentWidth; | ||
} else { | ||
dynamicColumns.push(column); | ||
dynamicColumnsContentWidth += column.contentWidth; | ||
column.width = 0; | ||
} | ||
tableContentWidth += column.contentWidth; | ||
}); | ||
table.contentWidth = tableContentWidth; | ||
var maxTableWidth = pageWidth - settings.margin.left - settings.margin.right; | ||
var preferredTableWidth = maxTableWidth; // settings.tableWidth === 'auto' | ||
if (typeof settings.tableWidth === 'number') { | ||
preferredTableWidth = settings.tableWidth; | ||
} else if (settings.tableWidth === 'wrap') { | ||
preferredTableWidth = table.contentWidth; | ||
} | ||
staticWidth += column.width; | ||
}); | ||
table.width = preferredTableWidth < maxTableWidth ? preferredTableWidth : maxTableWidth; | ||
// Distributes extra width or trims columns down to fit | ||
distributeWidth(dynamicColumns, staticWidth, dynamicColumnsContentWidth, fairWidth); | ||
// Row height, table height and text overflow | ||
table.height = 0; | ||
var all = table.rows.concat(table.headerRow); | ||
all.forEach(function (row, i) { | ||
var lineBreakCount = 0; | ||
var cursorX = table.x; | ||
table.columns.forEach(function (col) { | ||
var cell = row.cells[col.dataKey]; | ||
col.x = cursorX; | ||
applyStyles(cell.styles); | ||
var textSpace = col.width - cell.styles.cellPadding * 2; | ||
if (cell.styles.overflow === 'linebreak') { | ||
// Add one pt to textSpace to fix rounding error | ||
cell.text = doc.splitTextToSize(cell.text, textSpace + 1, { fontSize: cell.styles.fontSize }); | ||
} else if (cell.styles.overflow === 'ellipsize') { | ||
cell.text = ellipsize(cell.text, textSpace, cell.styles); | ||
} else if (cell.styles.overflow === 'visible') { | ||
// Do nothing | ||
} else if (cell.styles.overflow === 'hidden') { | ||
cell.text = ellipsize(cell.text, textSpace, cell.styles, ''); | ||
} else if (typeof cell.styles.overflow === 'function') { | ||
cell.text = cell.styles.overflow(cell.text, textSpace); | ||
// To avoid subjecting columns with little content with the chosen overflow method, | ||
// never shrink a column more than the table divided by column count (its "fair part") | ||
var dynamicColumns = []; | ||
var dynamicColumnsContentWidth = 0; | ||
var fairWidth = table.width / table.columns.length; | ||
var staticWidth = 0; | ||
table.columns.forEach(function (column) { | ||
var colStyles = Config.styles([themes[settings.theme].table, settings.styles, column.styles]); | ||
if (colStyles.columnWidth === 'wrap') { | ||
column.width = column.contentWidth; | ||
} else if (typeof colStyles.columnWidth === 'number') { | ||
column.width = colStyles.columnWidth; | ||
} else if (colStyles.columnWidth === 'auto' || true) { | ||
if (column.contentWidth <= fairWidth && table.contentWidth > table.width) { | ||
column.width = column.contentWidth; | ||
} else { | ||
console.error("Unrecognized overflow type: " + cell.styles.overflow); | ||
dynamicColumns.push(column); | ||
dynamicColumnsContentWidth += column.contentWidth; | ||
column.width = 0; | ||
} | ||
var count = Array.isArray(cell.text) ? cell.text.length - 1 : 0; | ||
if (count > lineBreakCount) { | ||
lineBreakCount = count; | ||
} | ||
cursorX += col.width; | ||
staticWidth += column.width; | ||
}); | ||
row.heightStyle = row.styles.rowHeight; | ||
// TODO Pick the highest row based on font size as well | ||
row.height = row.heightStyle + lineBreakCount * row.styles.fontSize * FONT_ROW_RATIO; | ||
table.height += row.height; | ||
}); | ||
} | ||
// Distributes extra width or trims columns down to fit | ||
distributeWidth(dynamicColumns, staticWidth, dynamicColumnsContentWidth, fairWidth); | ||
function distributeWidth(dynamicColumns, staticWidth, dynamicColumnsContentWidth, fairWidth) { | ||
var extraWidth = table.width - staticWidth - dynamicColumnsContentWidth; | ||
for (var i = 0; i < dynamicColumns.length; i++) { | ||
var col = dynamicColumns[i]; | ||
var ratio = col.contentWidth / dynamicColumnsContentWidth; | ||
// A column turned out to be none dynamic, start over recursively | ||
var isNoneDynamic = col.contentWidth + extraWidth * ratio < fairWidth; | ||
if (extraWidth < 0 && isNoneDynamic) { | ||
dynamicColumns.splice(i, 1); | ||
dynamicColumnsContentWidth -= col.contentWidth; | ||
col.width = fairWidth; | ||
staticWidth += col.width; | ||
distributeWidth(dynamicColumns, staticWidth, dynamicColumnsContentWidth, fairWidth); | ||
break; | ||
} else { | ||
col.width = col.contentWidth + extraWidth * ratio; | ||
} | ||
} | ||
} | ||
function printRows() { | ||
table.rows.forEach(function (row, i) { | ||
if (isNewPage(row.height)) { | ||
var samePageThreshold = 3; | ||
// TODO Fix cell height > pageHeight | ||
/*if (row.height > row.heightStyle * samePageThreshold) { | ||
var remainingPageSpace = doc.internal.pageSize.height - cursor.y - settings.margin.bottom; | ||
var lineCount = Math.floor(remainingPageSpace / (row.styles.fontSize * FONT_ROW_RATIO)); | ||
table.columns.forEach(function(col) { | ||
var arr = row.cells[col.dataKey].text; | ||
if (arr.length > lineCount) { | ||
arr.splice(lineCount - 1, arr.length, "..."); | ||
// Row height, table height and text overflow | ||
table.height = 0; | ||
var all = table.rows.concat(table.headerRow); | ||
all.forEach(function (row, i) { | ||
var lineBreakCount = 0; | ||
table.columns.forEach(function (col) { | ||
var cell = row.cells[col.dataKey]; | ||
applyStyles(cell.styles); | ||
var textSpace = col.width - cell.styles.cellPadding * 2; | ||
if (cell.styles.overflow === 'linebreak') { | ||
// Add one pt to textSpace to fix rounding error | ||
cell.text = doc.splitTextToSize(cell.text, textSpace + 1, { fontSize: cell.styles.fontSize }); | ||
} else if (cell.styles.overflow === 'ellipsize') { | ||
cell.text = ellipsize(cell.text, textSpace, cell.styles); | ||
} else if (cell.styles.overflow === 'visible') { | ||
// Do nothing | ||
} else if (cell.styles.overflow === 'hidden') { | ||
cell.text = ellipsize(cell.text, textSpace, cell.styles, ''); | ||
} else if (typeof cell.styles.overflow === 'function') { | ||
cell.text = cell.styles.overflow(cell.text, textSpace); | ||
} else { | ||
console.error("Unrecognized overflow type: " + cell.styles.overflow); | ||
} | ||
}); | ||
row.height = remainingPageSpace; | ||
if (settings.drawRow(row, hooksData({row: row})) !== false) { | ||
printRow(row, settings.drawCell); | ||
var count = Array.isArray(cell.text) ? cell.text.length - 1 : 0; | ||
if (count > lineBreakCount) { | ||
lineBreakCount = count; | ||
} | ||
row = new Row(rawRow); | ||
}*/ | ||
addPage(); | ||
} | ||
row.y = cursor.y; | ||
if (settings.drawRow(row, hooksData({ row: row })) !== false) { | ||
printRow(row, settings.drawCell); | ||
} | ||
}); | ||
} | ||
}); | ||
function addPage() { | ||
settings.afterPageContent(hooksData()); | ||
doc.addPage(); | ||
pageCount++; | ||
cursor = { x: settings.margin.left, y: settings.margin.top }; | ||
settings.beforePageContent(hooksData()); | ||
if (settings.drawHeaderRow(table.headerRow, hooksData({ row: table.headerRow })) !== false) { | ||
printRow(table.headerRow, settings.drawHeaderCell); | ||
row.heightStyle = row.styles.rowHeight; | ||
// TODO Pick the highest row based on font size as well | ||
row.height = row.heightStyle + lineBreakCount * row.styles.fontSize * FONT_ROW_RATIO; | ||
table.height += row.height; | ||
}); | ||
} | ||
} | ||
/** | ||
* Add a new page if cursor is at the end of page | ||
* @param rowHeight | ||
* @returns {boolean} | ||
*/ | ||
function isNewPage(rowHeight) { | ||
var afterRowPos = cursor.y + rowHeight + settings.margin.bottom; | ||
return afterRowPos >= doc.internal.pageSize.height; | ||
} | ||
function printRow(row, hookHandler) { | ||
for (var i = 0; i < table.columns.length; i++) { | ||
var column = table.columns[i]; | ||
var cell = row.cells[column.dataKey]; | ||
if (!cell) { | ||
continue; | ||
function distributeWidth(dynamicColumns, staticWidth, dynamicColumnsContentWidth, fairWidth) { | ||
var extraWidth = table.width - staticWidth - dynamicColumnsContentWidth; | ||
for (var i = 0; i < dynamicColumns.length; i++) { | ||
var col = dynamicColumns[i]; | ||
var ratio = col.contentWidth / dynamicColumnsContentWidth; | ||
// A column turned out to be none dynamic, start over recursively | ||
var isNoneDynamic = col.contentWidth + extraWidth * ratio < fairWidth; | ||
if (extraWidth < 0 && isNoneDynamic) { | ||
dynamicColumns.splice(i, 1); | ||
dynamicColumnsContentWidth -= col.contentWidth; | ||
col.width = fairWidth; | ||
staticWidth += col.width; | ||
distributeWidth(dynamicColumns, staticWidth, dynamicColumnsContentWidth, fairWidth); | ||
break; | ||
} else { | ||
col.width = col.contentWidth + extraWidth * ratio; | ||
} | ||
} | ||
applyStyles(cell.styles); | ||
} | ||
cell.x = column.x; | ||
cell.y = cursor.y; | ||
cell.height = row.height; | ||
cell.width = column.width; | ||
if (cell.styles.valign === 'top') { | ||
cell.textPos.y = cursor.y + cell.styles.cellPadding; | ||
} else if (cell.styles.valign === 'bottom') { | ||
cell.textPos.y = cursor.y + row.height - cell.styles.cellPadding; | ||
} else { | ||
cell.textPos.y = cursor.y + row.height / 2; | ||
function addPage(jspdfAddPage) { | ||
settings.afterPageContent(hooksData()); | ||
jspdfAddPage(); | ||
table.pageCount++; | ||
cursor = { x: settings.margin.left, y: settings.margin.top }; | ||
settings.beforePageContent(hooksData()); | ||
if (settings.drawHeaderRow(table.headerRow, hooksData({ row: table.headerRow })) !== false) { | ||
printRow(table.headerRow, settings.drawHeaderCell); | ||
} | ||
} | ||
if (cell.styles.halign === 'right') { | ||
cell.textPos.x = cell.x + cell.width - cell.styles.cellPadding; | ||
} else if (cell.styles.halign === 'center') { | ||
cell.textPos.x = cell.x + cell.width / 2; | ||
} else { | ||
cell.textPos.x = cell.x + cell.styles.cellPadding; | ||
} | ||
/** | ||
* Add a new page if cursor is at the end of page | ||
*/ | ||
function isNewPage(rowHeight) { | ||
var afterRowPos = cursor.y + rowHeight + settings.margin.bottom; | ||
return afterRowPos >= pageSize.height; | ||
} | ||
var data = hooksData({ column: column, row: row }); | ||
if (hookHandler(cell, data) !== false) { | ||
doc.rect(cell.x, cell.y, cell.width, cell.height, cell.styles.fillStyle); | ||
doc.autoTableText(cell.text, cell.textPos.x, cell.textPos.y, { | ||
halign: cell.styles.halign, | ||
valign: cell.styles.valign | ||
}); | ||
} | ||
function printRows(jspdfAddPage) { | ||
table.rows.forEach(function (row, i) { | ||
if (isNewPage(row.height)) { | ||
var samePageThreshold = 3; | ||
// TODO Fix cell height > page height | ||
/*if (row.height > row.heightStyle * samePageThreshold) { | ||
var remainingPageSpace = pageSize.height - cursor.y - settings.margin.bottom; | ||
var lineCount = Math.floor(remainingPageSpace / (row.styles.fontSize * FONT_ROW_RATIO)); | ||
table.columns.forEach(function(col) { | ||
var arr = row.cells[col.dataKey].text; | ||
if (arr.length > lineCount) { | ||
arr.splice(lineCount - 1, arr.length, "..."); | ||
} | ||
}); | ||
row.height = remainingPageSpace; | ||
if (settings.drawRow(row, hooksData({row: row})) !== false) { | ||
printRow(row, settings.drawCell); | ||
} | ||
row = new Row(rawRow); | ||
}*/ | ||
addPage(jspdfAddPage); | ||
} | ||
row.y = cursor.y; | ||
if (settings.drawRow(row, hooksData({ row: row })) !== false) { | ||
printRow(row, settings.drawCell); | ||
} | ||
}); | ||
} | ||
cursor.y += row.height; | ||
} | ||
function printRow(row, hookHandler) { | ||
cursor.x = settings.margin.left; | ||
for (var i = 0; i < table.columns.length; i++) { | ||
var column = table.columns[i]; | ||
var cell = row.cells[column.dataKey]; | ||
if (!cell) { | ||
continue; | ||
} | ||
applyStyles(cell.styles); | ||
function applyStyles(styles) { | ||
var arr = [{ func: doc.setFillColor, value: styles.fillColor }, { func: doc.setTextColor, value: styles.textColor }, { func: doc.setFontStyle, value: styles.fontStyle }, { func: doc.setDrawColor, value: styles.lineColor }, { func: doc.setLineWidth, value: styles.lineWidth }, { func: doc.setFont, value: styles.font }, { func: doc.setFontSize, value: styles.fontSize }]; | ||
arr.forEach(function (obj) { | ||
if (typeof obj.value !== 'undefined') { | ||
if (obj.value.constructor === Array) { | ||
obj.func.apply(this, obj.value); | ||
cell.x = cursor.x; | ||
cell.y = cursor.y; | ||
cell.height = row.height; | ||
cell.width = column.width; | ||
if (cell.styles.valign === 'top') { | ||
cell.textPos.y = cursor.y + cell.styles.cellPadding; | ||
} else if (cell.styles.valign === 'bottom') { | ||
cell.textPos.y = cursor.y + row.height - cell.styles.cellPadding; | ||
} else { | ||
obj.func(obj.value); | ||
cell.textPos.y = cursor.y + row.height / 2; | ||
} | ||
if (cell.styles.halign === 'right') { | ||
cell.textPos.x = cell.x + cell.width - cell.styles.cellPadding; | ||
} else if (cell.styles.halign === 'center') { | ||
cell.textPos.x = cell.x + cell.width / 2; | ||
} else { | ||
cell.textPos.x = cell.x + cell.styles.cellPadding; | ||
} | ||
var data = hooksData({ column: column, row: row }); | ||
if (hookHandler(cell, data) !== false) { | ||
doc.rect(cell.x, cell.y, cell.width, cell.height, cell.styles.fillStyle); | ||
doc.autoTableText(cell.text, cell.textPos.x, cell.textPos.y, { | ||
halign: cell.styles.halign, | ||
valign: cell.styles.valign | ||
}); | ||
} | ||
cursor.x += cell.width; | ||
} | ||
}); | ||
} | ||
function hooksData(additionalData) { | ||
additionalData = additionalData || {}; | ||
var data = { | ||
pageCount: pageCount, | ||
settings: settings, | ||
table: table, | ||
cursor: cursor | ||
}; | ||
for (var prop in additionalData) { | ||
if (additionalData.hasOwnProperty(prop)) { | ||
data[prop] = additionalData[prop]; | ||
} | ||
cursor.y += row.height; | ||
} | ||
return data; | ||
} | ||
/** | ||
* Ellipsize the text to fit in the width | ||
*/ | ||
function ellipsize(text, width, styles, ellipsizeStr) { | ||
ellipsizeStr = typeof ellipsizeStr !== 'undefined' ? ellipsizeStr : '...'; | ||
if (Array.isArray(text)) { | ||
text.forEach(function (str, i) { | ||
text[i] = ellipsize(str, width, styles, ellipsizeStr); | ||
function applyStyles(styles) { | ||
Object.keys(styleModifiers).forEach(function (name) { | ||
var style = styles[name]; | ||
var modifier = styleModifiers[name]; | ||
if (typeof style !== 'undefined') { | ||
if (style.constructor === Array) { | ||
modifier.apply(this, style); | ||
} else { | ||
modifier(style); | ||
} | ||
} | ||
}); | ||
return text; | ||
} | ||
if (width >= getStringWidth(text, styles)) { | ||
return text; | ||
function hooksData(additionalData) { | ||
return Object.assign({ | ||
pageCount: table.pageCount, | ||
settings: settings, | ||
table: table, | ||
cursor: cursor | ||
}, additionalData || {}); | ||
} | ||
while (width < getStringWidth(text + ellipsizeStr, styles)) { | ||
if (text.length < 2) { | ||
break; | ||
} | ||
text = text.substring(0, text.length - 1); | ||
function getStringWidth(text, styles) { | ||
applyStyles(styles); | ||
var w = doc.getStringUnitWidth(text); | ||
return w * styles.fontSize; | ||
} | ||
return text.trim() + ellipsizeStr; | ||
} | ||
function getStringWidth(text, styles) { | ||
applyStyles(styles); | ||
var w = doc.getStringUnitWidth(text); | ||
return w * styles.fontSize; | ||
} | ||
/** | ||
* Ellipsize the text to fit in the width | ||
*/ | ||
function ellipsize(text, width, styles, ellipsizeStr) { | ||
ellipsizeStr = typeof ellipsizeStr !== 'undefined' ? ellipsizeStr : '...'; | ||
function extend(defaults) { | ||
var extended = {}; | ||
var prop; | ||
for (prop in defaults) { | ||
if (defaults.hasOwnProperty(prop)) { | ||
extended[prop] = defaults[prop]; | ||
if (Array.isArray(text)) { | ||
text.forEach(function (str, i) { | ||
text[i] = ellipsize(str, width, styles, ellipsizeStr); | ||
}); | ||
return text; | ||
} | ||
} | ||
for (var i = 1; i < arguments.length; i++) { | ||
var options = arguments[i]; | ||
for (prop in options) { | ||
if (options.hasOwnProperty(prop)) { | ||
if (typeof options[prop] === 'object' && !Array.isArray(options[prop])) { | ||
//extended[prop] = extend(extended[prop] || {}, options[prop]) | ||
extended[prop] = options[prop]; | ||
} else { | ||
extended[prop] = options[prop]; | ||
} | ||
if (width >= getStringWidth(text, styles)) { | ||
return text; | ||
} | ||
while (width < getStringWidth(text + ellipsizeStr, styles)) { | ||
if (text.length < 2) { | ||
break; | ||
} | ||
text = text.substring(0, text.length - 1); | ||
} | ||
return text.trim() + ellipsizeStr; | ||
} | ||
return extended; | ||
} | ||
})(jsPDF.API); | ||
})(jsPDF.API); | ||
var Table = function Table() { | ||
_classCallCheck(this, Table); | ||
// Polyfills | ||
if (typeof Object.assign != 'function') { | ||
(function () { | ||
Object.assign = function (target) { | ||
'use strict'; | ||
this.height = 0; | ||
this.width = 0; | ||
this.x = 0; | ||
this.y = 0; | ||
this.contentWidth = 0; | ||
this.rows = []; | ||
this.columns = []; | ||
this.headerRow = null; | ||
this.settings = {}; | ||
}; | ||
if (target === undefined || target === null) { | ||
throw new TypeError('Cannot convert undefined or null to object'); | ||
} | ||
var Row = function Row(raw) { | ||
_classCallCheck(this, Row); | ||
var output = Object(target); | ||
for (var index = 1; index < arguments.length; index++) { | ||
var source = arguments[index]; | ||
if (source !== undefined && source !== null) { | ||
for (var nextKey in source) { | ||
if (source.hasOwnProperty(nextKey)) { | ||
output[nextKey] = source[nextKey]; | ||
} | ||
} | ||
} | ||
} | ||
return output; | ||
}; | ||
})(); | ||
} | ||
this.raw = raw || {}; | ||
this.index = 0; | ||
this.styles = {}; | ||
this.cells = {}; | ||
this.height = 0; | ||
this.y = 0; | ||
}; | ||
var Cell = function Cell(raw) { | ||
_classCallCheck(this, Cell); | ||
this.raw = raw; | ||
this.styles = {}; | ||
this.text = ''; | ||
this.contentWidth = 0; | ||
this.textPos = {}; | ||
this.height = 0; | ||
this.width = 0; | ||
this.x = 0; | ||
this.y = 0; | ||
}; | ||
var Column = function Column(dataKey) { | ||
_classCallCheck(this, Column); | ||
this.dataKey = dataKey; | ||
this.options = {}; | ||
this.styles = {}; | ||
this.contentWidth = 0; | ||
this.width = 0; | ||
this.x = 0; | ||
}; | ||
}()); |
{ | ||
"name": "jspdf-autotable", | ||
"version": "2.0.17", | ||
"description": "Generate PDF tables with jsPDF", | ||
"version": "2.0.18", | ||
"description": "Generate pdf tables with javascript (jsPDF plugin)", | ||
"main": "dist/jspdf.plugin.autotable.js", | ||
@@ -13,15 +13,18 @@ "directories": { | ||
"devDependencies": { | ||
"babel": "^5.8.23", | ||
"babel-preset-es2015-rollup": "^1.1.1", | ||
"nodemon": "^1.8.1", | ||
"rollup": "^0.25.1", | ||
"rollup-plugin-babel": "^2.3.9", | ||
"uglify-js": "^2.4.24" | ||
}, | ||
"scripts": { | ||
"build": "babel src/main.js | uglifyjs -o dist/jspdf.plugin.autotable.js --comments && babel src/main.js > dist/jspdf.plugin.autotable.src.js && node build updateVersion", | ||
"version": "npm run build && git add -A dist", | ||
"start": "nodemon --watch src -e js,ts build.js develop", | ||
"build": "node build.js build", | ||
"version": "npm run build && git add -A dist && git add -A examples/libs", | ||
"hosted": "git checkout gh-pages && npm run build && git add -A && git commit -m \"Updated to latest version\" && git push && git checkout master && git clean -f -d", | ||
"deploy": "git push && git push --tags && npm publish && npm run hosted", | ||
"test": "echo 'To test, manually open the examples.html and check that all examples looks good.'" | ||
"deploy": "git push && git push --tags && npm publish && npm run hosted" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/simonbengtsson/jsPDF-AutoTable.git" | ||
"url": "https://github.com/simonbengtsson/jsPDF-AutoTable.git" | ||
}, | ||
@@ -33,3 +36,3 @@ "keywords": [ | ||
], | ||
"author": "Simon Bengtsson <simongbe@gmail.com> (simonbengtsson.com)", | ||
"author": "Simon Bengtsson <dev@simonbengtsson.com>", | ||
"license": "MIT", | ||
@@ -39,3 +42,3 @@ "bugs": { | ||
}, | ||
"homepage": "https://github.com/simonbengtsson/jsPDF-AutoTable#readme" | ||
"homepage": "https://simonbengtsson.github.io/jsPDF-AutoTable/" | ||
} |
@@ -157,2 +157,5 @@ # AutoTable - Table plugin for jsPDF | ||
### Upgrade to Version 2.1 from 2.0 | ||
- Use cursor.x instead of column.x. | ||
### Upgrade to Version 2.0 from 1.x | ||
@@ -159,0 +162,0 @@ - Use the hooks (or styles and themes) instead of `renderCell`, `renderHeaderCell`, `renderFooter`and `renderHeader` |
406
src/main.js
@@ -1,109 +0,14 @@ | ||
/** | ||
* jsPDF AutoTable plugin __VERSION__ | ||
* Copyright (c) 2014 Simon Bengtsson, https://github.com/simonbengtsson/jsPDF-AutoTable | ||
* | ||
* Licensed under the MIT License. | ||
* http://opensource.org/licenses/mit-license | ||
* | ||
* @preserve | ||
*/ | ||
import {Table, Row, Cell, Column} from './models.js'; | ||
import {Config, themes, FONT_ROW_RATIO} from './config.js'; | ||
(function (API) { | ||
'use strict'; | ||
// Ratio between font size and font height. The number comes from jspdf's source code | ||
var FONT_ROW_RATIO = 1.15; | ||
var doc, // The current jspdf instance | ||
cursor, // An object keeping track of the x and y position of the next table cell to draw | ||
styleModifiers, | ||
pageSize, | ||
settings, // Default options merged with user options | ||
pageCount, // The page count the current table spans | ||
table; // The current Table instance | ||
// Base style for all themes | ||
var defaultStyles = { | ||
cellPadding: 5, | ||
fontSize: 10, | ||
font: "helvetica", // helvetica, times, courier | ||
lineColor: 200, | ||
lineWidth: 0.1, | ||
fontStyle: 'normal', // normal, bold, italic, bolditalic | ||
overflow: 'ellipsize', // visible, hidden, ellipsize or linebreak | ||
fillColor: 255, | ||
textColor: 20, | ||
halign: 'left', // left, center, right | ||
valign: 'top', // top, middle, bottom | ||
fillStyle: 'F', // 'S', 'F' or 'DF' (stroke, fill or fill then stroke) | ||
rowHeight: 20, | ||
columnWidth: 'auto' | ||
}; | ||
// Styles for the themes | ||
var themes = { | ||
'striped': { | ||
table: { | ||
fillColor: 255, | ||
textColor: 80, | ||
fontStyle: 'normal', | ||
fillStyle: 'F' | ||
}, | ||
header: { | ||
textColor: 255, | ||
fillColor: [41, 128, 185], | ||
rowHeight: 23, | ||
fontStyle: 'bold' | ||
}, | ||
body: {}, | ||
alternateRow: {fillColor: 245} | ||
}, | ||
'grid': { | ||
table: { | ||
fillColor: 255, | ||
textColor: 80, | ||
fontStyle: 'normal', | ||
lineWidth: 0.1, | ||
fillStyle: 'DF' | ||
}, | ||
header: { | ||
textColor: 255, | ||
fillColor: [26, 188, 156], | ||
rowHeight: 23, | ||
fillStyle: 'F', | ||
fontStyle: 'bold' | ||
}, | ||
body: {}, | ||
alternateRow: {} | ||
}, | ||
'plain': {header: {fontStyle: 'bold'}} | ||
}; | ||
// See README.md for documentation of the options | ||
// See examples.js for usage examples | ||
var defaultOptions = function () { | ||
return { | ||
// Styling | ||
theme: 'striped', // 'striped', 'grid' or 'plain' | ||
styles: {}, | ||
headerStyles: {}, | ||
bodyStyles: {}, | ||
alternateRowStyles: {}, | ||
columnStyles: {}, | ||
// Properties | ||
startY: false, // false indicates the margin.top value | ||
margin: 40, | ||
pageBreak: 'auto', // 'auto', 'avoid', 'always' | ||
tableWidth: 'auto', // number, 'auto', 'wrap' | ||
// Hooks | ||
createdHeaderCell: function (cell, data) {}, | ||
createdCell: function (cell, data) {}, | ||
drawHeaderRow: function (row, data) {}, | ||
drawRow: function (row, data) {}, | ||
drawHeaderCell: function (cell, data) {}, | ||
drawCell: function (cell, data) {}, | ||
beforePageContent: function (data) {}, | ||
afterPageContent: function (data) {} | ||
} | ||
}; | ||
/** | ||
@@ -119,7 +24,22 @@ * Create a table from a set of rows and columns. | ||
doc = this; | ||
settings = initOptions(options || {}); | ||
pageCount = 1; | ||
pageSize = doc.internal.pageSize; | ||
styleModifiers = { | ||
fillColor: doc.setFillColor, | ||
textColor: doc.setTextColor, | ||
fontStyle: doc.setFontStyle, | ||
lineColor: doc.setDrawColor, | ||
lineWidth: doc.setLineWidth, | ||
font: doc.setFont, | ||
fontSize: doc.setFontSize | ||
}; | ||
settings = Config.initSettings(options || {}); | ||
// Need a cursor y as it needs to be reset after each page (row.y can't do that) | ||
cursor = { y: settings.startY === false ? settings.margin.top : settings.startY }; | ||
// Also prefer cursor to column.x as the cursor is easier to modify in the hooks | ||
cursor = { | ||
x: settings.margin.left, | ||
y: settings.startY === false ? settings.margin.top : settings.startY | ||
}; | ||
@@ -134,3 +54,3 @@ var userStyles = { | ||
createModels(headers, data); | ||
calculateWidths(); | ||
calculateWidths(this, pageSize.width); | ||
@@ -144,4 +64,4 @@ // Page break if there is room for only the first data row | ||
if ((settings.pageBreak === 'always' && settings.startY !== false) || | ||
(settings.startY !== false && minTableBottomPos > doc.internal.pageSize.height)) { | ||
doc.addPage(); | ||
(settings.startY !== false && minTableBottomPos > pageSize.height)) { | ||
this.addPage(this.addPage); | ||
cursor.y = settings.margin.top; | ||
@@ -156,3 +76,3 @@ } | ||
applyStyles(userStyles); | ||
printRows(); | ||
printRows(this.addPage); | ||
settings.afterPageContent(hooksData()); | ||
@@ -218,3 +138,3 @@ | ||
} | ||
var fontSize = doc.internal.getFontSize() / doc.internal.scaleFactor; | ||
var fontSize = this.internal.getFontSize() / this.internal.scaleFactor; | ||
@@ -248,3 +168,3 @@ // As defined in jsPDF source code | ||
for (var iLine = 0; iLine < splittedText.length; iLine++) { | ||
doc.text(splittedText[iLine], x - doc.getStringUnitWidth(splittedText[iLine]) * alignSize, y); | ||
this.text(splittedText[iLine], x - this.getStringUnitWidth(splittedText[iLine]) * alignSize, y); | ||
y += fontSize; | ||
@@ -254,7 +174,8 @@ } | ||
} | ||
x -= doc.getStringUnitWidth(text) * alignSize; | ||
x -= this.getStringUnitWidth(text) * alignSize; | ||
} | ||
doc.text(text, x, y); | ||
return doc; | ||
this.text(text, x, y); | ||
return this; | ||
}; | ||
@@ -282,49 +203,2 @@ | ||
function initOptions(userOptions) { | ||
var settings = extend(defaultOptions(), userOptions); | ||
// Options | ||
if (typeof settings.extendWidth !== 'undefined') { | ||
settings.tableWidth = settings.extendWidth ? 'auto' : 'wrap'; | ||
console.error("Use of deprecated option: extendWidth, use tableWidth instead."); | ||
} | ||
if (typeof settings.margins !== 'undefined') { | ||
if (typeof settings.margin === 'undefined') settings.margin = settings.margins; | ||
console.error("Use of deprecated option: margins, use margin instead."); | ||
} | ||
[['padding', 'cellPadding'], ['lineHeight', 'rowHeight'], 'fontSize', 'overflow'].forEach(function (o) { | ||
var deprecatedOption = typeof o === 'string' ? o : o[0]; | ||
var style = typeof o === 'string' ? o : o[1]; | ||
if (typeof settings[deprecatedOption] !== 'undefined') { | ||
if (typeof settings.styles[style] === 'undefined') { | ||
settings.styles[style] = settings[deprecatedOption]; | ||
} | ||
console.error("Use of deprecated option: " + deprecatedOption + ", use the style " + style + " instead."); | ||
} | ||
}); | ||
// Unifying | ||
var marginSetting = settings.margin; | ||
settings.margin = {}; | ||
if (typeof marginSetting.horizontal === 'number') { | ||
marginSetting.right = marginSetting.horizontal; | ||
marginSetting.left = marginSetting.horizontal; | ||
} | ||
if (typeof marginSetting.vertical === 'number') { | ||
marginSetting.top = marginSetting.vertical; | ||
marginSetting.bottom = marginSetting.vertical; | ||
} | ||
['top', 'right', 'bottom', 'left'].forEach(function (side, i) { | ||
if (typeof marginSetting === 'number') { | ||
settings.margin[side] = marginSetting; | ||
} else { | ||
var key = Array.isArray(marginSetting) ? i : side; | ||
settings.margin[side] = typeof marginSetting[key] === 'number' ? marginSetting[key] : 40; | ||
} | ||
}); | ||
return settings; | ||
} | ||
/** | ||
@@ -338,3 +212,2 @@ * Create models from the user input | ||
table = new Table(); | ||
table.x = settings.margin.left; | ||
@@ -347,4 +220,4 @@ var splitRegex = /\r\n|\r|\n/g; | ||
var themeStyles = extend(defaultStyles, themes[settings.theme].table, themes[settings.theme].header); | ||
headerRow.styles = extend(themeStyles, settings.styles, settings.headerStyles); | ||
var themeStyles = Config.styles([themes[settings.theme].table, themes[settings.theme].header]); | ||
headerRow.styles = Object.assign({}, themeStyles, settings.styles, settings.headerStyles); | ||
@@ -367,3 +240,3 @@ // Columns and header row | ||
cell.raw = typeof rawColumn === 'object' ? rawColumn.title : rawColumn; | ||
cell.styles = extend(headerRow.styles); | ||
cell.styles = Object.assign({}, headerRow.styles); | ||
cell.text = '' + cell.raw; | ||
@@ -382,5 +255,5 @@ cell.contentWidth = cell.styles.cellPadding * 2 + getStringWidth(cell.text, cell.styles); | ||
var isAlternate = i % 2 === 0; | ||
var themeStyles = extend(defaultStyles, themes[settings.theme].table, isAlternate ? themes[settings.theme].alternateRow : {}); | ||
var userStyles = extend(settings.styles, settings.bodyStyles, isAlternate ? settings.alternateRowStyles : {}); | ||
row.styles = extend(themeStyles, userStyles); | ||
var themeStyles = Config.styles([themes[settings.theme].table, isAlternate ? themes[settings.theme].alternateRow : {}]); | ||
var userStyles = Object.assign({}, settings.styles, settings.bodyStyles, isAlternate ? settings.alternateRowStyles : {}); | ||
row.styles = Object.assign({}, themeStyles, userStyles); | ||
row.index = i; | ||
@@ -390,3 +263,3 @@ table.columns.forEach(function (column) { | ||
cell.raw = rawRow[column.dataKey]; | ||
cell.styles = extend(row.styles, column.styles); | ||
cell.styles = Object.assign({}, row.styles, column.styles); | ||
cell.text = typeof cell.raw !== 'undefined' ? '' + cell.raw : ''; // Stringify 0 and false, but not undefined | ||
@@ -405,3 +278,3 @@ row.cells[column.dataKey] = cell; | ||
*/ | ||
function calculateWidths() { | ||
function calculateWidths(doc, pageWidth) { | ||
// Column and table content width | ||
@@ -422,3 +295,3 @@ var tableContentWidth = 0; | ||
var maxTableWidth = doc.internal.pageSize.width - settings.margin.left - settings.margin.right; | ||
var maxTableWidth = pageWidth - settings.margin.left - settings.margin.right; | ||
var preferredTableWidth = maxTableWidth; // settings.tableWidth === 'auto' | ||
@@ -439,3 +312,3 @@ if (typeof settings.tableWidth === 'number') { | ||
table.columns.forEach(function (column) { | ||
var colStyles = extend(defaultStyles, themes[settings.theme].table, settings.styles, column.styles); | ||
var colStyles = Config.styles([themes[settings.theme].table, settings.styles, column.styles]); | ||
if (colStyles.columnWidth === 'wrap') { | ||
@@ -465,6 +338,4 @@ column.width = column.contentWidth; | ||
var lineBreakCount = 0; | ||
var cursorX = table.x; | ||
table.columns.forEach(function (col) { | ||
var cell = row.cells[col.dataKey]; | ||
col.x = cursorX; | ||
applyStyles(cell.styles); | ||
@@ -490,3 +361,2 @@ var textSpace = col.width - cell.styles.cellPadding * 2; | ||
} | ||
cursorX += col.width; | ||
}); | ||
@@ -521,9 +391,28 @@ | ||
function printRows() { | ||
function addPage(jspdfAddPage) { | ||
settings.afterPageContent(hooksData()); | ||
jspdfAddPage(); | ||
table.pageCount++; | ||
cursor = {x: settings.margin.left, y: settings.margin.top}; | ||
settings.beforePageContent(hooksData()); | ||
if (settings.drawHeaderRow(table.headerRow, hooksData({row: table.headerRow})) !== false) { | ||
printRow(table.headerRow, settings.drawHeaderCell); | ||
} | ||
} | ||
/** | ||
* Add a new page if cursor is at the end of page | ||
*/ | ||
function isNewPage(rowHeight) { | ||
var afterRowPos = cursor.y + rowHeight + settings.margin.bottom; | ||
return afterRowPos >= pageSize.height; | ||
} | ||
function printRows(jspdfAddPage) { | ||
table.rows.forEach(function (row, i) { | ||
if (isNewPage(row.height)) { | ||
var samePageThreshold = 3; | ||
// TODO Fix cell height > pageHeight | ||
// TODO Fix cell height > page height | ||
/*if (row.height > row.heightStyle * samePageThreshold) { | ||
var remainingPageSpace = doc.internal.pageSize.height - cursor.y - settings.margin.bottom; | ||
var remainingPageSpace = pageSize.height - cursor.y - settings.margin.bottom; | ||
var lineCount = Math.floor(remainingPageSpace / (row.styles.fontSize * FONT_ROW_RATIO)); | ||
@@ -543,3 +432,3 @@ table.columns.forEach(function(col) { | ||
}*/ | ||
addPage(); | ||
addPage(jspdfAddPage); | ||
} | ||
@@ -553,24 +442,4 @@ row.y = cursor.y; | ||
function addPage() { | ||
settings.afterPageContent(hooksData()); | ||
doc.addPage(); | ||
pageCount++; | ||
cursor = {x: settings.margin.left, y: settings.margin.top}; | ||
settings.beforePageContent(hooksData()); | ||
if (settings.drawHeaderRow(table.headerRow, hooksData({row: table.headerRow})) !== false) { | ||
printRow(table.headerRow, settings.drawHeaderCell); | ||
} | ||
} | ||
/** | ||
* Add a new page if cursor is at the end of page | ||
* @param rowHeight | ||
* @returns {boolean} | ||
*/ | ||
function isNewPage(rowHeight) { | ||
var afterRowPos = cursor.y + rowHeight + settings.margin.bottom; | ||
return afterRowPos >= doc.internal.pageSize.height; | ||
} | ||
function printRow(row, hookHandler) { | ||
cursor.x = settings.margin.left; | ||
for (var i = 0; i < table.columns.length; i++) { | ||
@@ -584,3 +453,3 @@ var column = table.columns[i]; | ||
cell.x = column.x; | ||
cell.x = cursor.x; | ||
cell.y = cursor.y; | ||
@@ -614,2 +483,3 @@ cell.height = row.height; | ||
} | ||
cursor.x += cell.width; | ||
} | ||
@@ -621,17 +491,10 @@ | ||
function applyStyles(styles) { | ||
var arr = [ | ||
{func: doc.setFillColor, value: styles.fillColor}, | ||
{func: doc.setTextColor, value: styles.textColor}, | ||
{func: doc.setFontStyle, value: styles.fontStyle}, | ||
{func: doc.setDrawColor, value: styles.lineColor}, | ||
{func: doc.setLineWidth, value: styles.lineWidth}, | ||
{func: doc.setFont, value: styles.font}, | ||
{func: doc.setFontSize, value: styles.fontSize} | ||
]; | ||
arr.forEach(function (obj) { | ||
if (typeof obj.value !== 'undefined') { | ||
if (obj.value.constructor === Array) { | ||
obj.func.apply(this, obj.value); | ||
Object.keys(styleModifiers).forEach(function (name) { | ||
var style = styles[name]; | ||
var modifier = styleModifiers[name]; | ||
if (typeof style !== 'undefined') { | ||
if (style.constructor === Array) { | ||
modifier.apply(this, style); | ||
} else { | ||
obj.func(obj.value); | ||
modifier(style); | ||
} | ||
@@ -643,17 +506,17 @@ } | ||
function hooksData(additionalData) { | ||
additionalData = additionalData || {}; | ||
var data = { | ||
pageCount: pageCount, | ||
return Object.assign({ | ||
pageCount: table.pageCount, | ||
settings: settings, | ||
table: table, | ||
cursor: cursor | ||
}; | ||
for (var prop in additionalData) { | ||
if (additionalData.hasOwnProperty(prop)) { | ||
data[prop] = additionalData[prop]; | ||
} | ||
} | ||
return data; | ||
}, additionalData || {}); | ||
} | ||
function getStringWidth(text, styles) { | ||
applyStyles(styles); | ||
var w = doc.getStringUnitWidth(text); | ||
return w * styles.fontSize; | ||
} | ||
/** | ||
@@ -684,82 +547,27 @@ * Ellipsize the text to fit in the width | ||
function getStringWidth(text, styles) { | ||
applyStyles(styles); | ||
var w = doc.getStringUnitWidth(text); | ||
return w * styles.fontSize; | ||
} | ||
})(jsPDF.API); | ||
function extend(defaults) { | ||
var extended = {}; | ||
var prop; | ||
for (prop in defaults) { | ||
if (defaults.hasOwnProperty(prop)) { | ||
extended[prop] = defaults[prop]; | ||
// Polyfills | ||
if (typeof Object.assign != 'function') { | ||
(function () { | ||
Object.assign = function (target) { | ||
'use strict'; | ||
if (target === undefined || target === null) { | ||
throw new TypeError('Cannot convert undefined or null to object'); | ||
} | ||
} | ||
for (var i = 1; i < arguments.length; i++) { | ||
var options = arguments[i]; | ||
for (prop in options) { | ||
if (options.hasOwnProperty(prop)) { | ||
if (typeof options[prop] === 'object' && !Array.isArray(options[prop])) { | ||
//extended[prop] = extend(extended[prop] || {}, options[prop]) | ||
extended[prop] = options[prop]; | ||
} else { | ||
extended[prop] = options[prop]; | ||
var output = Object(target); | ||
for (var index = 1; index < arguments.length; index++) { | ||
var source = arguments[index]; | ||
if (source !== undefined && source !== null) { | ||
for (var nextKey in source) { | ||
if (source.hasOwnProperty(nextKey)) { | ||
output[nextKey] = source[nextKey]; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return extended; | ||
} | ||
})(jsPDF.API); | ||
class Table { | ||
constructor() { | ||
this.height = 0; | ||
this.width = 0; | ||
this.x = 0; | ||
this.y = 0; | ||
this.contentWidth = 0; | ||
this.rows = []; | ||
this.columns = []; | ||
this.headerRow = null; | ||
this.settings = {}; | ||
} | ||
} | ||
class Row { | ||
constructor(raw) { | ||
this.raw = raw || {}; | ||
this.index = 0; | ||
this.styles = {}; | ||
this.cells = {}; | ||
this.height = 0; | ||
this.y = 0; | ||
} | ||
} | ||
class Cell { | ||
constructor(raw) { | ||
this.raw = raw; | ||
this.styles = {}; | ||
this.text = ''; | ||
this.contentWidth = 0; | ||
this.textPos = {}; | ||
this.height = 0; | ||
this.width = 0; | ||
this.x = 0; | ||
this.y = 0; | ||
} | ||
} | ||
class Column { | ||
constructor(dataKey) { | ||
this.dataKey = dataKey; | ||
this.options = {}; | ||
this.styles = {}; | ||
this.contentWidth = 0; | ||
this.width = 0; | ||
this.x = 0; | ||
} | ||
} | ||
return output; | ||
}; | ||
})(); | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1097443
22
5399
205
5