plugins_cell.js.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>plugins/cell.js - Documentation</title>
  6. <script src="scripts/prettify/prettify.js"></script>
  7. <script src="scripts/prettify/lang-css.js"></script>
  8. <!--[if lt IE 9]>
  9. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  10. <![endif]-->
  11. <link type="text/css" rel="stylesheet" href="styles/prettify.css">
  12. <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
  13. </head>
  14. <body>
  15. <input type="checkbox" id="nav-trigger" class="nav-trigger" />
  16. <label for="nav-trigger" class="navicon-button x">
  17. <div class="navicon"></div>
  18. </label>
  19. <label for="nav-trigger" class="overlay"></label>
  20. <nav>
  21. <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="jsPDF.html">jsPDF</a></li></ul><h3>Global</h3><ul><li><a href="global.html#addFont">addFont</a></li><li><a href="global.html#addHTML">addHTML</a></li><li><a href="global.html#addMetadata">addMetadata</a></li><li><a href="global.html#addPage">addPage</a></li><li><a href="global.html#autoPrint">autoPrint</a></li><li><a href="global.html#CapJoinStyles">CapJoinStyles</a></li><li><a href="global.html#circle">circle</a></li><li><a href="global.html#ellipse">ellipse</a></li><li><a href="global.html#getFontList">getFontList</a></li><li><a href="global.html#lines">lines</a></li><li><a href="global.html#lstext">lstext</a></li><li><a href="global.html#output">output</a></li><li><a href="global.html#rect">rect</a></li><li><a href="global.html#roundedRect">roundedRect</a></li><li><a href="global.html#save">save</a></li><li><a href="global.html#setDisplayMode">setDisplayMode</a></li><li><a href="global.html#setDrawColor">setDrawColor</a></li><li><a href="global.html#setFillColor">setFillColor</a></li><li><a href="global.html#setFont">setFont</a></li><li><a href="global.html#setFontSize">setFontSize</a></li><li><a href="global.html#setFontStyle">setFontStyle</a></li><li><a href="global.html#setLineCap">setLineCap</a></li><li><a href="global.html#setLineJoin">setLineJoin</a></li><li><a href="global.html#setLineWidth">setLineWidth</a></li><li><a href="global.html#setPage">setPage</a></li><li><a href="global.html#setProperties">setProperties</a></li><li><a href="global.html#setTextColor">setTextColor</a></li><li><a href="global.html#text">text</a></li><li><a href="global.html#triangle">triangle</a></li></ul>
  22. </nav>
  23. <div id="main">
  24. <h1 class="page-title">plugins/cell.js</h1>
  25. <section>
  26. <article>
  27. <pre class="prettyprint source linenums"><code>/** ====================================================================
  28. * jsPDF Cell plugin
  29. * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
  30. * 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
  31. * 2013 Lee Driscoll, https://github.com/lsdriscoll
  32. * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
  33. * 2014 James Hall, james@parall.ax
  34. * 2014 Diego Casorran, https://github.com/diegocr
  35. *
  36. * Permission is hereby granted, free of charge, to any person obtaining
  37. * a copy of this software and associated documentation files (the
  38. * "Software"), to deal in the Software without restriction, including
  39. * without limitation the rights to use, copy, modify, merge, publish,
  40. * distribute, sublicense, and/or sell copies of the Software, and to
  41. * permit persons to whom the Software is furnished to do so, subject to
  42. * the following conditions:
  43. *
  44. * The above copyright notice and this permission notice shall be
  45. * included in all copies or substantial portions of the Software.
  46. *
  47. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  48. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  49. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  50. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  51. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  52. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  53. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  54. * ====================================================================
  55. */
  56. (function (jsPDFAPI) {
  57. 'use strict';
  58. /*jslint browser:true */
  59. /*global document: false, jsPDF */
  60. var fontName,
  61. fontSize,
  62. fontStyle,
  63. padding = 3,
  64. margin = 13,
  65. headerFunction,
  66. lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },
  67. pages = 1,
  68. setLastCellPosition = function (x, y, w, h, ln) {
  69. lastCellPos = { 'x': x, 'y': y, 'w': w, 'h': h, 'ln': ln };
  70. },
  71. getLastCellPosition = function () {
  72. return lastCellPos;
  73. },
  74. NO_MARGINS = {left:0, top:0, bottom: 0};
  75. jsPDFAPI.setHeaderFunction = function (func) {
  76. headerFunction = func;
  77. };
  78. jsPDFAPI.getTextDimensions = function (txt) {
  79. fontName = this.internal.getFont().fontName;
  80. fontSize = this.table_font_size || this.internal.getFontSize();
  81. fontStyle = this.internal.getFont().fontStyle;
  82. // 1 pixel = 0.264583 mm and 1 mm = 72/25.4 point
  83. var px2pt = 0.264583 * 72 / 25.4,
  84. dimensions,
  85. text;
  86. text = document.createElement('font');
  87. text.id = "jsPDFCell";
  88. try {
  89. text.style.fontStyle = fontStyle;
  90. } catch(e) {
  91. text.style.fontWeight = fontStyle;
  92. }
  93. text.style.fontName = fontName;
  94. text.style.fontSize = fontSize + 'pt';
  95. try {
  96. text.textContent = txt;
  97. } catch(e) {
  98. text.innerText = txt;
  99. }
  100. document.body.appendChild(text);
  101. dimensions = { w: (text.offsetWidth + 1) * px2pt, h: (text.offsetHeight + 1) * px2pt};
  102. document.body.removeChild(text);
  103. return dimensions;
  104. };
  105. jsPDFAPI.cellAddPage = function () {
  106. var margins = this.margins || NO_MARGINS;
  107. this.addPage();
  108. setLastCellPosition(margins.left, margins.top, undefined, undefined);
  109. //setLastCellPosition(undefined, undefined, undefined, undefined, undefined);
  110. pages += 1;
  111. };
  112. jsPDFAPI.cellInitialize = function () {
  113. lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined };
  114. pages = 1;
  115. };
  116. jsPDFAPI.cell = function (x, y, w, h, txt, ln, align) {
  117. var curCell = getLastCellPosition();
  118. var pgAdded = false;
  119. // If this is not the first cell, we must change its position
  120. if (curCell.ln !== undefined) {
  121. if (curCell.ln === ln) {
  122. //Same line
  123. x = curCell.x + curCell.w;
  124. y = curCell.y;
  125. } else {
  126. //New line
  127. var margins = this.margins || NO_MARGINS;
  128. if ((curCell.y + curCell.h + h + margin) >= this.internal.pageSize.height - margins.bottom) {
  129. this.cellAddPage();
  130. pgAdded = true;
  131. if (this.printHeaders &amp;&amp; this.tableHeaderRow) {
  132. this.printHeaderRow(ln, true);
  133. }
  134. }
  135. //We ignore the passed y: the lines may have different heights
  136. y = (getLastCellPosition().y + getLastCellPosition().h);
  137. if (pgAdded) y = margin + 10;
  138. }
  139. }
  140. if (txt[0] !== undefined) {
  141. if (this.printingHeaderRow) {
  142. this.rect(x, y, w, h, 'FD');
  143. } else {
  144. this.rect(x, y, w, h);
  145. }
  146. if (align === 'right') {
  147. if (!(txt instanceof Array)) {
  148. txt = [txt];
  149. }
  150. for (var i = 0; i &lt; txt.length; i++) {
  151. var currentLine = txt[i];
  152. var textSize = this.getStringUnitWidth(currentLine) * this.internal.getFontSize();
  153. this.text(currentLine, x + w - textSize - padding, y + this.internal.getLineHeight()*(i+1));
  154. }
  155. } else {
  156. this.text(txt, x + padding, y + this.internal.getLineHeight());
  157. }
  158. }
  159. setLastCellPosition(x, y, w, h, ln);
  160. return this;
  161. };
  162. /**
  163. * Return the maximum value from an array
  164. * @param array
  165. * @param comparisonFn
  166. * @returns {*}
  167. */
  168. jsPDFAPI.arrayMax = function (array, comparisonFn) {
  169. var max = array[0],
  170. i,
  171. ln,
  172. item;
  173. for (i = 0, ln = array.length; i &lt; ln; i += 1) {
  174. item = array[i];
  175. if (comparisonFn) {
  176. if (comparisonFn(max, item) === -1) {
  177. max = item;
  178. }
  179. } else {
  180. if (item > max) {
  181. max = item;
  182. }
  183. }
  184. }
  185. return max;
  186. };
  187. /**
  188. * Create a table from a set of data.
  189. * @param {Integer} [x] : left-position for top-left corner of table
  190. * @param {Integer} [y] top-position for top-left corner of table
  191. * @param {Object[]} [data] As array of objects containing key-value pairs corresponding to a row of data.
  192. * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost
  193. * @param {Object} [config.printHeaders] True to print column headers at the top of every page
  194. * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value
  195. * @param {Object} [config.margins] margin values for left, top, bottom, and width
  196. * @param {Object} [config.fontSize] Integer fontSize to use (optional)
  197. */
  198. jsPDFAPI.table = function (x,y, data, headers, config) {
  199. if (!data) {
  200. throw 'No data for PDF table';
  201. }
  202. var headerNames = [],
  203. headerPrompts = [],
  204. header,
  205. i,
  206. ln,
  207. cln,
  208. columnMatrix = {},
  209. columnWidths = {},
  210. columnData,
  211. column,
  212. columnMinWidths = [],
  213. j,
  214. tableHeaderConfigs = [],
  215. model,
  216. jln,
  217. func,
  218. //set up defaults. If a value is provided in config, defaults will be overwritten:
  219. autoSize = false,
  220. printHeaders = true,
  221. fontSize = 12,
  222. margins = NO_MARGINS;
  223. margins.width = this.internal.pageSize.width;
  224. if (config) {
  225. //override config defaults if the user has specified non-default behavior:
  226. if(config.autoSize === true) {
  227. autoSize = true;
  228. }
  229. if(config.printHeaders === false) {
  230. printHeaders = false;
  231. }
  232. if(config.fontSize){
  233. fontSize = config.fontSize;
  234. }
  235. if (config.css &amp;&amp; typeof(config.css['font-size']) !== "undefined") {
  236. fontSize = config.css['font-size'] * 16;
  237. }
  238. if(config.margins){
  239. margins = config.margins;
  240. }
  241. }
  242. /**
  243. * @property {Number} lnMod
  244. * Keep track of the current line number modifier used when creating cells
  245. */
  246. this.lnMod = 0;
  247. lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },
  248. pages = 1;
  249. this.printHeaders = printHeaders;
  250. this.margins = margins;
  251. this.setFontSize(fontSize);
  252. this.table_font_size = fontSize;
  253. // Set header values
  254. if (headers === undefined || (headers === null)) {
  255. // No headers defined so we derive from data
  256. headerNames = Object.keys(data[0]);
  257. } else if (headers[0] &amp;&amp; (typeof headers[0] !== 'string')) {
  258. var px2pt = 0.264583 * 72 / 25.4;
  259. // Split header configs into names and prompts
  260. for (i = 0, ln = headers.length; i &lt; ln; i += 1) {
  261. header = headers[i];
  262. headerNames.push(header.name);
  263. headerPrompts.push(header.prompt);
  264. columnWidths[header.name] = header.width *px2pt;
  265. }
  266. } else {
  267. headerNames = headers;
  268. }
  269. if (autoSize) {
  270. // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]}
  271. func = function (rec) {
  272. return rec[header];
  273. };
  274. for (i = 0, ln = headerNames.length; i &lt; ln; i += 1) {
  275. header = headerNames[i];
  276. columnMatrix[header] = data.map(
  277. func
  278. );
  279. // get header width
  280. columnMinWidths.push(this.getTextDimensions(headerPrompts[i] || header).w);
  281. column = columnMatrix[header];
  282. // get cell widths
  283. for (j = 0, cln = column.length; j &lt; cln; j += 1) {
  284. columnData = column[j];
  285. columnMinWidths.push(this.getTextDimensions(columnData).w);
  286. }
  287. // get final column width
  288. columnWidths[header] = jsPDFAPI.arrayMax(columnMinWidths);
  289. //have to reset
  290. columnMinWidths = [];
  291. }
  292. }
  293. // -- Construct the table
  294. if (printHeaders) {
  295. var lineHeight = this.calculateLineHeight(headerNames, columnWidths, headerPrompts.length?headerPrompts:headerNames);
  296. // Construct the header row
  297. for (i = 0, ln = headerNames.length; i &lt; ln; i += 1) {
  298. header = headerNames[i];
  299. tableHeaderConfigs.push([x, y, columnWidths[header], lineHeight, String(headerPrompts.length ? headerPrompts[i] : header)]);
  300. }
  301. // Store the table header config
  302. this.setTableHeaderRow(tableHeaderConfigs);
  303. // Print the header for the start of the table
  304. this.printHeaderRow(1, false);
  305. }
  306. // Construct the data rows
  307. for (i = 0, ln = data.length; i &lt; ln; i += 1) {
  308. var lineHeight;
  309. model = data[i];
  310. lineHeight = this.calculateLineHeight(headerNames, columnWidths, model);
  311. for (j = 0, jln = headerNames.length; j &lt; jln; j += 1) {
  312. header = headerNames[j];
  313. this.cell(x, y, columnWidths[header], lineHeight, model[header], i + 2, header.align);
  314. }
  315. }
  316. this.lastCellPos = lastCellPos;
  317. this.table_x = x;
  318. this.table_y = y;
  319. return this;
  320. };
  321. /**
  322. * Calculate the height for containing the highest column
  323. * @param {String[]} headerNames is the header, used as keys to the data
  324. * @param {Integer[]} columnWidths is size of each column
  325. * @param {Object[]} model is the line of data we want to calculate the height of
  326. */
  327. jsPDFAPI.calculateLineHeight = function (headerNames, columnWidths, model) {
  328. var header, lineHeight = 0;
  329. for (var j = 0; j &lt; headerNames.length; j++) {
  330. header = headerNames[j];
  331. model[header] = this.splitTextToSize(String(model[header]), columnWidths[header] - padding);
  332. var h = this.internal.getLineHeight() * model[header].length + padding;
  333. if (h > lineHeight)
  334. lineHeight = h;
  335. }
  336. return lineHeight;
  337. };
  338. /**
  339. * Store the config for outputting a table header
  340. * @param {Object[]} config
  341. * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell
  342. * except the ln parameter is excluded
  343. */
  344. jsPDFAPI.setTableHeaderRow = function (config) {
  345. this.tableHeaderRow = config;
  346. };
  347. /**
  348. * Output the store header row
  349. * @param lineNumber The line number to output the header at
  350. */
  351. jsPDFAPI.printHeaderRow = function (lineNumber, new_page) {
  352. if (!this.tableHeaderRow) {
  353. throw 'Property tableHeaderRow does not exist.';
  354. }
  355. var tableHeaderCell,
  356. tmpArray,
  357. i,
  358. ln;
  359. this.printingHeaderRow = true;
  360. if (headerFunction !== undefined) {
  361. var position = headerFunction(this, pages);
  362. setLastCellPosition(position[0], position[1], position[2], position[3], -1);
  363. }
  364. this.setFontStyle('bold');
  365. var tempHeaderConf = [];
  366. for (i = 0, ln = this.tableHeaderRow.length; i &lt; ln; i += 1) {
  367. this.setFillColor(200,200,200);
  368. tableHeaderCell = this.tableHeaderRow[i];
  369. if (new_page) {
  370. this.margins.top = margin;
  371. tableHeaderCell[1] = this.margins &amp;&amp; this.margins.top || 0;
  372. tempHeaderConf.push(tableHeaderCell);
  373. }
  374. tmpArray = [].concat(tableHeaderCell);
  375. this.cell.apply(this, tmpArray.concat(lineNumber));
  376. }
  377. if (tempHeaderConf.length > 0){
  378. this.setTableHeaderRow(tempHeaderConf);
  379. }
  380. this.setFontStyle('normal');
  381. this.printingHeaderRow = false;
  382. };
  383. })(jsPDF.API);
  384. </code></pre>
  385. </article>
  386. </section>
  387. </div>
  388. <br class="clear">
  389. <footer>
  390. Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.2</a> on Sun Oct 09 2016 11:08:27 GMT+0100 (BST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
  391. </footer>
  392. <script>prettyPrint();</script>
  393. <script src="scripts/linenumber.js"></script>
  394. </body>
  395. </html>