✨ feat:新增table表格打印功能
parent
4b2785bd41
commit
ecf0cc18a0
|
|
@ -83,6 +83,18 @@ export const useMessage = () => {
|
|||
}
|
||||
)
|
||||
},
|
||||
// 打印窗体
|
||||
printConfirm(content?: string, tip?: string) {
|
||||
return ElMessageBox.confirm(
|
||||
content ? content : t('common.printMessage'),
|
||||
tip ? tip : t('common.confirmTitle'),
|
||||
{
|
||||
confirmButtonText: t('common.ok'),
|
||||
cancelButtonText: t('common.cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
},
|
||||
// 提交内容
|
||||
prompt(content: string, tip: string) {
|
||||
return ElMessageBox.prompt(content, tip, {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export default {
|
|||
confirmTitle: 'System Hint',
|
||||
exportMessage: 'Whether to confirm export data item?',
|
||||
importMessage: 'Whether to confirm import data item?',
|
||||
printMessage: 'Whether to confirm print data item?',
|
||||
createSuccess: 'Create Success',
|
||||
updateSuccess: 'Update Success',
|
||||
delMessage: 'Delete the selected data?',
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export default {
|
|||
confirmTitle: '系统提示',
|
||||
exportMessage: '是否确认导出数据项?',
|
||||
importMessage: '是否确认导入数据项?',
|
||||
printMessage: '是否确认打印数据项?',
|
||||
createSuccess: '新增成功',
|
||||
updateSuccess: '修改成功',
|
||||
delMessage: '是否删除所选中数据?',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
export interface PrintTargetColumnData {
|
||||
value: string
|
||||
label: string
|
||||
width?: number
|
||||
}
|
||||
|
||||
export interface PrintTargetData {
|
||||
column: PrintTargetColumnData[]
|
||||
data: object[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Table 打印
|
||||
*
|
||||
* @param target 容器元素 ID 或 数据 (如:{"column":[{"value":"a","label":"啊","width":100},{"value":"b","label":"吧","width":200},{"value":"c","label":"唱","width":300}],"data":[{"a":"啊呀","b":"吧唧","c":"唱歌"},{"a":"天啊","b":"吧啦","c":"唱魂"}]})
|
||||
* @param hideClassAndColumn 隐藏 class 或 列 (如:['print-hide', 8])
|
||||
*/
|
||||
export function printTable(
|
||||
target: string | PrintTargetData,
|
||||
hideClassAndColumn?: (string | number)[]
|
||||
) {
|
||||
// 打印内容
|
||||
// let printColgroup: string = ''
|
||||
let printThead: string = ''
|
||||
let printTbody: string = ''
|
||||
if (typeof target === 'string') {
|
||||
const printElement = document.getElementById(target)
|
||||
if (printElement) {
|
||||
// 提取 table 元素
|
||||
// const printColgroupElement = printElement.getElementsByTagName('colgroup')[0]
|
||||
const printTheadElement = printElement.getElementsByTagName('thead')[0]
|
||||
const printTbodyElement = printElement.getElementsByTagName('tbody')[0]
|
||||
|
||||
// printColgroup = printColgroupElement?.outerHTML
|
||||
printThead = printTheadElement?.outerHTML
|
||||
printTbody = printTbodyElement?.outerHTML
|
||||
}
|
||||
} else if (target) {
|
||||
// 组装 table 元素
|
||||
const columnList: PrintTargetColumnData[] = target.column || []
|
||||
const dataList: object[] = target.data || []
|
||||
// printColgroup = [
|
||||
// '<colgroup>',
|
||||
// columnList
|
||||
// .map(
|
||||
// (columnItem: PrintTargetColumnData) =>
|
||||
// `<col name="${columnItem.value || ''}" width="${columnItem.width || ''}">`
|
||||
// )
|
||||
// .join(''),
|
||||
// '</colgroup>'
|
||||
// ].join('')
|
||||
printThead = [
|
||||
'<thead>',
|
||||
'<tr>',
|
||||
columnList
|
||||
.map((columnItem: PrintTargetColumnData) => `<th><div>${columnItem.label || ''}</div></th>`)
|
||||
.join(''),
|
||||
'</tr>',
|
||||
'</thead>'
|
||||
].join('')
|
||||
printTbody = [
|
||||
'<tbody>',
|
||||
dataList
|
||||
.map(
|
||||
(dataItem: object) =>
|
||||
`<tr>${columnList.map((columnItem: PrintTargetColumnData) => `<td><div>${dataItem[columnItem.value] || ''}</div></td>`).join('')}</tr>`
|
||||
)
|
||||
.join(''),
|
||||
'</tbody>'
|
||||
].join('')
|
||||
}
|
||||
const printContent = [
|
||||
'<table cellspacing="0" cellpadding="0" border="0">',
|
||||
// printColgroup,
|
||||
printThead,
|
||||
printTbody,
|
||||
'</table>'
|
||||
].join('')
|
||||
|
||||
// 隐藏内容
|
||||
const hideClassList: string[] = []
|
||||
const hideColumnList: string[] = []
|
||||
hideClassAndColumn?.forEach((item: string | number) => {
|
||||
if (Number.isNaN(Number(item))) {
|
||||
hideClassList.push(`.${item}`)
|
||||
} else {
|
||||
hideColumnList.push(`&:nth-child(${item})`)
|
||||
}
|
||||
})
|
||||
|
||||
// 空页面
|
||||
const printDocumentContent = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8">',
|
||||
'<style>',
|
||||
'body { font-size: 14px; color: #666666; }',
|
||||
' table { width: 100% !important; border-collapse: collapse; border-spacing: 0; }',
|
||||
' th, td { line-height: 20px; padding: 8px 8px; border: 1px solid #cccccc; text-align: left; font-size: 14px; color: #666666; }',
|
||||
' a { color: #666666; text-decoration: none; }',
|
||||
// 隐藏 class
|
||||
!!hideClassList.length
|
||||
? [' * { ', hideClassList.join(', '), ' { display: none; } }'].join('')
|
||||
: '',
|
||||
// 隐藏 column
|
||||
!!hideColumnList.length
|
||||
? [' col, th, td { ', hideColumnList.join(', '), ' { display: none; } }'].join('')
|
||||
: '',
|
||||
'</style>',
|
||||
'</head>',
|
||||
'<body>',
|
||||
printContent,
|
||||
'</body>',
|
||||
'</html>'
|
||||
].join('')
|
||||
|
||||
// 打开新窗口
|
||||
const printWindow = window.open('打印窗口', '_blank')
|
||||
if (printWindow) {
|
||||
// 将内容赋值到新页面
|
||||
printWindow.document.write(printDocumentContent)
|
||||
printWindow.document.close()
|
||||
// 聚焦,不加 focus 在某些情况下打印页面会有问题
|
||||
printWindow.focus()
|
||||
// 使用 setTimeout 等页面 dom 元素渲染完成后再打印
|
||||
const timer = setTimeout(() => {
|
||||
clearTimeout(timer)
|
||||
// 打印
|
||||
printWindow.print()
|
||||
// 关闭打印窗口
|
||||
printWindow.close()
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
|
@ -92,13 +92,16 @@
|
|||
<Icon icon="ep:download" class="mr-5px" />
|
||||
导出
|
||||
</el-button>
|
||||
<el-button type="info" plain @click="handlePrint" v-hasPermi="['system:tenant:export']">
|
||||
<Icon class="mr-5px" icon="ep:printer" />打印
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list">
|
||||
<el-table id="SystemTenantTable" v-loading="loading" :data="list">
|
||||
<el-table-column label="租户编号" align="center" prop="id" />
|
||||
<el-table-column label="租户名" align="center" prop="name" />
|
||||
<el-table-column label="租户套餐" align="center" prop="packageId">
|
||||
|
|
@ -138,7 +141,13 @@
|
|||
width="180"
|
||||
:formatter="dateFormatter"
|
||||
/>
|
||||
<el-table-column label="操作" align="center" min-width="110" fixed="right">
|
||||
<el-table-column
|
||||
class-name="table-column-print-hide"
|
||||
label="操作"
|
||||
align="center"
|
||||
min-width="110"
|
||||
fixed="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
|
|
@ -175,6 +184,7 @@
|
|||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { printTable } from '@/utils/print'
|
||||
import * as TenantApi from '@/api/system/tenant'
|
||||
import * as TenantPackageApi from '@/api/system/tenantPackage'
|
||||
import TenantForm from './TenantForm.vue'
|
||||
|
|
@ -258,6 +268,18 @@ const handleExport = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
/** 打印按钮操作 */
|
||||
const handlePrint = async () => {
|
||||
try {
|
||||
// 打印的二次确认
|
||||
await message.printConfirm()
|
||||
// 发起打印
|
||||
printTable('SystemTenantTable', ['table-column-print-hide'])
|
||||
} catch {
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(async () => {
|
||||
await getList()
|
||||
|
|
|
|||
Loading…
Reference in New Issue