el-table打印PDF预览,表头错位的解决方案

背景与需求

本例以vue2项目为例,vue3与react等同理。

有个项目需要打印的功能,网页使用vue2写的,主体内容为表格el-table,添加某个按钮,点击按钮时弹出PDF打印预览,示例如下:

el-table打印PDF预览,表头错位的解决方案

需求分析

通常我们会使用vue-print-nb组件,通过一些配置即可实现需求,但是会出现一些奇怪的bug,比如:

  • 表头错位
  • 首页尾页多出一页
  • 边框线不显示
  • 表格的边框1px不会不显示的问题
  • 某些边框变粗了……

以上问题会在下面解决!

解决方案

方案一:vue-print-nb插件

vue-print-nb是vue项目中用的比较广泛的打印预览插件,其npm地址如下:

vue-print-nb文档(https://www.npmjs.com/package/vue-print-nb)

安装

npm install vue-print-nb --save

引入

在main.js中引入并注册插件:

import Print from 'vue-print-nb'
Vue.use(Print)

使用

在需要的vue组件中使用:

<template>
  <div class="app-container">
    <el-button type="primary" size="medium" v-print="printObj">报表打印</el-button>

    <div id="printArea" ref="gatprintArea">
      打印区域,内容自定义
    </div>
    
  </div>
</template>

<script>
  export default {
    data() {
      return {
        printObj: {
          id: 'printArea', // 这里是要打印元素的ID
          popTitle: ' ', // 打印的标题
        },
      };
    },
  };
</script>

通过上述代码,我们可以实现打印并预览PDF的效果,但是实际应用中会出现之前说的问题。

原图:

el-table打印PDF预览,表头错位的解决方案

预览效果图:

el-table打印PDF预览,表头错位的解决方案

可以看到,没有把完整的表格区域打印出来,而且表格的很多边框线没显示,我们给它添加一些样式,先让它能完整的打印出来:

  ::v-deep table {
    table-layout: auto;
  }
  ::v-deep .el-table__header-wrapper .el-table__header {
    width: 100% !important;
  }
  ::v-deep .el-table__body-wrapper .el-table__body {
    width: 100% !important;
  }
  ::v-deep .el-table .cell.el-tooltip {
    text-overflow: clip;
    white-space: normal;
    min-width: none;
    width: auto !important;
    border: none !important;
  }

添加完样式之后,表格能完整的显示出来了,效果如下:

el-table打印PDF预览,表头错位的解决方案

但是边框线还是不显示,再加一些样式如下:

  @page{
    size:  auto;
    margin-bottom: 0; //去掉页脚
  }

  @media print{
    body {
      margin: 0;
      padding: 0;
    }
    #printArea {
      page-break-inside: avoid;
    }

    ::v-deep .el-table th.gutter {
      display: table-cell !important;
    }

    // 设置表格边框样式
    ::v-deep table {
      //table-layout: auto;
      border: 1px solid #dfe6ec !important;
      border-color: #dfe6ec !important;
      //border-collapse: collapse;
      font-size: 12px !important;
      td {
        border-right: 1px solid  #dfe6ec !important;
        border-bottom: 1px solid  #dfe6ec !important;
      }
      tbody {
        border-left: 1px solid  #dfe6ec !important;
      }
      th {
        border: 1px solid #dfe6ec !important;
        border-bottom: none !important;
        width: auto !important;
      }
      .cell {
        padding: 0 !important;
      }
    }
    ::v-deep thead tr th {
      border-right: 0 !important;
    }
   
    // 清除原来的边框样式
    ::v-deep .el-table--border::after,
    .el-table--group::after,
    .el-table::before {
      background-color: transparent;
    }
    ::v-deep .el-table th {
      border-bottom: 1px solid #dfe6ec;
      background: #F5F7FA !important;
    }
    ::v-deep {
      .el-table--border::after {
        display: none !important;
      }
      .el-table__header {
        border: 0 !important;
        .gutter {
          width: 0 !important;
        }
      }
      thead tr:nth-child(1) th:nth-child(1) {
        border-left: 0 !important;
      }
    }
  }

现在可以看到,边框线经过处理后,基本都能显示出来了,但是还有表头错位的问题没有解决,这是因为预览时,表格自动计算的宽度会存在误差,且目前无法避免(即使没有多级表头),效果如下:

el-table打印PDF预览,表头错位的解决方案

既然这样会存在一点问题,那么我们只能试试第二种方案了。

方案二

html2canvasprint-js结合,其原理是先把需要打印的内容转化为图片,然后打印预览图片,这样就不会出现表头错位的问题了。

安装

npm install --save html2canvas
npm install --save print-js

使用

示例代码如下:

<template>
  <div class="app-container">
    <el-button type="primary" size="medium" @click="onPrint">报表打印</el-button>

    <div id="printArea" ref="gatprintArea">
      打印区域,内容自定义
    </div>
    
  </div>
</template>

<script>

