Vue中手动导出Element表格为pdf/word/excel格式

在vue中将element的表格进行导出为pdf/word/excel样式,需要进行一些处理,比较麻烦

网页样式
在这里插入图片描述
导出为表格
在这里插入图片描述
导出为word
在这里插入图片描述
导出为PDF
在这里插入图片描述

一、编写工具函数和前置对element样式的修改函数

@param {String} inerHTML 需要导出的html字段
@param {String} typeName 需要导出的文件类型
(注意最外层需要一个单独的容器包裹,使用)

// 导出函数
export function exportFileByInerHTML(inerHTML, typeName) {
  const dateTime = new Date();
      const dateTimeStr =
        dateTime.getFullYear() +
        "-" +
        dateTime.getMonth() +
        "-" +
        dateTime.getDay();
      let blob;
      try {
        //word文档为msword,docx为vnd,pdf文档为pdf,msexcel 为excel
        blob = new Blob([inerHTML], {
          type: "application/file"
        });
      } catch (e) {
        if (typeof console !== "undefined") {
          this.$message.error("导出失败");
          console.log(e);
        }
      }
      let objectUrl = URL.createObjectURL(blob);
      let link = document.createElement("a");
      let fname = `表格_${dateTimeStr}.${typeName}`; //下载文件的名字
      link.href = objectUrl;
      link.setAttribute("download", fname);
      document.body.appendChild(link);
      link.click();
}

1. 因为表格只支持最原生的border,但是element的样式没有设置,并且最右侧底部没有线条的,然后最右侧和底部被element的css样式的before和after覆盖了,我们都要自己去设置和清除
2. element表格其实是两个table组成,第一个table是表头,第二个table是内容,我们要把第一个的tr放到第二个的table里面,导出结束后复原。

打印pdf需要进行的样式修改,通过vuedata中 { isPrintToPdfFlag: false}来控制
<el-tabler>的外层加一个class标识符

<div id="print-table" class="table-container" :class="{'printToPdf': isPrintToPdfFlag}">
	<table class="table-configurable" border="0" cellspacing="0" cellpadding="0">
	......
	</table>
</div>
  .printToPdf {
    /deep/ .el-table {
      &--border {
        &::after {
          background-color: none;
        }
        &--group {
          &::after {
            background-color: none;
          }
        }
        &::after {
          background-color: none;
        }
      }
    }
  }

前置设置:

// todo设置表格样式
    setTableStyle() {
      //table-designer-container是我自己的外层class,换成你自己的!!!!!!!!!!!!!!!
      let tableDomList = document
        .querySelector(".table-designer-container")
        .getElementsByTagName("table");

      // 去除element的覆盖层
      this.isPrintToPdfFlag = true;
      let headRightTh = tableDomList[0]
        .getElementsByTagName("tr")[0]
        .getElementsByTagName("th");
      headRightTh[headRightTh.length - 2].style.borderRight =
        "1px solid #ABABAB";

      // 遍历两个table
      let tableLength = tableDomList.length;
      for (let i = 0; i < tableLength; i++) {
        tableDomList[i].setAttribute("border", "1");
        tableDomList[i].style.border = "#ffffff";
        let childTr = tableDomList[i].getElementsByTagName("tr");
        let childTrLength = childTr.length;
        // 第一个table是头部,没有td会报错
        if (i > 0) {
          for (let j = 0; j < childTrLength; j++) {
            let childTd = childTr[j].getElementsByTagName("td");
            let childTdLength = childTd.length;
            // 修改最后一个的边框值
            if (childTd[childTdLength - 1].style) {
              childTd[childTdLength - 1].style.borderRight =
                "1px solid #ABABAB";
            }

            for (let k = 0; k < childTdLength; k++) {
              childTd[k].style.padding = "8px 0"; //改变之后与element高度一致
              childTd[k].style.valign = "center";
              childTd[k].style.align = "center";
              childTd[k].style.textAlign = "center";

              if (j == childTrLength - 1) {
                childTd[k].style.borderBottom = "1px solid #ABABAB";
              }
            }
          }
        } else {
          // 去除第一个table去除最右侧的空白th
          let childTr = tableDomList[i].getElementsByTagName("tr");
          let childTrLength = childTr.length;
          for (let i = 0; i < childTrLength; i++) {
            let lastTh = childTr[i].querySelector(".gutter");
            if (lastTh) {
              lastTh.parentNode.removeChild(lastTh);
            }
          }
        }
      }
	
	// print-table是我自己的外层id,换成你自己的id
    return document.querySelector("#print-table .el-table").innerHTML;
   }

