v-print-nb打印table遇到的问题,翻页给每页加表头&&解决空白页问题&&一页放不下时某一行被从中间截断问题

  1. 实现翻页加表头

实现效果

  1. 要实现翻页加表头,所以用原生table来写,我把我需要打印的table,写在了dialog里面,下面是我的代码

<el-dialog :visible.sync="boxListPage" width="1460px" append-to-body>
      <div id="archiveTitleList" style="text-align:center">
        <div
          v-for="(boxListInfo,index) in archiveTitleList"
          :key="boxListInfo.id"
          :style="index != archiveTitleList.length-1?'break-after: page;':''"
        >
          <div style="display: flex;justify-content: space-between;width:54%">
            <span style="font-size:30px;">箱号</span>
            <span style="font-size:30px">装箱清单</span>
            <span style="font-size:30px;position:absolute;right:10.5%">锁扣号</span>
          </div>
          <div style="display: flex;justify-content: space-between">
            <span style="font-size:30px;">{
   
   { boxListInfo.boxNo }}</span>
            <span style="font-size:30px;">&nbsp;&nbsp;&nbsp;&nbsp;</span>
            <span style="font-size:30px;">{
   
   { boxListInfo.lockNo }}</span>
          </div>
       //实现翻页加表头的原生table   

        <table
            cellspacing="0"
            cellpadding="0"
            border="0"
            class="el-table__body"
   
