✨ 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) {
|
prompt(content: string, tip: string) {
|
||||||
return ElMessageBox.prompt(content, tip, {
|
return ElMessageBox.prompt(content, tip, {
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ export default {
|
||||||
confirmTitle: 'System Hint',
|
confirmTitle: 'System Hint',
|
||||||
exportMessage: 'Whether to confirm export data item?',
|
exportMessage: 'Whether to confirm export data item?',
|
||||||
importMessage: 'Whether to confirm import data item?',
|
importMessage: 'Whether to confirm import data item?',
|
||||||
|
printMessage: 'Whether to confirm print data item?',
|
||||||
createSuccess: 'Create Success',
|
createSuccess: 'Create Success',
|
||||||
updateSuccess: 'Update Success',
|
updateSuccess: 'Update Success',
|
||||||
delMessage: 'Delete the selected data?',
|
delMessage: 'Delete the selected data?',
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ export default {
|
||||||
confirmTitle: '系统提示',
|
confirmTitle: '系统提示',
|
||||||
exportMessage: '是否确认导出数据项?',
|
exportMessage: '是否确认导出数据项?',
|
||||||
importMessage: '是否确认导入数据项?',
|
importMessage: '是否确认导入数据项?',
|
||||||
|
printMessage: '是否确认打印数据项?',
|
||||||
createSuccess: '新增成功',
|
createSuccess: '新增成功',
|
||||||
updateSuccess: '修改成功',
|
updateSuccess: '修改成功',
|
||||||
delMessage: '是否删除所选中数据?',
|
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" />
|
<Icon icon="ep:download" class="mr-5px" />
|
||||||
导出
|
导出
|
||||||
</el-button>
|
</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-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<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="id" />
|
||||||
<el-table-column label="租户名" align="center" prop="name" />
|
<el-table-column label="租户名" align="center" prop="name" />
|
||||||
<el-table-column label="租户套餐" align="center" prop="packageId">
|
<el-table-column label="租户套餐" align="center" prop="packageId">
|
||||||
|
|
@ -138,7 +141,13 @@
|
||||||
width="180"
|
width="180"
|
||||||
:formatter="dateFormatter"
|
: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">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
@ -175,6 +184,7 @@
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import download from '@/utils/download'
|
import download from '@/utils/download'
|
||||||
|
import { printTable } from '@/utils/print'
|
||||||
import * as TenantApi from '@/api/system/tenant'
|
import * as TenantApi from '@/api/system/tenant'
|
||||||
import * as TenantPackageApi from '@/api/system/tenantPackage'
|
import * as TenantPackageApi from '@/api/system/tenantPackage'
|
||||||
import TenantForm from './TenantForm.vue'
|
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 () => {
|
onMounted(async () => {
|
||||||
await getList()
|
await getList()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue