From ecf0cc18a0023e302faf1110d9b8dc6056baf86e Mon Sep 17 00:00:00 2001 From: preschooler Date: Sat, 12 Oct 2024 15:51:21 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=E6=96=B0=E5=A2=9Etable?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E6=89=93=E5=8D=B0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/web/useMessage.ts | 12 +++ src/locales/en.ts | 1 + src/locales/zh-CN.ts | 1 + src/utils/print.ts | 134 ++++++++++++++++++++++++++++++ src/views/system/tenant/index.vue | 26 +++++- 5 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 src/utils/print.ts diff --git a/src/hooks/web/useMessage.ts b/src/hooks/web/useMessage.ts index ac2b552e0..4d4061b0f 100644 --- a/src/hooks/web/useMessage.ts +++ b/src/hooks/web/useMessage.ts @@ -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, { diff --git a/src/locales/en.ts b/src/locales/en.ts index 6562c9b75..819cbd6df 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -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?', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index b9deb3f24..762821eed 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -42,6 +42,7 @@ export default { confirmTitle: '系统提示', exportMessage: '是否确认导出数据项?', importMessage: '是否确认导入数据项?', + printMessage: '是否确认打印数据项?', createSuccess: '新增成功', updateSuccess: '修改成功', delMessage: '是否删除所选中数据?', diff --git a/src/utils/print.ts b/src/utils/print.ts new file mode 100644 index 000000000..b75b9096b --- /dev/null +++ b/src/utils/print.ts @@ -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 = [ + // '', + // columnList + // .map( + // (columnItem: PrintTargetColumnData) => + // `` + // ) + // .join(''), + // '' + // ].join('') + printThead = [ + '', + '', + columnList + .map((columnItem: PrintTargetColumnData) => `
${columnItem.label || ''}
`) + .join(''), + '', + '' + ].join('') + printTbody = [ + '', + dataList + .map( + (dataItem: object) => + `${columnList.map((columnItem: PrintTargetColumnData) => `
${dataItem[columnItem.value] || ''}
`).join('')}` + ) + .join(''), + '' + ].join('') + } + const printContent = [ + '', + // printColgroup, + printThead, + printTbody, + '
' + ].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 = [ + '', + '', + '', + '', + '', + '', + printContent, + '', + '' + ].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) + } +} diff --git a/src/views/system/tenant/index.vue b/src/views/system/tenant/index.vue index ae9a2b790..6a9c80e3e 100644 --- a/src/views/system/tenant/index.vue +++ b/src/views/system/tenant/index.vue @@ -92,13 +92,16 @@ 导出 + + 打印 + - + @@ -138,7 +141,13 @@ width="180" :formatter="dateFormatter" /> - +