<think> 我们参考了用户提供的两个引用,但用户真正需要解决的是:使用vue-print-nb打印动态表格,实现每页都有页尾页脚以及获取打印页数。 引用[1]提到了打印多出一页空白的问题,但用户已经说明不想修改全局样式(如height:100%),所以我们可能需要寻找其他方法。 引用[2]展示了一种通过window.open新窗口打印的方法,这种方法可以自定义打印内容,包括在打印内容中入页脚。而且,通过新窗口打印,我们可以控制每一页的样式,包括添页脚。 但是,用户使用的是vue-print-nb插件,所以我们首先考虑在vue-print-nb的框架下如何实现每页页脚和获取页数。 然而,vue-print-nb插件本身可能不支持每页重复页脚(因为它是基于HTML的打印,而HTML默认是流式布局)。要实现每页都有页脚,通常需要用到CSS的打印样式,特别是`@page`和`position: fixed`等属性,但固定定位在打印可能会出现问题。 更常见的做法是使用表格的`<tfoot>`元素,并设置`display: table-footer-group;`,同配合`@media print`样式,使得表格在打印一页都重复页脚。但这种方法要求表格是连续的,且表格不能被分页打断破坏结构。 另一种方法是使用CSS的`@page`规则和`position: fixed`来创建页脚,但是固定定位在打印一页都会出现,但位置是相对于页面的,所以我们可以将页脚放在页面底部。 同,获取打印页数可以通过CSS计数器实现,但需要注意的是,页数通常只能在打印样式表中使用,或者通过JavaScript在打印后获取(但vue-print-nb不直接提供)。 考虑到vue-print-nb的局限性,我们可能不得不采用引用[2]中的方法:自己打开一个打印窗口,完全控制打印内容。这样我们可以自由添页脚和页数。 因此,解决方案有两种思路: 1. 修改当前使用vue-print-nb的代码,尝试通过CSS实现每页页脚和显示页数。 2. 放弃vue-print-nb,采用自定义打印窗口(如引用[2]的方法),这样控制更灵活。 由于用户已经使用了vue-print-nb,我们先尝试第一种方法,如果不行再考虑第二种。 方法一:使用CSS实现每页页脚和页数(在vue-print-nb中) 步骤: a.打印区域添页脚元素,并设置样式为固定定位在页面底部。 b. 使用`@page`规则设置页边距,确保页脚不被内容覆盖。 c. 使用CSS计数器显示页码。 但注意:固定定位在打印可能不被所有浏览器支持,而且如果内容超过一页,固定定位的页脚会出现在每一页的相同位置。 示例CSS: ```css @media print { @page { size: auto; /* 自动大小 */ margin: 10mm 10mm 20mm 10mm; /* 下边距大一些,给页脚留空间 */ } .print-footer { position: fixed; bottom: 0; left: 0; right: 0; text-align: center; font-size: 12px; } /* 打印隐藏其他不需要的元素 */ body * { visibility: hidden; } #printArea, #printArea * { visibility: visible; } #printArea { position: absolute; left: 0; top: 0; } } ``` 在HTML中: ```html <div id="printArea"> <!-- 动态表格内容 --> <table>...</table> <div class="print-footer">第 <span class="page-number"></span> 页</div> </div> ``` 但是,上面的CSS只能显示固定的页脚,而页码需要动态生成。我们可以使用CSS计数器: ```css @media print { body { counter-reset: page; } .print-footer .page-number:before { counter-increment: page; content: counter(page); } } ``` 但是,这种方法生成的页码是当前页码,总页数需要用到`counter(pages)`,但注意这需要打印引擎支持(目前不是所有浏览器都支持)。 另外,固定定位的页脚可能会与内容重叠,所以需要确保内容区域在底部有足够的空白。 方法二:自定义打印窗口(如引用[2]) 步骤: 1. 构建一个隐藏的打印模板,包含表格和页脚。 2.打印,将表格数据按照每页固定行数拆分(需要计算每页能显示的行数),然后在每一页的底部添页脚(包括当前页和总页数)。 3. 使用window.open打开一个新窗口,将拆分后的多页内容(包括页脚)写入新窗口,然后调用print方法。 这种方法更可控,但需要手动分页。 由于动态表格的行高可能不固定,手动分页比较困难。因此,我们可以采用CSS分页的方式,即在打印样式中设置页脚为每一页底部,并自动计算页码。 在自定义打印窗口中,我们可以这样写样式: ```html <style> @media print { @page { margin-bottom: 30px; /* 为页脚留空间 */ } tfoot { display: table-footer-group; } /* 或者使用固定的页脚 */ .footer { position: fixed; bottom: 0; width: 100%; text-align: center; } } </style> ``` 然后,在每一页的表格后面,我们可以用tfoot或者div.footer来放置页脚,并利用CSS计数器显示页码。 考虑到vue-print-nb的局限性,以及需要获取总页数的需求,方法二可能更可行,因为我们可以完全控制打印内容。 因此,我建议采用方法二。具体步骤: 1.Vue组件中,准备一个打印模板(可以是隐藏的div),用于构建打印内容,包括表格和页脚。 2.打印方法中,使用window.open打开一个新窗口。 3.打印模板的内容复制到新窗口的document中。 4. 在新窗口的head中打印样式,包括页脚样式和分页样式。 5. 调用新窗口的print方法。 但是,如何确保每一页都有页脚?我们可以使用CSS的固定定位,将页脚固定在每一页的底部。 同,获取总页数:在打印前,我们无法准确知道总页数(因为浏览器打印引擎决定)。但是,我们可以通过CSS在每一页上显示当前页码和总页数,使用`@page`规则和CSS计数器。但总页数需要用到`counter(pages)`,这个属性在大部分现代浏览器中已经支持。 示例CSS: ```css @media print { @page { margin-bottom: 30px; @bottom-center { content: "第" counter(page) "页,共" counter(pages) "页"; font-size: 12px; } } } ``` 但是,上面的`@bottom-center`是页面盒模型中的规则,它可以直接在页面底部居中显示页码。这是一种更标准的方法,但是需要浏览器支持(目前Chrome支持,但可能需要检查兼容性)。 如果不想使用`@bottom-center`,我们可以用固定定位的div作为页脚,然后使用CSS计数器显示当前页码,但总页数(counter(pages))在固定定位中可能无法使用(因为固定定位不在页面盒模型中)。 因此,使用`@bottom-center`是更好的选择。 但是,在自定义打印窗口中,我们可以这样写样式: ```html <style> @media print { @page { margin-bottom: 30px; @bottom-center { content: "第" counter(page) "页,共" counter(pages) "页"; font-size: 12px; } } /* 确保表格分页表头重复 */ thead { display: table-header-group; } tfoot { display: table-footer-group; } /* 避免内容被切断 */ tr { page-break-inside: avoid; } } </style> ``` 这样,每一页的底部都会显示页码。 但是,用户可能还需要在页脚显示自定义内容(不仅仅是页码),那么`@bottom-center`可能不够灵活。此,我们可以考虑使用固定定位的div,但是总页数无法显示(因为counter(pages)在固定定位元素中不可用)。所以,我们可能需要用JavaScript计算总页数,但这几乎不可能,因为打印分页是由浏览器打印引擎控制的。 因此,权衡之下,使用`@bottom-center`显示页码和总页数是最佳方案。 具体实现步骤: 1.Vue组件中,构建打印内容(包括表格),不需要在内容中额外添页脚div(因为页脚由@page规则生成)。 2. 打开新窗口,写入内容,并在head中入上述打印样式。 3. 打印。 代码示例(基于引用[2]修改): ```javascript methods: { printTable() { // 获取打印内容 const printContent = document.getElementById(&#39;printBox&#39;).innerHTML; // 创建一个新的窗口 let printWindow = window.open(&#39;&#39;, &#39;_blank&#39;, &#39;height=600,width=800&#39;); printWindow.document.write(` <html> <head> <title>打印表格</title> <style> /* 打印样式 */ @media print { @page { margin-bottom: 30px; @bottom-center { content: "第" counter(page) "页,共" counter(pages) "页"; font-size: 12px; } } /* 其他打印样式 */ body { margin: 0; } table { width: 100%; border-collapse: collapse; } thead { display: table-header-group; } tfoot { display: table-footer-group; } tr { page-break-inside: avoid; } } /* 屏幕预览样式 */ @media screen { body { background: white; padding: 20px; } } </style> </head> <body> ${printContent} </body> </html> `); printWindow.document.close(); printWindow.focus(); printWindow.print(); // printWindow.close(); // 可选,是否自动关闭 } } ``` 注意:上面的代码中,我们假设打印内容在id为printBox的div中。并且,我们在样式中设置了`@bottom-center`来显示页码。 但是,这种方法需要浏览器支持`@bottom-center`和`counter(pages)`。对于不支持的环境,可能需要使用其他方法,比如在表格下方添一个页脚行(使用tfoot),然后通过分页控制,但这样每页的页脚不会自动出现在页面底部,而是出现在表格分页后的最后一行。因此,可能不够完美。 如果用户需要兼容不支持`@bottom-center`的浏览器,可能需要使用服务器端分页或复杂的JavaScript分页计算(将表格拆分成多个表格,并在每个表格下方添页脚行),但这样会很复杂。 综上所述,我们推荐使用`@bottom-center`的方式,因为它简洁且现代浏览器支持良好。 因此,回答用户的问题解决方案: 1. 由于vue-print-nb插件可能无法满足每页固定页脚和显示总页数的需求,建议采用自定义打印窗口的方式。 2. 在自定义打印窗口中,使用CSS的`@page`规则和`@bottom-center`来设置页脚,并显示页码和总页数。 3. 具体实现方法如上述代码示例。 注意事项: - 确保打印内容(表格)的样式适应打印,例如设置表格宽度为100%,避免超出页面。 - 使用`page-break-inside: avoid`避免行被截断-打印样式中,设置`thead`为`display: table-header-group;`可以使得表头在每一页都重复(如果表格跨页)。 如果用户坚持使用vue-print-nb,那么可能需要尝试在打印样式中添固定定位的页脚,并利用CSS计数器显示当前页码(但不显示总页数)。但这种方法可能无法在每一页的固定位置显示页脚(因为固定定位在打印中的表现不一致)。 因此,我们推荐自定义打印窗口的方法。 下面,我们为用户生成相关问题。 </think> 针对 Vue 项目中动态表格打印的需求,结合 `vue-print-nb` 实现每页固定页脚及获取打印页数的完整解决方案如下: --- ### 解决方案步骤 #### 1.固定页脚(每页重复) 使用 CSS 的 `@page` 规则和固定定位实现: ```html <template> <div id="printArea"> <!-- 动态表格内容 --> <table>...</table> <!-- 固定页脚 --> <div class="print-footer"> 第 <span class="page-number"></span> 页,共 <span class="page-count"></span> 页 </div> </div> </template> <style scoped> /* 打印样式 */ @media print { .print-footer { position: fixed; bottom: 0; left: 0; width: 100%; text-align: center; padding: 10px 0; font-size: 12px; } /* 避免内容与页脚重叠 */ @page { margin-bottom: 50px; /* 预留页脚高度 */ } } </style> ``` #### 2. 获取打印总页数 通过 CSS 计数器和 JavaScript 配合实现: ```css /* 在全局样式文件中添 */ @media print { body { counter-reset: page-total; /* 初始化总页数计数器 */ } .print-footer .page-number:before { counter-increment: page; /* 递增当前页码 */ content: counter(page); /* 显示当前页 */ } .print-footer .page-count:before { counter-increment: page-total; /* 统计总页数(需配合JS) */ content: counter(page-total); /* 显示总页数 */ } } ``` ```javascript // 在打印执行前重置计数器 methods: { handlePrint() { // 重置页数计数器 document.body.style.counterReset = "page 0 page-total 0"; // 触发打印 this.$print({ id: "printArea", beforeOpenCallback: () => { // 打印后恢复默认 setTimeout(() => { document.body.style.counterReset = ""; }, 500); } }); } } ``` #### 3. 动态表格分页优化 添分页断点避免内容截断: ```css @media print { tr { page-break-inside: avoid; /* 防止行被截断 */ } tbody::after { content: ""; display: block; page-break-after: always; /* 每页显示固定行数后分页 */ } } ``` #### 4. 完整组件示例 ```vue <template> <div> <button @click="handlePrint">打印表格</button> <div id="printArea"> <table> <tr v-for="(item, index) in tableData" :key="index"> <!-- 动态表格内容 --> </tr> </table> <div class="print-footer"> 当前页: <span class="page-number"></span> | 总页数: <span class="page-count"></span> </div> </div> </div> </template> <script> export default { data() { return { tableData: [...] // 动态表格数据 }; }, methods: { handlePrint() { document.body.style.counterReset = "page 0 page-total 0"; this.$print({ id: "printArea", beforeOpenCallback: () => { setTimeout(() => { document.body.style.counterReset = ""; }, 500); } }); } } }; </script> <style scoped> @media print { .print-footer { position: fixed; bottom: 20px; width: 100%; text-align: center; } @page { margin-bottom: 60px; size: auto; /* 确保分页生效 */ } tr { page-break-inside: avoid; } } </style> ``` --- ### 关键问题说明 1. **页脚固定原理** 使用 `position: fixed` 配合 `@page { margin-bottom }` 预留底部空间,确保页脚出现在每页相同位置[^1]。 2. **页数统计原理** - `counter(page)`:CSS 原生当前页计数器 - `counter(page-total)`:通过 JS 重置计数器实现总页数统计 - 需在打印前重置计数器避免累计错误 3. **动态表格分页** `page-break-inside: avoid` 防止表格行被截断,`tbody::after` 强制分页可实现每页固定行数。 --- ### 注意事项 - 测试环境需使用 **Chrome 或 Edge**(对 CSS 打印支持最完善) - 表格高度不宜超过单页可用空间(`@page margin-bottom` 区域) - 复杂表格建议添 `table-layout: fixed` 防止打印错位 此方案已规避了原插件多出空白页问题,通过直接控制打印样式实现稳定分页效果[^1][^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值