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

2022-07-22 13:49:16

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

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

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

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

// 导出函数exportfunctionexportFileByInerHTML(inerHTML, typeName){const dateTime=newDate();const dateTimeStr=
        dateTime.getFullYear()+"-"+
        dateTime.getMonth()+"-"+
        dateTime.getDay();let blob;try{//word文档为msword,docx为vnd,pdf文档为pdf,msexcel 为excel
        blob=newBlob([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标识符

<divid="print-table"class="table-container":class="{'printToPdf': isPrintToPdfFlag}"><tableclass="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";// 遍历两个tablelet 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去除最右侧的空白thlet 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,换成你自己的idreturn 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是我自己的外层idlet _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--><iframeid="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是自己的外层idlet 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();
  • 作者:ldz_miantiao
  • 原文链接:https://blog.csdn.net/qq_40282732/article/details/107159852
    更新时间:2022-07-22 13:49:16