UNPKG

vue-table-print

Version:

一个强大的Vue表格打印工具,支持ElementPlus、Ant Design Vue、Arco Design vue等组件库

3 lines (2 loc) 6.53 kB
class n{constructor(n={}){this.options={title:"数据表格",showHeader:!0,showFooter:!0,margins:"1cm",fontSize:"12px",headerStyle:{backgroundColor:"#f5f7fa",color:"#333",fontWeight:"bold"},customStyles:"",watermark:"",logo:"",...n}}async printTable(n,t,e={}){const r={...this.options,...e};try{const e=this.generateAdvancedHTML(n,t,r);return await this.executePrint(e,r),{success:!0}}catch(n){return console.error("打印失败:",n),{success:!1,message:n instanceof Error?n.message:"打印失败"}}}previewTable(n,t,e={}){const r={...this.options,...e},o=this.generateAdvancedHTML(n,t,r),i=window.open("","_blank","width=1000,height=700");if(!i)throw new Error("无法打开预览窗口,请检查浏览器弹窗设置");i.document.write(o.replace(this.generatePrintScript(r),"// 预览模式,不自动打印")),i.document.close()}exportToHTML(n,t,e="table-export.html",r={}){const o={...this.options,...r},i=this.generateAdvancedHTML(n,t,o),a=new Blob([i],{type:"text/html"}),l=URL.createObjectURL(a),s=document.createElement("a");s.href=l,s.download=e,document.body.appendChild(s),s.click(),document.body.removeChild(s),URL.revokeObjectURL(l)}generateAdvancedHTML(n,t,e){const r=(new Date).toLocaleString("zh-CN"),o=Math.ceil(n.length/20);return`\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset="utf-8">\n <title>${e.title}</title>\n <style>\n ${this.generatePrintStyles(e)}\n </style>\n </head>\n <body>\n ${e.showHeader?this.generateHeader(e,r):""}\n ${this.generateTableContent(n,t,e)}\n ${e.showFooter?this.generateFooter(n.length,o):""}\n \n <script>\n ${this.generatePrintScript(e)}\n <\/script>\n </body>\n </html>\n `}generatePrintStyles(n){return`\n @media print {\n body { margin: 0; }\n .no-print { display: none !important; }\n @page {\n margin: ${n.margins};\n \n \n }\n }\n \n body {\n font-family: 'Microsoft YaHei', Arial, sans-serif;\n margin: 20px;\n color: #333;\n font-size: ${n.fontSize};\n line-height: 1.6;\n ${n.watermark?this.generateWatermarkStyle(n.watermark):""}\n }\n \n .print-header {\n text-align: center;\n margin-bottom: 30px;\n border-bottom: 2px solid #409EFF;\n padding-bottom: 15px;\n position: relative;\n }\n \n .print-logo {\n position: absolute;\n left: 0;\n top: 0;\n max-height: 50px;\n max-width: 150px;\n }\n \n .print-title {\n font-size: 28px;\n font-weight: bold;\n margin: 0 0 10px 0;\n color: #409EFF;\n }\n \n .print-subtitle {\n margin: 5px 0;\n color: #666;\n font-size: 14px;\n }\n \n .print-table {\n width: 100%;\n border-collapse: collapse;\n margin: 20px 0;\n font-size: ${n.fontSize};\n }\n \n .print-table th,\n .print-table td {\n border: 1px solid #ddd;\n padding: 10px 8px;\n text-align: left;\n word-wrap: break-word;\n }\n \n .print-table th {\n background-color: ${n.headerStyle.backgroundColor};\n color: ${n.headerStyle.color};\n font-weight: ${n.headerStyle.fontWeight};\n }\n \n .print-table tbody tr:nth-child(even) {\n background-color: #fafafa;\n }\n \n .print-footer {\n margin-top: 30px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 12px;\n color: #666;\n border-top: 1px solid #eee;\n padding-top: 15px;\n }\n \n .text-center { text-align: center; }\n .text-right { text-align: right; }\n .text-left { text-align: left; }\n \n ${n.customStyles}\n `}generateWatermarkStyle(n){return`\n position: relative;\n &::before {\n content: "${n}";\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) rotate(-45deg);\n font-size: 48px;\n color: rgba(0, 0, 0, 0.1);\n z-index: -1;\n pointer-events: none;\n }\n `}generateHeader(n,t){return`\n <div class="print-header">\n ${n.logo?`<img src="${n.logo}" alt="Logo" class="print-logo">`:""}\n <h1 class="print-title">${n.title}</h1>\n <p class="print-subtitle">打印时间: ${t}</p>\n </div>\n `}generateTableContent(n,t,e){return`\n <table class="print-table">\n <thead>\n <tr>${t.map((n=>`<th style="${n.width?`width: ${n.width}`:""}">${n.label}</th>`)).join("")}</tr>\n </thead>\n <tbody>\n ${n.map(((n,e)=>`<tr>${t.map((t=>{let r=this.getNestedValue(n,t.prop);t.formatter&&"function"==typeof t.formatter&&(r=t.formatter(n,t,r,e));return`<td class="${t.align?`text-${t.align}`:""}">${null!=r?r:""}</td>`})).join("")}</tr>`)).join("")}\n </tbody>\n </table>\n `}generateFooter(n,t){return`\n <div class="print-footer">\n <div>共 ${n} 条记录</div>\n <div>第 1 页,共 ${t} 页</div>\n </div>\n `}generatePrintScript(n){return"\n window.onload = function() {\n setTimeout(function() {\n window.print();\n }, 800);\n }\n \n window.onafterprint = function() {\n setTimeout(function() {\n window.close();\n }, 1000);\n }\n "}async executePrint(n,t){return new Promise(((t,e)=>{try{const r=window.open("","_blank","width=800,height=600");if(!r)return void e(new Error("无法打开打印窗口,请检查浏览器弹窗设置"));r.document.write(n),r.document.close(),r.focus(),r.onload=()=>{setTimeout((()=>{r.print(),t()}),500)}}catch(n){e(n)}}))}getNestedValue(n,t){var e;return null===(e=null==t?void 0:t.split("."))||void 0===e?void 0:e.reduce(((n,t)=>null==n?void 0:n[t]),n)}}function t(t={}){const e=new n(t);return{printTable:async(n,t,r={})=>await e.printTable(n,t,r),previewTable:(n,t,r={})=>{e.previewTable(n,t,r)},exportToHTML:(n,t,r,o={})=>{e.exportToHTML(n,t,r,o)},printUtil:e}}export{n as TablePrintUtil,n as default,t as useTablePrint}; //# sourceMappingURL=index.esm.js.map