buttons.print.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*!
  2. * Print button for Buttons and DataTables.
  3. * 2016 SpryMedia Ltd - datatables.net/license
  4. */
  5. (function( factory ){
  6. if ( typeof define === 'function' && define.amd ) {
  7. // AMD
  8. define( ['jquery', 'datatables.net', 'datatables.net-buttons'], function ( $ ) {
  9. return factory( $, window, document );
  10. } );
  11. }
  12. else if ( typeof exports === 'object' ) {
  13. // CommonJS
  14. module.exports = function (root, $) {
  15. if ( ! root ) {
  16. root = window;
  17. }
  18. if ( ! $ || ! $.fn.dataTable ) {
  19. $ = require('datatables.net')(root, $).$;
  20. }
  21. if ( ! $.fn.dataTable.Buttons ) {
  22. require('datatables.net-buttons')(root, $);
  23. }
  24. return factory( $, root, root.document );
  25. };
  26. }
  27. else {
  28. // Browser
  29. factory( jQuery, window, document );
  30. }
  31. }(function( $, window, document, undefined ) {
  32. 'use strict';
  33. var DataTable = $.fn.dataTable;
  34. var _link = document.createElement( 'a' );
  35. /**
  36. * Clone link and style tags, taking into account the need to change the source
  37. * path.
  38. *
  39. * @param {node} el Element to convert
  40. */
  41. var _styleToAbs = function( el ) {
  42. var url;
  43. var clone = $(el).clone()[0];
  44. var linkHost;
  45. if ( clone.nodeName.toLowerCase() === 'link' ) {
  46. clone.href = _relToAbs( clone.href );
  47. }
  48. return clone.outerHTML;
  49. };
  50. /**
  51. * Convert a URL from a relative to an absolute address so it will work
  52. * correctly in the popup window which has no base URL.
  53. *
  54. * @param {string} href URL
  55. */
  56. var _relToAbs = function( href ) {
  57. // Assign to a link on the original page so the browser will do all the
  58. // hard work of figuring out where the file actually is
  59. _link.href = href;
  60. var linkHost = _link.host;
  61. // IE doesn't have a trailing slash on the host
  62. // Chrome has it on the pathname
  63. if ( linkHost.indexOf('/') === -1 && _link.pathname.indexOf('/') !== 0) {
  64. linkHost += '/';
  65. }
  66. return _link.protocol+"//"+linkHost+_link.pathname+_link.search;
  67. };
  68. DataTable.ext.buttons.print = {
  69. className: 'buttons-print',
  70. text: function ( dt ) {
  71. return dt.i18n( 'buttons.print', 'Print' );
  72. },
  73. action: function ( e, dt, button, config ) {
  74. var data = dt.buttons.exportData(
  75. $.extend( {decodeEntities: false}, config.exportOptions ) // XSS protection
  76. );
  77. var exportInfo = dt.buttons.exportInfo( config );
  78. var columnClasses = $.map( dt.settings()[0].aoColumns, function (col, key) {
  79. return col.sClass;
  80. } );
  81. var addRow = function ( d, tag ) {
  82. var str = '<tr>';
  83. for ( var i=0, ien=d.length ; i<ien ; i++ ) {
  84. // null and undefined aren't useful in the print output
  85. var dataOut = d[i] === null || d[i] === undefined ?
  86. '' :
  87. d[i];
  88. var classAttr = columnClasses[i] ?
  89. 'class="'+columnClasses[i]+'"' :
  90. '';
  91. str += '<'+tag+' '+classAttr+'>'+dataOut+'</'+tag+'>';
  92. }
  93. return str + '</tr>';
  94. };
  95. // Construct a table for printing
  96. var html = '<table class="'+dt.table().node().className+'">';
  97. if ( config.header ) {
  98. html += '<thead>'+ addRow( data.header, 'th' ) +'</thead>';
  99. }
  100. html += '<tbody>';
  101. for ( var i=0, ien=data.body.length ; i<ien ; i++ ) {
  102. html += addRow( data.body[i], 'td' );
  103. }
  104. html += '</tbody>';
  105. if ( config.footer && data.footer ) {
  106. html += '<tfoot>'+ addRow( data.footer, 'th' ) +'</tfoot>';
  107. }
  108. html += '</table>';
  109. // Open a new window for the printable table
  110. var win = window.open( '', '' );
  111. win.document.close();
  112. // Inject the title and also a copy of the style and link tags from this
  113. // document so the table can retain its base styling. Note that we have
  114. // to use string manipulation as IE won't allow elements to be created
  115. // in the host document and then appended to the new window.
  116. var head = '<title>'+exportInfo.title+'</title>';
  117. $('style, link').each( function () {
  118. head += _styleToAbs( this );
  119. } );
  120. try {
  121. win.document.head.innerHTML = head; // Work around for Edge
  122. }
  123. catch (e) {
  124. $(win.document.head).html( head ); // Old IE
  125. }
  126. // Inject the table and other surrounding information
  127. win.document.body.innerHTML =
  128. '<h1>'+exportInfo.title+'</h1>'+
  129. '<div>'+(exportInfo.messageTop || '')+'</div>'+
  130. html+
  131. '<div>'+(exportInfo.messageBottom || '')+'</div>';
  132. $(win.document.body).addClass('dt-print-view');
  133. $('img', win.document.body).each( function ( i, img ) {
  134. img.setAttribute( 'src', _relToAbs( img.getAttribute('src') ) );
  135. } );
  136. if ( config.customize ) {
  137. config.customize( win, config, dt );
  138. }
  139. // Allow stylesheets time to load
  140. win.setTimeout( function () {
  141. if ( config.autoPrint ) {
  142. win.print(); // blocking - so close will not
  143. win.close(); // execute until this is done
  144. }
  145. }, 1000 );
  146. },
  147. title: '*',
  148. messageTop: '*',
  149. messageBottom: '*',
  150. exportOptions: {},
  151. header: true,
  152. footer: false,
  153. autoPrint: true,
  154. customize: null
  155. };
  156. return DataTable.Buttons;
  157. }));