import html2canvas from "html2canvas";
import printJS from "print-js";
export default {
  
  methods: {
    
    // 方案二,这种方法不会错位
    onPrint() {
      const printContent = this.$refs.gatprintArea; //获取上面的ref对应的组件实例
 
      // 获取dom 宽度 高度
      const width = printContent.clientWidth + 2; //如果有边框可适当增加2~10之间的画布大小
      const height = printContent.clientHeight + 2;//如果有边框可适当增加2~10之间的画布大小
      // 创建一个canvas节点
      const canvas = document.createElement('canvas');

      const scale = 1; // 定义任意放大倍数,支持小数;越大,图片清晰度越高,生成图片越慢。
      canvas.width = width * scale; // 定义canvas 宽度 * 缩放
      canvas.height = height * scale; // 定义canvas高度 *缩放
      canvas.style.width = width * scale + 'px';
      canvas.style.height = height * scale + 'px';
      canvas.getContext('2d').scale(scale, scale); // 获取context,设置scale

      const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 获取滚动轴滚动的长度
      const scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; // 获取水平滚动轴的长度
      
      html2canvas(printContent, {
        canvas,
        // backgroundColor: null,
        useCORS: true,
        windowHeight: document.body.scrollHeight,
        scrollX: -scrollLeft, // 解决水平偏移问题,防止打印的内容不全
        scrollY: -scrollTop
      }).then((myCanvas) => {
        const url = myCanvas.toDataURL('image/png')
        printJS({
          printable: url,
          type: 'image',
          documentTitle: '', // 标题
          style: '@page{size:auto;margin: 0.5cm 1cm 0cm 1cm;}' // 去除页眉页脚
        })
      }).catch(err => {
        console.error(err);
      })
    }
  }
};
</script>

可以从下图看到,虽然显示效果没有方案一的好,但是实现了功能,示例图如下:

el-table打印PDF预览,表头错位的解决方案

如果打印的内容超过一页,会在收尾出现空白页,可添加样式如下:

printJS({
 printable: url,
  type: 'image',
  documentTitle: '', // 标题
  style: '@page{size:auto;margin: 0.5cm 1cm 0cm 1cm;}body{margin:0}' // 去除页眉页脚
})

至此,本方案成功解决需求

方案三

看了网友的一个方案,就是把表头隐藏起来:show-header=”false” ,把表头放到表格内容中,再稍微调整一下样式,这样就不会出现错位了,因为表头和内容自动分配宽度,也页面内可以正确对齐,但是打印时又计算了,其他因素影响导致错位的。

el-table打印PDF预览,表头错位的解决方案

总结

方案一显示下过好,但是表头错位问题无法解决,如果不涉及el-table表头,打印预览其他内容时,本方案很推荐。如果方案一无法解决,那么就用方案二,如果表格简单,也可以用方案三。

【版权提示】信息来自于互联网,不代表Intoep官方立场,内容仅供网友参考学习。如发现本站内容存在版权问题,烦请提供版权疑问、联系方式等发邮件至 1359125269@qq.com ,我们将及时沟通与处理。如若转载请联系原出处
(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024-12-23 10:07
下一篇 2024-12-23 12:08

相关推荐

  • CSS终于在2024年增加了垂直居中功能align-content:center

    CSS终于在 2024 年增加了垂直居中功能align-content: center,CSS 对齐一般会使用 flexbox 或 grid 布局,因为 align-content 在默认的流式布局中不起作用。在 2024 年,浏览器实现了 align-content。

    2024-09-02
    02490
  • 解决访问国外公共静态资源速度慢的问题

    由于众所周知的原因,jsdelivr国内被墙,部分地区可能无法正常访问,其他国外的公共静态资源也存在访问速度慢或无法正常访问的问题,为解决该问题,辉哥博客&蓝易云安全开发了国外静态资源js和css资源CDN替换国内的脚本,供所有用户免费使用。

    2022-06-29
    02920
  • Vue插件vue-plugin-hiprint,一款hiprint封装的Vue插件,可以让你快速生成可视化报表

    一款基于 hiprint 的 Vue 插件vue-plugin-hiprint ,是一个生成和打印可视化报表的工具。为了方便在 Vue 项目中使用,vue-plugin-hiprint 把 hiprint 封装成一个 Vue 组件。无论你是需要打印表格、图表、条形码、二维码,还是需要打印发票、订单、标签、证书,vue-plugin-hiprint 都可以帮你实现。

    2024-02-05 Vue
    03620
  • H5网页布局+css代码美化

    HTML5的结构化标签,对搜索引擎更友好 li 标签对不利于搜索引擎的收录,尽量少用 banner图片一般拥有版权,不需要搜索引擎收录,因此可以使用ul + li <samp…

    2021-12-25 Html/CSS
    02380
  • PHP使用http_build_query()构造URL字符串的方法

    1、明确需求 实战工作中经常会请求各种各样的接口,例如 • 微信网页授权接口 • 高德周边检索接口 • 发现:下图是根据接口文档开发后的代码,发现代码可读性差(ps. 参数的作用不…

    2021-12-05 Php
    03350
  • 推荐一款免费的网页打印控件

    做过网页打印的应该都清楚,如果想使用js直接调用本地打印机进行打印任务都需要基于打印控件,因为js不能直接调用打印机,即使是google浏览器也是内置的打印控件。 网页打印控件比较…

    JavaScript 2021-12-16
    03190

发表回复

登录后才能评论
分享本页
返回顶部