当前位置: 首页 > news >正文

Vue3 打印表格、Element Plus 打印、前端打印、表格导出打印、打印插件封装、JavaScript 打印、打印预览

🚀 Vue3 高级表格打印工具封装(支持预览、分页、样式美化)

关键词:Vue3 打印表格、Element Plus 打印、前端打印、表格导出打印、打印插件封装、JavaScript 打印、打印预览

在企业级应用中,我们经常遇到打印报表、导出数据的需求,今天分享一个基于 Vue3 封装的表格打印工具类,支持:

  • 🖨️ 表格打印 & 预览
  • 🎨 样式高度可定制
  • 📄 分页支持
  • 🧩 formatter 格式化器
  • ✅ 可组合式 API(useTablePrint

🧠 核心封装代码

// utils/tablePrint.js
// 高级表格打印工具类
export class TablePrintUtil {constructor(options = {}) {this.options = {title: '数据表格',showHeader: true,showFooter: true,pageSize: 'A4',orientation: 'portrait',margins: '1cm',fontSize: '12px',headerStyle: {backgroundColor: '#f5f7fa',color: '#333',fontWeight: 'bold'},...options}}async printTable(data, columns, customOptions = {}) {const finalOptions = { ...this.options, ...customOptions }try {const printContent = this.generateAdvancedHTML(data, columns, finalOptions)await this.executePrint(printContent, finalOptions)} catch (error) {console.error('打印失败:', error)throw error}}generateAdvancedHTML(data, columns, options) {const currentTime = new Date().toLocaleString('zh-CN')const totalPages = Math.ceil(data.length / 20)return \`<!DOCTYPE html><html><head><meta charset="utf-8"><title>\${options.title}</title><style>\${this.generatePrintStyles(options)}</style></head><body>\${options.showHeader ? this.generateHeader(options, currentTime) : ''}\${this.generateTableContent(data, columns, options)}\${options.showFooter ? this.generateFooter(data.length, totalPages) : ''}<script>\${this.generatePrintScript(options)}</script></body></html>\`}generatePrintStyles(options) {return \`@media print {body { margin: 0; }.no-print { display: none !important; }@page {margin: \${options.margins};size: \${options.pageSize} \${options.orientation};}}body {font-family: 'Microsoft YaHei', Arial, sans-serif;margin: 20px;color: #333;font-size: \${options.fontSize};}.print-header {text-align: center;margin-bottom: 30px;border-bottom: 2px solid #409EFF;padding-bottom: 15px;}.print-title {font-size: 28px;font-weight: bold;color: #409EFF;}.print-subtitle {color: #666;font-size: 14px;}.print-table {width: 100%;border-collapse: collapse;margin: 20px 0;}.print-table th, .print-table td {border: 1px solid #ddd;padding: 10px 8px;word-break: break-word;}.print-table th {background-color: \${options.headerStyle.backgroundColor};color: \${options.headerStyle.color};font-weight: \${options.headerStyle.fontWeight};}.print-table tbody tr:nth-child(even) {background-color: #fafafa;}.print-footer {margin-top: 30px;display: flex;justify-content: space-between;font-size: 12px;color: #666;border-top: 1px solid #eee;padding-top: 15px;}.text-center { text-align: center; }.text-right { text-align: right; }\`}generateHeader(options, time) {return \`<div class="print-header"><h1 class="print-title">\${options.title}</h1><p class="print-subtitle">打印时间: \${time}</p></div>\`}generateTableContent(data, columns, options) {const header = columns.map(col => \`<th>\${col.label}</th>\`).join('')const rows = data.map((row, idx) => {const cells = columns.map(col => {let value = this.getNestedValue(row, col.prop)if (col.formatter) value = col.formatter(row, col, value, idx)return \`<td class="\${col.align ? 'text-' + col.align : ''}">\${value ?? ''}</td>\`}).join('')return \`<tr>\${cells}</tr>\`}).join('')return \`<table class="print-table"><thead><tr>\${header}</tr></thead><tbody>\${rows}</tbody></table>\`}generateFooter(total, pages) {return \`<div class="print-footer"><div>共 \${total} 条记录</div><div>1 页,共 \${pages}</div></div>\`}generatePrintScript() {return \`window.onload = () => setTimeout(() => window.print(), 800);window.onafterprint = () => setTimeout(() => window.close(), 1000);\`}async executePrint(content) {return new Promise((resolve, reject) => {try {const win = window.open('', '_blank', 'width=800,height=600')if (!win) return reject(new Error('无法打开打印窗口'))win.document.write(content)win.document.close()win.onload = () => setTimeout(() => { win.print(); resolve() }, 500)} catch (e) {reject(e)}})}getNestedValue(obj, path) {return path?.split('.').reduce((curr, key) => curr?.[key], obj)}previewTable(data, columns, options = {}) {const content = this.generateAdvancedHTML(data, columns, {...this.options,...options}).replace(this.generatePrintScript(options), '// 预览模式不自动打印')const win = window.open('', '_blank', 'width=1000,height=700')win.document.write(content)win.document.close()}
}// Vue组合式封装
export function useTablePrint(options = {}) {const printUtil = new TablePrintUtil(options)const printTable = async (data, columns, customOptions = {}) => {try {await printUtil.printTable(data, columns, customOptions)} catch (err) {console.error('打印失败:', err)}}const previewTable = (data, columns, customOptions = {}) => {printUtil.previewTable(data, columns, customOptions)}return {printTable,previewTable,printUtil}
}

📦 使用示例(适用于 Vue3 + Element Plus)

import { useTablePrint } from '@/utils/tablePrint'const { printTable, previewTable } = useTablePrint({title: '员工信息表',fontSize: '14px'
})const columns = [{ prop: 'id', label: 'ID', align: 'center' },{ prop: 'name', label: '姓名' },{ prop: 'age', label: '年龄', align: 'center' },{ prop: 'department', label: '部门' },{prop: 'salary',label: '薪资',align: 'right',formatter: (row) => `${row.salary}`}
]const handlePrint = () => {printTable(tableData, columns)
}const handlePreview = () => {previewTable(tableData, columns)
}

📌 总结

这套打印封装解决了多数前端项目中的打印难题,支持高度自定义和开箱即用。你可以根据项目需求扩展页码逻辑、横向打印、多页数据分割等。

如果觉得实用,欢迎 👍 点赞、🌟 收藏、📢 分享!

http://www.xdnf.cn/news/590311.html

相关文章:

  • Java使用Collections集合工具类
  • DAY 33 简单的神经网络
  • 软件设计师“面向对象设计”真题考点分析——求三连
  • 深入剖析 Doris 倒排索引(上):原理与应用全解析​
  • 腾讯2025年校招笔试真题手撕(三)
  • 嵌入式学习笔记 - 关于ARM编辑器compiler version 5 and compiler version 6
  • 软考高项考前48小时冲刺:核心考点记忆 + 错题复盘 + 3 科重点
  • 养生指南:五维提升健康品质
  • 基于cornerstone3D的dicom影像浏览器 第二十一章 显示DICOM TAGS
  • Paimon和Hive相集成
  • Java基础 Day18
  • Redis 是否适合像 MySQL 一样当数据库使用?
  • 单一职责原则 (Single Responsibility Principle, SRP)
  • html主题切换小demo
  • Oracle 中 SHRINK 与 MOVE 操作的比较
  • NR 通讯的整体架构
  • PyTorch可视化工具——使用Visdom进行深度学习可视化
  • Jetson:aarch64平台编译onnxruntime使用GPU
  • 【GESP】C++三级真题 luogu-B4038 [GESP202409 三级] 平衡序列
  • Flask 路由跳转机制:url_for生成动态URL、redirect页面重定向
  • 基于 ZU49DR FPGA 的无线电射频数据采样转换开发平台核心板
  • Docker-Mysql
  • LLaMA-Factory微调LLM-Research/Llama-3.2-3B-Instruct模型
  • 基于多目标优化的样本调度适应度函数设计
  • 7.1.查找的基本概念
  • 高等数学-无穷级数
  • Unity飞机大战-射击类游戏3D虚拟
  • Athena 执行引擎:在线服务计算的效率王者
  • pandas :从入门到进阶的系统实践笔记
  • 错误: gdalbuildvrt 命令未找到————的问题