bootstrap-table-print.js 4.6 KB

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