导出后要清除设置

 // todo清除表格样式
    clearTableStyle() {
     //table-designer-container是我自己的外层class,换成你自己的!!!!!!!!!!!!!!!
     let tableDomList = document
        .querySelector(".table-designer-container")
        .getElementsByTagName("table");

      // 去除第一个table表头最右侧的边框
      let headRightTh = tableDomList[0]
        .getElementsByTagName("tr")[0]
        .getElementsByTagName("th");
      headRightTh[headRightTh.length - 2].style.borderRight = "1px solid #EBEEF5";

      //去除右侧和最底部的样式
      for (let i = 0; i < tableDomList.length; i++) {
        tableDomList[i].setAttribute("border", "0");
        tableDomList[i].style.border = "none";
        let childTr = tableDomList[i].getElementsByTagName("tr");
        let childTrLength = childTr.length;
        // 第一个table是头部,没有td会报错
        if (i > 0) {
          for (let j = 0; j < childTrLength; j++) {
            let childTd = childTr[j].getElementsByTagName("td");
            let childTdLength = childTd.length;
            // 修改最后一个的边框值
            if (childTd[childTdLength - 1].style) {
              childTd[childTdLength - 1].style.borderRight = "none";
            }
            for (let k = 0; k < childTdLength; k++) {
              if (j == childTrLength - 1) {
                childTd[k].style.borderBottom = "1px solid #EBEEF5";
              }
            }
          }
        }
      }
    },

二、导出excel和word

// 设置边框
this.setTableStyle()
// 变换结点,让空格
// #print-table是我自己的外层id
let _table_body = document.querySelector("#print-table .el-table__body-wrapper .el-table__body tbody");
let _docHtml = document.querySelector("#print-table .el-table__header-wrapper .el-table__header");
_docHtml.appendChild(_table_body);
let _header_wrapper = document.querySelector("#print-table  .el-table__header-wrapper");
exportFileByInerHTML(_header_wrapper.innerHTML, "doc"); //导出表格就用‘’xlsx/xls之类的

// 导出完毕要把dom界面复原,然后再去除修改的格式
let _table__body = document.querySelector("#print-table .el-table__body-wrapper .el-table__body")
_table__body.appendChild(_docHtml.querySelector('tbody'));
this.clearTableStyle();

三、导出为pdf,借助iframe生成自己的代码片段,然后借助浏览器自带的打印功能,要手动选择 另存为PDF!!!!!!

<!-- 导出pdf-->
<iframe id="exportPdf" src="localhost:8080/TableDesigner.html" width="0" height="0"></iframe>
this.setTableStyle();
let iframe = document.getElementById("exportPdf");
let doc = iframe.contentWindow.document;
// #print-table是自己的外层id
let tcontent = document.querySelector("#print-table .el-table").innerHTML; //获取table表中数据

//将获取到html标签数据赋值给iframe中组件中id中,组件的样式将影响html标签数据
doc.getElementsByTagName("body")[0].innerHTML = tcontent; 

iframe.contentWindow.print(); //调取iframe打印,数据过多打印会自动分页

//清除样式
this.clearTableStyle();

看完点个赞,谢谢!
在这里插入图片描述

  • 21
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
在使用Okhttp进行文件上传时,需要注意设置请求头的Content-Type为multipart/form-data。这是因为在文件上传时,需要将文件数据以多部分的形式进行传输。\[1\]你可以使用Okhttp3库来实现这个功能。首先,你需要引入Okhttp3的jar包,可以通过在pom.xml文件添加以下依赖来引入Okhttp3库: ```xml <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.0.0</version> </dependency> ``` 接下来,你可以使用Okhttp3的RequestBody类来创建一个请求体,然后将文件数据添加到请求体。在创建RequestBody时,你需要指定Content-Type为multipart/form-data。这样后台才能正确解析请求并接收到数据。\[2\]如果你在设置请求头的Content-Type后仍然无法成功上传文件,可能是因为你没有正确设置RequestBody的Content-Type。你可以尝试在创建RequestBody时设置Content-Type为multipart/form-data,这样可以确保请求体的Content-Type与请求头的Content-Type一致,从而解决上传文件的问题。\[3\] #### 引用[.reference_title] - *1* *3* [通过Okhttp3 post方式上传文件 Content-Type=multipart/form-data](https://blog.csdn.net/qq_15327175/article/details/130533804)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [SpringBoot2.1.x,okhttp3网络请求之MultipartFile方式上传文件,multipart/form-data表单多文件+多参数](https://blog.csdn.net/p812438109/article/details/107943319)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ldz_miantiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值