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

news2024/12/18 9:50:55

文章目录

  • 背景与需求
  • 需求分析
  • 解决方案
    • 方案一:vue-print-nb插件
      • 安装
      • 引入
      • 使用
    • 方案二
      • 安装
      • 使用
    • 方案三
  • 总结

背景与需求

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

有个项目需要打印的功能,网页使用vue2写的,主体内容为表格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: '&nbsp', // 打印的标题
        },
      };
    },
  };
</script>

通过上述代码,我们可以实现打印并预览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;
  }

添加完样式之后,表格能完整的显示出来了,效果如下:
在这里插入图片描述
但是边框线还是不显示,再加一些样式如下:

  @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;
      }
    }
  }

现在可以看到,边框线经过处理后,基本都能显示出来了,但是还有表头错位的问题没有解决,这是因为预览时,表格自动计算的宽度会存在误差,且目前无法避免(即使没有多级表头),效果如下:
在这里插入图片描述
既然这样会存在一点问题,那么我们只能试试第二种方案了。

方案二

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>

可以从下图看到,虽然显示效果没有方案一的好,但是实现了功能,示例图如下:
在这里插入图片描述
如果打印的内容超过一页,会在收尾出现空白页,可添加样式如下:

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

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

方案三

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

总结

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

如果有更好的解决方案,欢迎评论!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2261522.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法day16】二叉树:搜索二叉树的修剪与构建

题目引用 修剪二叉搜索树将有序数组转换为二叉搜索树把二叉搜索树转换为累加树 1. 修剪二叉搜索树 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在…

java中File类

1、介绍 File类定义了一些与平台无关的方法来操作文件&#xff0c;可以通过调用File类中的方法&#xff0c;实现创建、删除、重命名文件等操作。File类的对象主要用来获取文件本身的一些信息&#xff0c;如文件所在的目录、文件长度、文件读写权限等。数据流可以将数据写入到文…

金碟中间件-AAS-V10.0安装

金蝶中间件AAS-V10.0 AAS-V10.0安装 1.解压AAS-v10.0安装包 unzip AAS-V10.zip2.更新license.xml cd /root/ApusicAS/aas# 这里要将license复制到该路径 [rootvdb1 aas]# ls bin docs jmods lib modules templates config domains …

易语言OCR证件照文字识别

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…

Haproxy 高可用代理原理配置(Haproxy High Availability Proxy Principle Configuration)

Haproxy 高可用代理原理 简介 Haproxy是一个开源的高可用性负载均衡解决方案&#xff0c;提供基于TCP和HTTP的应用代理服务。它支持高并发连接&#xff0c;能够处理大量的请求&#xff0c;特别适合高负载站点和需要会话保持的应用场景。 主要特点 ‌高可用性‌&#xff1a;…

企业微信可信域名个人配置方法,个人添加企业微信可信IP方法5.0版本,无论是否企业认证都通用。

自动22年11月份开始更新企业微信可信域名配置方法后&#xff0c;先后阿里&#xff08;22年11月&#xff09;1.0可信域名配置方法、腾讯&#xff08;2022年12月14日&#xff09;2.0版本可信域名配置方法、百度&#xff08;2023年1月27日&#xff09;、华为&#xff08;2023年2月…

Endnote | 查看文献所在分组

软件版本&#xff1a;Endnote X8 第一种方式&#xff1a; 在文献上右键——记录摘要&#xff0c;即可在弹出页面上看到自定义和智能组的分组情况。 第二种方式&#xff1a; 在菜单栏点击文献——记录摘要&#xff0c;也可以查看分组情况。 注&#xff1a; 新版本的endnote软件…

力扣-图论-15【算法学习day.65】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非…

练习题:一维数组

练习题 第一题 键盘录入一组数列&#xff0c;利用冒泡排序将数据由大到小排序 代码 #include <stdio.h>int arr_home01() {int arr[10];int i,j,temp;printf("请输入10个测试整数&#xff1a;\n");int len sizeof(arr) / sizeof(arr[0]);for(i 0;i < …

Kerberos身份验证

