Skip to content

Commit 9855b10

Browse files
author
Eduardo Menezes Morais
committed
Merging tables branch
2 parents 707cef8 + b918c9a commit 9855b10

10 files changed

Lines changed: 730 additions & 211 deletions

dist/jspdf.amd.min.js

Lines changed: 108 additions & 102 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/jspdf.min.js

Lines changed: 108 additions & 102 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/jspdf.source.js

Lines changed: 375 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @preserve jsPDF 0.9.0rc2 ( 2013-07-26T14:30 commit ID afdc433c2444775787f39c73c8f2533a41c6c724 )
1+
/** @preserve jsPDF 0.9.0rc2 ( 2013-08-05T14:21 commit ID 707cef854e43573aa05f60b47370d20e08fd580f )
22
Copyright (c) 2010-2012 James Hall, james@snapshotmedia.co.uk, https://github.com/MrRio/jsPDF
33
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
44
MIT license.
@@ -3666,9 +3666,381 @@ jsPDFAPI.putTotalPages = function(pageExpression) {
36663666
this.internal.pages[n][i] = this.internal.pages[n][i].replace(replaceExpression, this.internal.getNumberOfPages());
36673667
}
36683668
return this;
3669-
}
3669+
};
36703670

3671-
})(jsPDF.API)
3671+
})(jsPDF.API);
3672+
/** ====================================================================
3673+
* jsPDF Cell plugin
3674+
* Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
3675+
*
3676+
* Permission is hereby granted, free of charge, to any person obtaining
3677+
* a copy of this software and associated documentation files (the
3678+
* "Software"), to deal in the Software without restriction, including
3679+
* without limitation the rights to use, copy, modify, merge, publish,
3680+
* distribute, sublicense, and/or sell copies of the Software, and to
3681+
* permit persons to whom the Software is furnished to do so, subject to
3682+
* the following conditions:
3683+
*
3684+
* The above copyright notice and this permission notice shall be
3685+
* included in all copies or substantial portions of the Software.
3686+
*
3687+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3688+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3689+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3690+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
3691+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
3692+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
3693+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3694+
* ====================================================================
3695+
*/
3696+
3697+
(function (jsPDFAPI) {
3698+
'use strict';
3699+
/*jslint browser:true */
3700+
/*global document: false, jsPDF */
3701+
3702+
var maxLn = 0,
3703+
lnP = 0,
3704+
fontName,
3705+
fontSize,
3706+
fontStyle,
3707+
lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },
3708+
pages = 1,
3709+
newPage = false,
3710+
setLastCellPosition = function (x, y, w, h, ln) {
3711+
lastCellPos = { x: x, y: y, w: w, h: h, ln: ln };
3712+
},
3713+
getLastCellPosition = function () {
3714+
return lastCellPos;
3715+
},
3716+
setMaxLn = function (x) {
3717+
maxLn = x;
3718+
},
3719+
getMaxLn = function () {
3720+
return maxLn;
3721+
},
3722+
setLnP = function (x) {
3723+
lnP = x;
3724+
},
3725+
getLnP = function (x) {
3726+
return lnP;
3727+
};
3728+
3729+
jsPDFAPI.getTextDimensions = function (txt) {
3730+
fontName = this.internal.getFont().fontName;
3731+
fontSize = this.internal.getFontSize();
3732+
fontStyle = this.internal.getFont().fontStyle;
3733+
3734+
// 1 pixel = 0.264583 mm and 1 mm = 72/25.4 point
3735+
var px2pt = 0.264583 * 72 / 25.4,
3736+
dimensions,
3737+
text;
3738+
3739+
text = document.createElement('font');
3740+
text.id = "jsPDFCell";
3741+
text.style.fontStyle = fontStyle;
3742+
text.style.fontName = fontName;
3743+
text.style.fontSize = fontSize + 'pt';
3744+
text.innerText = txt;
3745+
3746+
document.body.appendChild(text);
3747+
3748+
dimensions = { w: (text.offsetWidth + 1) * px2pt, h: (text.offsetHeight + 1) * px2pt};
3749+
3750+
document.body.removeChild(text);
3751+
3752+
return dimensions;
3753+
};
3754+
3755+
jsPDFAPI.cellAddPage = function () {
3756+
this.addPage();
3757+
setLastCellPosition(undefined, undefined, undefined, undefined, undefined);
3758+
newPage = true;
3759+
pages += 1;
3760+
setLnP(1);
3761+
};
3762+
3763+
jsPDFAPI.cellInitialize = function () {
3764+
maxLn = 0;
3765+
lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined };
3766+
pages = 1;
3767+
newPage = false;
3768+
setLnP(0);
3769+
};
3770+
3771+
jsPDFAPI.cell = function (x, y, w, h, txt, ln) {
3772+
this.lnMod = this.lnMod === undefined ? 0 : this.lnMod;
3773+
if (this.printingHeaderRow !== true && this.lnMod !== 0) {
3774+
ln = ln + this.lnMod;
3775+
}
3776+
3777+
if ((((ln * h) + y + (h * 2)) / pages) >= this.internal.pageSize.height && pages === 1 && !newPage) {
3778+
this.cellAddPage();
3779+
3780+
if (this.printHeaders && this.tableHeaderRow) {
3781+
this.printHeaderRow(ln);
3782+
this.lnMod += 1;
3783+
ln += 1;
3784+
}
3785+
if (getMaxLn() === 0) {
3786+
setMaxLn(Math.round((this.internal.pageSize.height - (h * 2)) / h));
3787+
}
3788+
} else if (newPage && getLastCellPosition().ln !== ln && getLnP() === getMaxLn()) {
3789+
this.cellAddPage();
3790+
3791+
if (this.printHeaders && this.tableHeaderRow) {
3792+
this.printHeaderRow(ln);
3793+
this.lnMod += 1;
3794+
ln += 1;
3795+
}
3796+
}
3797+
3798+
var curCell = getLastCellPosition(),
3799+
dim = this.getTextDimensions(txt),
3800+
isNewLn = 1;
3801+
if (curCell.x !== undefined && curCell.ln === ln) {
3802+
x = curCell.x + curCell.w;
3803+
}
3804+
if (curCell.y !== undefined && curCell.y === y) {
3805+
y = curCell.y;
3806+
}
3807+
if (curCell.h !== undefined && curCell.h === h) {
3808+
h = curCell.h;
3809+
}
3810+
if (curCell.ln !== undefined && curCell.ln === ln) {
3811+
ln = curCell.ln;
3812+
isNewLn = 0;
3813+
}
3814+
if (newPage) {
3815+
y = h * (getLnP() + isNewLn);
3816+
} else {
3817+
y = (y + (h * Math.abs(getMaxLn() * pages - ln - getMaxLn())));
3818+
}
3819+
this.rect(x, y, w, h);
3820+
this.text(txt, x + 3, y + h - 3);
3821+
setLnP(getLnP() + isNewLn);
3822+
setLastCellPosition(x, y, w, h, ln);
3823+
return this;
3824+
};
3825+
3826+
/**
3827+
* Return an array containing all of the owned keys of an Object
3828+
* @type {Function}
3829+
* @return {String[]} of Object keys
3830+
*/
3831+
jsPDFAPI.getKeys = (typeof Object.keys === 'function')
3832+
? function (object) {
3833+
if (!object) {
3834+
return [];
3835+
}
3836+
return Object.keys(object);
3837+
}
3838+
: function (object) {
3839+
var keys = [],
3840+
property;
3841+
3842+
for (property in object) {
3843+
if (object.hasOwnProperty(property)) {
3844+
keys.push(property);
3845+
}
3846+
}
3847+
3848+
return keys;
3849+
};
3850+
3851+
/**
3852+
* Return the maximum value from an array
3853+
* @param array
3854+
* @param comparisonFn
3855+
* @returns {*}
3856+
*/
3857+
jsPDFAPI.arrayMax = function (array, comparisonFn) {
3858+
var max = array[0],
3859+
i,
3860+
ln,
3861+
item;
3862+
3863+
for (i = 0, ln = array.length; i < ln; i += 1) {
3864+
item = array[i];
3865+
3866+
if (comparisonFn) {
3867+
if (comparisonFn(max, item) === -1) {
3868+
max = item;
3869+
}
3870+
} else {
3871+
if (item > max) {
3872+
max = item;
3873+
}
3874+
}
3875+
}
3876+
3877+
return max;
3878+
};
3879+
3880+
/**
3881+
* Create a table from a set of data.
3882+
* @param {Object[]} data As array of objects containing key-value pairs
3883+
* @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost
3884+
* @param {Object} [config.printHeaders] True to print column headers at the top of every page
3885+
* @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value
3886+
* @param {Object} [config.autoStretch] True to force the table to fit the width of the page
3887+
*/
3888+
jsPDFAPI.table = function (data, headers, config) {
3889+
3890+
var headerNames = [],
3891+
headerPrompts = [],
3892+
header,
3893+
autoSize,
3894+
printHeaders,
3895+
autoStretch,
3896+
i,
3897+
ln,
3898+
columnMatrix = {},
3899+
columnWidths = {},
3900+
columnData,
3901+
column,
3902+
columnMinWidths = [],
3903+
j,
3904+
tableHeaderConfigs = [],
3905+
model,
3906+
jln,
3907+
func;
3908+
3909+
/**
3910+
* @property {Number} lnMod
3911+
* Keep track of the current line number modifier used when creating cells
3912+
*/
3913+
this.lnMod = 0;
3914+
3915+
if (config) {
3916+
autoSize = config.autoSize || false;
3917+
printHeaders = this.printHeaders = config.printHeaders || true;
3918+
autoStretch = config.autoStretch || true;
3919+
}
3920+
3921+
if (!data) {
3922+
throw 'No data for PDF table';
3923+
}
3924+
3925+
// Set headers
3926+
if (headers === undefined || (headers === null)) {
3927+
3928+
// No headers defined so we derive from data
3929+
headerNames = this.getKeys(data[0]);
3930+
3931+
} else if (headers[0] && (typeof headers[0] !== 'string')) {
3932+
3933+
// Split header configs into names and prompts
3934+
for (i = 0, ln = headers.length; i < ln; i += 1) {
3935+
header = headers[i];
3936+
headerNames.push(header.name);
3937+
headerPrompts.push(header.prompt);
3938+
}
3939+
3940+
} else {
3941+
headerNames = headers;
3942+
}
3943+
3944+
if (config.autoSize) {
3945+
3946+
// Create Columns Matrix
3947+
3948+
func = function (rec) {
3949+
return rec[header];
3950+
};
3951+
3952+
for (i = 0, ln = headerNames.length; i < ln; i += 1) {
3953+
header = headerNames[i];
3954+
3955+
columnMatrix[header] = data.map(
3956+
func
3957+
);
3958+
3959+
// get header width
3960+
columnMinWidths.push(this.getTextDimensions(headerPrompts[i] || header).w);
3961+
3962+
column = columnMatrix[header];
3963+
3964+
// get cell widths
3965+
for (j = 0, ln = column.length; j < ln; j += 1) {
3966+
columnData = column[j];
3967+
3968+
columnMinWidths.push(this.getTextDimensions(columnData).w);
3969+
}
3970+
3971+
// get final column width
3972+
columnWidths[header] = jsPDFAPI.arrayMax(columnMinWidths);
3973+
}
3974+
}
3975+
3976+
// -- Construct the table
3977+
3978+
if (config.printHeaders) {
3979+
3980+
// Construct the header row
3981+
for (i = 0, ln = headerNames.length; i < ln; i += 1) {
3982+
header = headerNames[i];
3983+
tableHeaderConfigs.push([10, 10, columnWidths[header], 25, String(headerPrompts.length ? headerPrompts[i] : header)]);
3984+
}
3985+
3986+
// Store the table header config
3987+
this.setTableHeaderRow(tableHeaderConfigs);
3988+
3989+
// Print the header for the start of the table
3990+
this.printHeaderRow(1);
3991+
}
3992+
3993+
// Construct the data rows
3994+
for (i = 0, ln = data.length; i < ln; i += 1) {
3995+
model = data[i];
3996+
3997+
for (j = 0, jln = headerNames.length; j < jln; j += 1) {
3998+
header = headerNames[j];
3999+
this.cell(10, 10, columnWidths[header], 25, String(model[header]), i + 2);
4000+
}
4001+
}
4002+
4003+
return this;
4004+
};
4005+
4006+
/**
4007+
* Store the config for outputting a table header
4008+
* @param {Object[]} config
4009+
* An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell
4010+
* except the ln parameter is excluded
4011+
*/
4012+
jsPDFAPI.setTableHeaderRow = function (config) {
4013+
this.tableHeaderRow = config;
4014+
};
4015+
4016+
/**
4017+
* Output the store header row
4018+
* @param lineNumber The line number to output the header at
4019+
*/
4020+
jsPDFAPI.printHeaderRow = function (lineNumber) {
4021+
if (!this.tableHeaderRow) {
4022+
throw 'Property tableHeaderRow does not exist.';
4023+
}
4024+
4025+
var tableHeaderCell,
4026+
tmpArray,
4027+
i,
4028+
ln;
4029+
4030+
this.printingHeaderRow = true;
4031+
4032+
for (i = 0, ln = this.tableHeaderRow.length; i < ln; i += 1) {
4033+
4034+
tableHeaderCell = this.tableHeaderRow[i];
4035+
tmpArray = [].concat(tableHeaderCell);
4036+
4037+
this.cell.apply(this, tmpArray.concat(lineNumber));
4038+
}
4039+
4040+
this.printingHeaderRow = false;
4041+
};
4042+
4043+
})(jsPDF.API);
36724044
/* BlobBuilder.js
36734045
* A BlobBuilder implementation.
36744046
* 2012-04-21

0 commit comments

Comments
 (0)