bootstrap-table-print.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /**
  2. * @update zhixin wen <wenzhixin2010@gmail.com>
  3. */
  4. const Utils = $.fn.bootstrapTable.utils
  5. const bootstrap = {
  6. 3: {
  7. icons: {
  8. print: 'glyphicon-print icon-share'
  9. }
  10. },
  11. 4: {
  12. icons: {
  13. print: 'fa-print'
  14. }
  15. }
  16. }[Utils.bootstrapVersion]
  17. function printPageBuilderDefault (table) {
  18. return `
  19. <html>
  20. <head>
  21. <style type="text/css" media="print">
  22. @page {
  23. size: auto;
  24. margin: 25px 0 25px 0;
  25. }
  26. </style>
  27. <style type="text/css" media="all">
  28. table {
  29. border-collapse: collapse;
  30. font-size: 12px;
  31. }
  32. table, th, td {
  33. border: 1px solid grey;
  34. }
  35. th, td {
  36. text-align: center;
  37. vertical-align: middle;
  38. }
  39. p {
  40. font-weight: bold;
  41. margin-left:20px;
  42. }
  43. table {
  44. width:94%;
  45. margin-left:3%;
  46. margin-right:3%;
  47. }
  48. div.bs-table-print {
  49. text-align:center;
  50. }
  51. </style>
  52. </head>
  53. <title>Print Table</title>
  54. <body>
  55. <p>Printed on: ${new Date} </p>
  56. <div class="bs-table-print">${table}</div>
  57. </body>
  58. </html>`
  59. }
  60. $.extend($.fn.bootstrapTable.defaults, {
  61. showPrint: false,
  62. printAsFilteredAndSortedOnUI: true,
  63. printSortColumn: undefined,
  64. printSortOrder: 'asc',
  65. printPageBuilder (table) {
  66. return printPageBuilderDefault(table)
  67. }
  68. })
  69. $.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
  70. printFilter: undefined,
  71. printIgnore: false,
  72. printFormatter: undefined
  73. })
  74. $.extend($.fn.bootstrapTable.defaults.icons, {
  75. print: bootstrap.icons.print
  76. })
  77. $.BootstrapTable = class extends $.BootstrapTable {
  78. initToolbar (...args) {
  79. this.showToolbar = this.showToolbar || this.options.showPrint
  80. super.initToolbar(...args)
  81. if (!this.options.showPrint) {
  82. return
  83. }
  84. const $btnGroup = this.$toolbar.find('>.btn-group')
  85. let $print = $btnGroup.find('button.bs-print')
  86. if (!$print.length) {
  87. $print = $(`
  88. <button class="${this.constants.buttonsClass} bs-print" type="button">
  89. <i class="${this.options.iconsPrefix} ${this.options.icons.print}"></i>
  90. </button>`
  91. ).appendTo($btnGroup)
  92. }
  93. $print.off('click').on('click', () => {
  94. this.doPrint(this.options.printAsFilteredAndSortedOnUI ?
  95. this.getData() : this.options.data.slice(0))
  96. })
  97. }
  98. doPrint (data) {
  99. const formatValue = (row, i, column ) => {
  100. const value = row[column.field]
  101. if (typeof column.printFormatter === 'function') {
  102. return column.printFormatter(...[value, row, i])
  103. }
  104. return typeof value === 'undefined' ? '-' : value
  105. }
  106. const buildTable = (data, columnsArray) => {
  107. const html = ['<table><thead>']
  108. for (const columns of columnsArray) {
  109. html.push('<tr>')
  110. for (let h = 0; h < columns.length; h++) {
  111. if (!columns[h].printIgnore) {
  112. html.push(
  113. `<th
  114. ${Utils.sprintf(' rowspan="%s"', columns[h].rowspan)}
  115. ${Utils.sprintf(' colspan="%s"', columns[h].colspan)}
  116. >${columns[h].title}</th>`)
  117. }
  118. }
  119. html.push('</tr>')
  120. }
  121. html.push('</thead><tbody>')
  122. for (let i = 0; i < data.length; i++) {
  123. html.push('<tr>')
  124. for (const columns of columnsArray) {
  125. for (let j = 0; j < columns.length; j++) {
  126. if (!columns[j].printIgnore && columns[j].field) {
  127. html.push('<td>', formatValue(data[i], i, columns[j]), '</td>')
  128. }
  129. }
  130. }
  131. html.push('</tr>')
  132. }
  133. html.push('</tbody></table>')
  134. return html.join('')
  135. }
  136. const sortRows = (data, colName, sortOrder) => {
  137. if (!colName) {
  138. return data
  139. }
  140. let reverse = sortOrder !== 'asc'
  141. reverse = -((+reverse) || -1)
  142. return data.sort((a, b) => reverse * (a[colName].localeCompare(b[colName])))
  143. }
  144. const filterRow = (row, filters) => {
  145. for (let index = 0; index < filters.length; ++index) {
  146. if (row[filters[index].colName] !== filters[index].value) {
  147. return false
  148. }
  149. }
  150. return true
  151. }
  152. const filterRows = (data, filters) => data.filter(row => filterRow(row,filters))
  153. const getColumnFilters = columns => !columns || !columns[0] ? [] : columns[0].filter(col => col.printFilter).map(col => ({
  154. colName: col.field,
  155. value: col.printFilter
  156. }))
  157. data = filterRows(data,getColumnFilters(this.options.columns))
  158. data = sortRows(data, this.options.printSortColumn, this.options.printSortOrder)
  159. const table = buildTable(data, this.options.columns)
  160. const newWin = window.open('')
  161. newWin.document.write(this.options.printPageBuilder.call(this, table))
  162. newWin.print()
  163. newWin.close()
  164. }
  165. }