Kerberos是更现代化的身份验证协议&#xff0c;它比 NTLM 认证更安全&#xff0c;但域内某些服务仍支持 NTLM 认证。Kerberos 和 NTLM 认证一样&#xff0c;都是通过在 SSPI 接口实现的功能&#xff0c;这使得使用第三方协议&#xff08;如&#xff1a;HTTP、SMB、LDAP&#xf…

Kotlin复习

一、Kotlin类型 1.整数 2.浮点 显示转换&#xff1a; 所有数字类型都支持转换为其他类型&#xff0c;但是转换前会检测长度。 toByte(): Byte toShort(): Short toInt(): Int toLong(): Long toFloat(): Float toDouble(): Double 不同进制的数字表示方法&#xff08;为了提高…

12月17日作业

#include <myhead.h>int main(int argc, const char *argv[]) {int pipefd[2];char buff[1024] "hello world";char s[1024];if(pipe(pipefd)-1){perror("pipe");return -1;}//读端pipefd[0] 写端pipefd[1]pid_t pid fork();//创建子进程if(pid0){…

Shopee算法分析 - 算法分析二(与URL有关的Key)

http://blog.androidcrack.com/index.php/archives/39/ 在Unidbg文章中, 我们尝试过多次主动调用, 文中可以发现, 只有253b8c85 这个的key是不变的. Unidbg运行一遍,搜索运行下这个Key, 我们在下面的堆栈中, 可以看到memcpy的调用地址为0x0498ec Unidbg trace整个流程, 在010ed…

ChatGPT重大更新:新增实时搜索和高级语音

12月17日消息&#xff0c;据报道&#xff0c;OpenAI开启了第八天技术分享直播&#xff0c;对ChatGPT搜索功能进行了大量更新。 此次ChatGPT新增的功能亮点纷呈。其中&#xff0c;实时搜索功能尤为引人注目。OpenAI对搜索算法进行了深度优化&#xff0c;使得用户提出问题后&…

Day9 神经网络的偏导数基础

多变量函数与神经网络 在神经网络中&#xff0c;我们经常遇到多变量函数。这些函数通常描述了网络的输入、权重、偏置与输出之间的关系。例如&#xff0c;一个简单的神经元输出可以表示为&#xff1a; z f ( w 1 x 1 w 2 x 2 … w n x n b ) z f(w_1x_1 w_2x_2 \ldots…

windows和LINUX下校验文件的哈希值(MD5、SHA256)

可以通过两个文件的哈希值来对比两个文件是不是一模一样&#xff0c;有没有缺失 1、windows CertUtil -hashfile 文件路径 MD5 CertUtil -hashfile 文件路径 SHA256 2、Liunx 校验当前目录下所有文件 sha256sum . 校验指定文件名 sha256sum 文件名

使用beego操作数据库的简单web项目

1、beego介绍 Beego 是一个开源的、高性能的Go语言框架&#xff0c;用于快速开发RESTful API、Web应用、后端服务等各种类型的软件。它由国人Asta Xie创建&#xff0c;并得到了广泛的社区支持。Beego的设计理念是让开发者能够以最少的时间和代码量来完成Web应用的开发。 以下是…

IS-IS协议

IS-IS协议介绍 IS-IS&#xff08;Intermediate System to Intermediate System&#xff09;协议是一种链路状态的内部网关协议&#xff08;IGP&#xff09;&#xff0c;用于在同一个自治系统&#xff08;Autonomous System, AS&#xff09;内部的路由器之间交换路由信息。IS-I…

不良人系列-复兴数据结构(栈和队列)

个人主页&#xff1a;爱编程的小新☆ 不良人经典语录&#xff1a;“相呴相济 玉汝于成 勿念 心安” 目录 一. 栈(stack) 1. 栈的概念 2. 栈的常见方法 3.栈的模拟实现 ​编辑 二. 队列 1. 队列的概念 2. 队列的使用 2.1 队列的常见方法 2.2 队列的模拟实现 2.3 队列…

机器学习04-为什么Relu函数

机器学习0-为什么Relu函数 文章目录 机器学习0-为什么Relu函数 [toc]1-手搓神经网络步骤总结2-为什么要用Relu函数3-进行L1正则化修改后的代码解释 4-进行L2正则化解释注意事项 5-Relu激活函数多有夸张1-细数Relu函数的5宗罪2-Relu函数5宗罪详述 6-那为什么要用这个Relu函数7-文…