Guest User

Untitled

a guest
Nov 23rd, 2017
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.17 KB | None | 0 0
  1. (function (root, factory) {
  2. if (typeof define === 'function' && define.amd) {
  3. define('html2pdf', ['html2canvas', 'jspdf'], factory);
  4. } else {
  5. root.html2pdf = factory(root.html2canvas, root.jsPDF);
  6. }
  7. }(typeof self !== 'undefined' ? self : this, function (html2canvas, jsPDF) {
  8. var func = {
  9. parseInput: function (source, opt) {
  10. opt.jsPDF = opt.jsPDF || {};
  11. opt.html2canvas = opt.html2canvas || {};
  12. opt.filename = opt.filename && utils.objType(opt.filename) === 'string' ? opt.filename : 'file.pdf';
  13. opt.enableLinks = opt.hasOwnProperty('enableLinks') ? opt.enableLinks : true;
  14. opt.image = opt.image || {};
  15. opt.image.type = opt.image.type || 'jpeg';
  16. opt.image.quality = opt.image.quality || 0.95;
  17.  
  18. switch (utils.objType(opt.margin)) {
  19. case 'undefined':
  20. opt.margin = 0;
  21. case 'number':
  22. opt.margin = [opt.margin, opt.margin, opt.margin, opt.margin];
  23. break;
  24. case 'array':
  25. if (opt.margin.length === 2) {
  26. opt.margin = [opt.margin[0], opt.margin[1], opt.margin[0], opt.margin[1]];
  27. }
  28. if (opt.margin.length === 4) {
  29. break;
  30. }
  31. default:
  32. throw 'Invalid margin array.';
  33. }
  34.  
  35. if (!source) {
  36. throw 'Missing source element or string.';
  37. } else if (utils.objType(source) === 'string') {
  38. source = utils.createElement('div', {
  39. innerHTML: source
  40. });
  41. } else if (utils.objType(source) === 'element') {
  42. source = utils.cloneNode(source, opt.html2canvas.javascriptEnabled);
  43. } else {
  44. throw 'Invalid source - please specify an HTML Element or string.';
  45. }
  46.  
  47. return source;
  48. },
  49. makeContainer: function (source, pageSize) {
  50. var overlayCSS = {
  51. position: 'fixed',
  52. overflow: 'hidden',
  53. zIndex: 1000,
  54. left: 0,
  55. right: 0,
  56. bottom: 0,
  57. top: 0,
  58. backgroundColor: 'rgba(0,0,0,0.8)'
  59. };
  60. var containerCSS = {
  61. position: 'absolute',
  62. width: pageSize.inner.width + pageSize.unit,
  63. left: 0,
  64. right: 0,
  65. top: 0,
  66. height: 'auto',
  67. margin: 'auto',
  68. backgroundColor: 'white'
  69. };
  70.  
  71. overlayCSS.opacity = 0;
  72.  
  73. var overlay = utils.createElement('div', {
  74. className: 'html2pdf__overlay',
  75. style: overlayCSS
  76. });
  77. var container = utils.createElement('div', {
  78. className: 'html2pdf__container',
  79. style: containerCSS
  80. });
  81. container.appendChild(source);
  82. overlay.appendChild(container);
  83. document.body.appendChild(overlay);
  84.  
  85. var pageBreaks = source.querySelectorAll('.html2pdf__page-break');
  86. var pxPageHeight = pageSize.inner.height * pageSize.k / 72 * 96;
  87. Array.prototype.forEach.call(pageBreaks, function (el) {
  88. el.style.display = 'block';
  89. var clientRect = el.getBoundingClientRect();
  90. el.style.height = pxPageHeight - (clientRect.top % pxPageHeight) + 'px';
  91. }, this);
  92.  
  93. return container;
  94. },
  95. makePDF: function (canvas, pageSize, opt) {
  96. var ctx = canvas.getContext('2d');
  97. var pxFullHeight = canvas.height;
  98. var pxPageHeight = Math.floor(canvas.width * pageSize.inner.ratio);
  99. var nPages = Math.ceil(pxFullHeight / pxPageHeight);
  100.  
  101. var pageCanvas = document.createElement('canvas');
  102. var pageCtx = pageCanvas.getContext('2d');
  103. var pageHeight = pageSize.inner.height;
  104. pageCanvas.width = canvas.width;
  105. pageCanvas.height = pxPageHeight;
  106.  
  107. var pdf = new jsPDF(opt.jsPDF);
  108.  
  109. for (var page = 0; page < nPages; page++) {
  110. if (page === nPages - 1) {
  111. pageCanvas.height = pxFullHeight % pxPageHeight;
  112. pageHeight = pageCanvas.height * pageSize.inner.width / pageCanvas.width;
  113. }
  114.  
  115. var w = pageCanvas.width;
  116. var h = pageCanvas.height;
  117. pageCtx.fillStyle = 'white';
  118. pageCtx.fillRect(0, 0, w, h);
  119. pageCtx.drawImage(canvas, 0, page * pxPageHeight, w, h, 0, 0, w, h);
  120.  
  121. if (page) pdf.addPage();
  122. var imgData = pageCanvas.toDataURL('image/' + opt.image.type, opt.image.quality);
  123. pdf.addImage(imgData, opt.image.type, opt.margin[1], opt.margin[0],
  124. pageSize.inner.width, pageHeight);
  125.  
  126. if (opt.enableLinks) {
  127. var pageTop = page * pageSize.inner.height;
  128. opt.links.forEach(function (link) {
  129. if (link.clientRect.top > pageTop && link.clientRect.top < pageTop + pageSize.inner.height) {
  130. var left = opt.margin[1] + link.clientRect.left;
  131. var top = opt.margin[0] + link.clientRect.top - pageTop;
  132. pdf.link(left, top, link.clientRect.width, link.clientRect.height, {
  133. url: link.el.href
  134. });
  135. }
  136. });
  137. }
  138. }
  139.  
  140. pdf.save(opt.filename);
  141. }
  142. };
  143.  
  144. var utils = {
  145. objType: function (obj) {
  146. if (typeof obj === 'undefined') return 'undefined';
  147. else if (typeof obj === 'string' || obj instanceof String) return 'string';
  148. else if (typeof obj === 'number' || obj instanceof Number) return 'number';
  149. else if (!!obj && obj.constructor === Array) return 'array';
  150. else if (obj && obj.nodeType === 1) return 'element';
  151. else if (typeof obj === 'object') return 'object';
  152. else return 'unknown';
  153. },
  154. createElement: function (tagName, opt) {
  155. var el = document.createElement(tagName);
  156. if (opt.className) el.className = opt.className;
  157. if (opt.innerHTML) {
  158. el.innerHTML = opt.innerHTML;
  159. var scripts = el.getElementsByTagName('script');
  160. for (var i = scripts.length; i-- > 0; null) {
  161. scripts[i].parentNode.removeChild(scripts[i]);
  162. }
  163. }
  164. for (var key in opt.style) {
  165. el.style[key] = opt.style[key];
  166. }
  167. return el;
  168. },
  169. cloneNode: function (node, javascriptEnabled) {
  170. var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
  171. for (var child = node.firstChild; child; child = child.nextSibling) {
  172. if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
  173. clone.appendChild(utils.cloneNode(child, javascriptEnabled));
  174. }
  175. }
  176.  
  177. if (node.nodeType === 1) {
  178. if (node.nodeName === 'CANVAS') {
  179. clone.width = node.width;
  180. clone.height = node.height;
  181. clone.getContext('2d').drawImage(node, 0, 0);
  182. } else if (node.nodeName === 'TEXTAREA' || node.nodeName === 'SELECT') {
  183. clone.value = node.value;
  184. }
  185.  
  186. clone.addEventListener('load', function () {
  187. clone.scrollTop = node.scrollTop;
  188. clone.scrollLeft = node.scrollLeft;
  189. }, true);
  190. }
  191.  
  192. return clone;
  193. },
  194. unitConvert: function (obj, k) {
  195. var newObj = {};
  196. for (var key in obj) {
  197. newObj[key] = obj[key] * 72 / 96 / k;
  198. }
  199. return newObj;
  200. },
  201. getPageSize: function (orientation, unit, format) {
  202. if (typeof orientation === 'object') {
  203. var options = orientation;
  204. orientation = options.orientation;
  205. unit = options.unit || unit;
  206. format = options.format || format;
  207. }
  208.  
  209. unit = unit || 'mm';
  210. format = format || 'a4';
  211. orientation = ('' + (orientation || 'P')).toLowerCase();
  212. var format_as_string = ('' + format).toLowerCase();
  213.  
  214. var pageFormats = {
  215. 'a0': [2383.94, 3370.39],
  216. 'a1': [1683.78, 2383.94],
  217. 'a2': [1190.55, 1683.78],
  218. 'a3': [841.89, 1190.55],
  219. 'a4': [595.28, 841.89],
  220. 'a5': [419.53, 595.28],
  221. 'a6': [297.64, 419.53],
  222. 'a7': [209.76, 297.64],
  223. 'a8': [147.40, 209.76],
  224. 'a9': [104.88, 147.40],
  225. 'a10': [73.70, 104.88],
  226. 'b0': [2834.65, 4008.19],
  227. 'b1': [2004.09, 2834.65],
  228. 'b2': [1417.32, 2004.09],
  229. 'b3': [1000.63, 1417.32],
  230. 'b4': [708.66, 1000.63],
  231. 'b5': [498.90, 708.66],
  232. 'b6': [354.33, 498.90],
  233. 'b7': [249.45, 354.33],
  234. 'b8': [175.75, 249.45],
  235. 'b9': [124.72, 175.75],
  236. 'b10': [87.87, 124.72],
  237. 'c0': [2599.37, 3676.54],
  238. 'c1': [1836.85, 2599.37],
  239. 'c2': [1298.27, 1836.85],
  240. 'c3': [918.43, 1298.27],
  241. 'c4': [649.13, 918.43],
  242. 'c5': [459.21, 649.13],
  243. 'c6': [323.15, 459.21],
  244. 'c7': [229.61, 323.15],
  245. 'c8': [161.57, 229.61],
  246. 'c9': [113.39, 161.57],
  247. 'c10': [79.37, 113.39],
  248. 'dl': [311.81, 623.62],
  249. 'letter': [612, 792],
  250. 'government-letter': [576, 756],
  251. 'legal': [612, 1008],
  252. 'junior-legal': [576, 360],
  253. 'ledger': [1224, 792],
  254. 'tabloid': [792, 1224],
  255. 'credit-card': [153, 243]
  256. };
  257.  
  258. var k;
  259. switch (unit) {
  260. case 'pt':
  261. k = 1;
  262. break;
  263. case 'mm':
  264. k = 72 / 25.4;
  265. break;
  266. case 'cm':
  267. k = 72 / 2.54;
  268. break;
  269. case 'in':
  270. k = 72;
  271. break;
  272. case 'px':
  273. k = 72 / 96;
  274. break;
  275. case 'pc':
  276. k = 12;
  277. break;
  278. case 'em':
  279. k = 12;
  280. break;
  281. case 'ex':
  282. k = 6;
  283. break;
  284. default:
  285. throw ('Invalid unit: ' + unit);
  286. }
  287.  
  288. var pageHeight, pageWidth;
  289. if (pageFormats.hasOwnProperty(format_as_string)) {
  290. pageHeight = pageFormats[format_as_string][1] / k;
  291. pageWidth = pageFormats[format_as_string][0] / k;
  292. } else {
  293. try {
  294. pageHeight = format[1];
  295. pageWidth = format[0];
  296. } catch (err) {
  297. throw new Error('Invalid format: ' + format);
  298. }
  299. }
  300.  
  301. var tmp;
  302. if (orientation === 'p' || orientation === 'portrait') {
  303. orientation = 'p';
  304. if (pageWidth > pageHeight) {
  305. tmp = pageWidth;
  306. pageWidth = pageHeight;
  307. pageHeight = tmp;
  308. }
  309. } else if (orientation === 'l' || orientation === 'landscape') {
  310. orientation = 'l';
  311. if (pageHeight > pageWidth) {
  312. tmp = pageWidth;
  313. pageWidth = pageHeight;
  314. pageHeight = tmp;
  315. }
  316. } else {
  317. throw ('Invalid orientation: ' + orientation);
  318. }
  319.  
  320. var info = {
  321. 'width': pageWidth,
  322. 'height': pageHeight,
  323. 'unit': unit,
  324. 'k': k
  325. };
  326. return info;
  327. }
  328. };
  329.  
  330. var html2pdf = function (source, opt) {
  331. opt = utils.objType(opt) === 'object' ? opt : {};
  332. source = func.parseInput(source, opt);
  333.  
  334. var pageSize = utils.getPageSize(opt.jsPDF);
  335. pageSize.inner = {
  336. width: pageSize.width - opt.margin[1] - opt.margin[3],
  337. height: pageSize.height - opt.margin[0] - opt.margin[2]
  338. };
  339. pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;
  340.  
  341. var container = func.makeContainer(source, pageSize);
  342. var overlay = container.parentElement;
  343.  
  344. if (opt.enableLinks) {
  345. opt.links = [];
  346. var links = container.querySelectorAll('a');
  347. var containerRect = utils.unitConvert(container.getBoundingClientRect(), pageSize.k);
  348.  
  349. Array.prototype.forEach.call(links, function (link) {
  350. var clientRects = link.getClientRects();
  351. for (var i = 0; i < clientRects.length; i++) {
  352. var clientRect = utils.unitConvert(clientRects[i], pageSize.k);
  353. clientRect.left -= containerRect.left;
  354. clientRect.top -= containerRect.top;
  355. opt.links.push({
  356. el: link,
  357. clientRect: clientRect
  358. });
  359. }
  360. });
  361. }
  362.  
  363. var onRendered = opt.html2canvas.onrendered || function () {};
  364. opt.html2canvas.onrendered = function (canvas) {
  365. onRendered(canvas);
  366. document.body.removeChild(overlay);
  367. func.makePDF(canvas, pageSize, opt);
  368. };
  369. html2canvas(container, opt.html2canvas);
  370. };
  371.  
  372. return html2pdf;
  373. }));
Add Comment
Please, Sign In to add comment