| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- /**
- * @update zhixin wen <wenzhixin2010@gmail.com>
- */
- const Utils = $.fn.bootstrapTable.utils
- function printPageBuilderDefault (table, styles) {
- return `
- <html>
- <head>
- ${styles}
- <style type="text/css" media="print">
- @page {
- size: auto;
- margin: 25px 0 25px 0;
- }
- </style>
- <style type="text/css" media="all">
- table {
- border-collapse: collapse;
- font-size: 12px;
- }
- table, th, td {
- border: 1px solid grey;
- }
- th, td {
- text-align: center;
- vertical-align: middle;
- }
- p {
- font-weight: bold;
- margin-left:20px;
- }
- table {
- width: 94%;
- margin-left: 3%;
- margin-right: 3%;
- }
- div.bs-table-print {
- text-align: center;
- }
- </style>
- </head>
- <title>Print Table</title>
- <body>
- <p>Printed on: ${new Date} </p>
- <div class="bs-table-print">${table}</div>
- </body>
- </html>
- `
- }
- Object.assign($.fn.bootstrapTable.locales, {
- formatPrint () {
- return 'Print'
- }
- })
- Object.assign($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
- Object.assign($.fn.bootstrapTable.defaults, {
- showPrint: false,
- printAsFilteredAndSortedOnUI: true,
- printSortColumn: undefined,
- printSortOrder: 'asc',
- printStyles: [],
- printPageBuilder (table, styles) {
- return printPageBuilderDefault(table, styles)
- }
- })
- Object.assign($.fn.bootstrapTable.columnDefaults, {
- printFilter: undefined,
- printIgnore: false,
- printFormatter: undefined
- })
- Object.assign($.fn.bootstrapTable.defaults.icons, {
- print: {
- bootstrap3: 'glyphicon-print icon-share',
- bootstrap5: 'bi-printer',
- 'bootstrap-table': 'icon-printer'
- }[$.fn.bootstrapTable.theme] || 'fa-print'
- })
- $.BootstrapTable = class extends $.BootstrapTable {
- init (...args) {
- super.init(...args)
- if (!this.options.showPrint) {
- return
- }
- this.mergedCells = []
- }
- initToolbar (...args) {
- this.showToolbar = this.showToolbar || this.options.showPrint
- if (this.options.showPrint) {
- this.buttons = Object.assign(this.buttons, {
- print: {
- text: this.options.formatPrint(),
- icon: this.options.icons.print,
- event: () => {
- this.doPrint(this.options.printAsFilteredAndSortedOnUI ? this.getData() : this.options.data.slice(0))
- },
- attributes: {
- 'aria-label': this.options.formatPrint(),
- title: this.options.formatPrint()
- }
- }
- })
- }
- super.initToolbar(...args)
- }
- mergeCells (options) {
- super.mergeCells(options)
- if (!this.options.showPrint) {
- return
- }
- let col = this.getVisibleFields().indexOf(options.field)
- if (Utils.hasDetailViewIcon(this.options)) {
- col += 1
- }
- this.mergedCells.push({
- row: options.index,
- col,
- rowspan: options.rowspan || 1,
- colspan: options.colspan || 1
- })
- }
- doPrint (data) {
- const canPrint = column => {
- return !column.printIgnore && column.visible
- }
- const formatValue = (row, i, column) => {
- const value_ = Utils.getItemField(row, column.field, this.options.escape, column.escape)
- const value = Utils.calculateObjectValue(column,
- column.printFormatter || column.formatter,
- [value_, row, i], value_)
- return typeof value === 'undefined' || value === null ?
- this.options.undefinedText : $('<div>').html(value).html()
- }
- const buildTable = (data, columnsArray) => {
- const dir = this.$el.attr('dir') || 'ltr'
- const html = [`<table dir="${dir}"><thead>`]
- for (const columns of columnsArray) {
- html.push('<tr>')
- for (let h = 0; h < columns.length; h++) {
- if (canPrint(columns[h])) {
- html.push(
- `<th
- ${Utils.sprintf(' rowspan="%s"', columns[h].rowspan)}
- ${Utils.sprintf(' colspan="%s"', columns[h].colspan)}
- >${columns[h].title}</th>`)
- }
- }
- html.push('</tr>')
- }
- html.push('</thead><tbody>')
- const notRender = []
- if (this.mergedCells) {
- for (let mc = 0; mc < this.mergedCells.length; mc++) {
- const currentMergedCell = this.mergedCells[mc]
- for (let rs = 0; rs < currentMergedCell.rowspan; rs++) {
- const row = currentMergedCell.row + rs
- for (let cs = 0; cs < currentMergedCell.colspan; cs++) {
- const col = currentMergedCell.col + cs
- notRender.push(`${row},${col}`)
- }
- }
- }
- }
- for (let i = 0; i < data.length; i++) {
- html.push('<tr>')
- const columns = columnsArray.flat(1)
- columns.sort((c1, c2) => {
- return c1.colspanIndex - c2.colspanIndex
- })
- for (let j = 0; j < columns.length; j++) {
- if (columns[j].colspanGroup > 0) continue
- let rowspan = 0
- let colspan = 0
- if (this.mergedCells) {
- for (let mc = 0; mc < this.mergedCells.length; mc++) {
- const currentMergedCell = this.mergedCells[mc]
- if (currentMergedCell.col === j && currentMergedCell.row === i) {
- rowspan = currentMergedCell.rowspan
- colspan = currentMergedCell.colspan
- }
- }
- }
- if (
- canPrint(columns[j]) &&
- (
- !notRender.includes(`${i},${j}`) ||
- rowspan > 0 && colspan > 0
- )
- ) {
- if (rowspan > 0 && colspan > 0) {
- html.push(`<td ${Utils.sprintf(' rowspan="%s"', rowspan)} ${Utils.sprintf(' colspan="%s"', colspan)}>`, formatValue(data[i], i, columns[j]), '</td>')
- } else {
- html.push('<td>', formatValue(data[i], i, columns[j]), '</td>')
- }
- }
- }
- html.push('</tr>')
- }
- html.push('</tbody>')
- if (this.options.showFooter) {
- html.push('<footer><tr>')
- for (const columns of columnsArray) {
- for (let h = 0; h < columns.length; h++) {
- if (canPrint(columns)) {
- const footerData = Utils.trToData(columns, this.$el.find('>tfoot>tr'))
- const footerValue = Utils.calculateObjectValue(columns[h], columns[h].footerFormatter, [data], footerData[0] && footerData[0][columns[h].field] || '')
- html.push(`<th>${footerValue}</th>`)
- }
- }
- }
- html.push('</tr></footer>')
- }
- html.push('</table>')
- return html.join('')
- }
- const sortRows = (data, colName, sortOrder) => {
- if (!colName) {
- return data
- }
- let reverse = sortOrder !== 'asc'
- reverse = -(+reverse || -1)
- return data.sort((a, b) => reverse * a[colName].localeCompare(b[colName]))
- }
- const filterRow = (row, filters) => {
- for (let index = 0; index < filters.length; ++index) {
- if (row[filters[index].colName] !== filters[index].value) {
- return false
- }
- }
- return true
- }
- const filterRows = (data, filters) => data.filter(row => filterRow(row, filters))
- const getColumnFilters = columns => !columns || !columns[0] ? [] : columns[0].filter(col => col.printFilter).map(col => ({
- colName: col.field,
- value: col.printFilter
- }))
- data = filterRows(data, getColumnFilters(this.options.columns))
- data = sortRows(data, this.options.printSortColumn, this.options.printSortOrder)
- const table = buildTable(data, this.options.columns)
- const newWin = window.open('')
- const printStyles = typeof this.options.printStyles === 'string' ?
- this.options.printStyles.replace(/\[|\]| /g, '').toLowerCase().split(',') :
- this.options.printStyles
- const styles = printStyles.map(it =>
- `<link rel="stylesheet" href="${it}" />`).join('')
- const calculatedPrintPage = Utils.calculateObjectValue(this, this.options.printPageBuilder,
- [table, styles], printPageBuilderDefault(table, styles))
- const startPrint = () => {
- newWin.focus()
- newWin.print()
- newWin.close()
- }
- newWin.document.write(calculatedPrintPage)
- newWin.document.close()
- if (printStyles.length) {
- const links = document.getElementsByTagName('link')
- const lastLink = links[links.length - 1]
- lastLink.onload = startPrint
- } else {
- startPrint()
- }
- }
- }
|