纯前端导出word、pdf、excel、csv、tsv、txt、svg文档方法与技巧(附带问题总结)

导出pdf

实现思路:

将html页面生成pdf文件,需首先将页面转换为图片,然后再输出成pdf。

  1. 用到2个插件
    html2canvas:html转canvas---- html2canvas官网------下载地址
    jsPDF:下载地址 canvas生成pdf(使用Javascript语言生成PDF的开源库)
    jspdf用法:将一个图片列表导出为pdf文件,根据图片宽高计算在pdf中的位置。
  2. npm安装插件
    npm install html2canvas
    npm install jspdf

问题总结:

问题1:导出的pdf很模糊。

    解决方法:设置画布(canvas)的dpi为300,scale为2,上个伪代码:
html2canvas(ele, {
    useCORS: true,//允许canvas画布内可以跨域请求外部链接图片, 允许跨域请求。
    dpi: 300, // 提升导出的文件的分辨率
    scale: 2 // 提升导出的文件的分辨率
}).then(async canvas => {})

问题2:需要导出的dom节点的高度和宽度是大于当前浏览器的可视窗口时,导出后发现导出的内容只包含了可视窗口的内容。

     	解决方法:检查你在设置画布(canvas)的宽高时是否是通过获取dom元素的scrollHeight(dom元素的高度,
     包含纵向滚动条的高度),scrollWidth(dom元素的宽度,包含横向滚动条的款度)。
     
     	还有可能是你所打印的dom节点没有全部展示,要给dom一个高度,让其全部展示,不能使用overflow:auto,
     不能将滚动条隐藏,否则都会出现打印不全或者dom丢失问题

问题3: 导出的pdf,某个模块被截断了,eg:一个table被分到了两个页面。

解决方法:参考方法二(往下看)

问题4: 导出的pdf部分元素缺失,这个问题只会在pdf的内容过大时出现,我是在导出的pdf在5M左右时出现的,当你确定你的缺失的元素是在你要导出的dom内时,若导出的pdf还是有部分内容缺失那你大概率是和我碰到一样的问题了。

    		解决方法:由原来的一次截图,换为分多次截图,将原来dom里面的元素进行克隆放进多个div中,由原来的对dom进行截图
    	换为循环对多个div进行截图即可。(如果看不懂这个处理方式,请先了解html2canvas+jsPDF是如何将html转为pdf的)
    		在你循环进行截图时有可能出现最后pdf里面的内容顺序是错乱的,出现这个问题是因为第一个div转为的图片添加到pdf中
    	还未添加完,第二个div就已经截图完也开始向pdf添加图片了。此时需要在第二个div截图完向pdf添加图片的方法设置等待时间:
    	上个伪代码

let imgBase64 = canvas.toDataURL('image/jpeg', 1.0)

setInterval(()=>{

pdf.addImage(imgBase64, 'JPEG', 0, 0, imgWidth, imgHeight);

}, 3000);

问题:5: 导出区域用input的时候会出现内容错乱问题

最后我Input换成div,点击保存的时候,把input隐藏掉,div显示,
或者用ui组件库中的input如,a-input el-input 等input框,不要用原生的input输入框(<a-input type="text" style="width: 100%; text-align: center" v-model:value="titleName" />

html2canvas官网html2canvas官网
下图为html2canvas的第二个参数options
参考链接:https://html2canvas.hertzen.com/configuration
在这里插入图片描述

jsPDF官网:jsPDF官网

具体代码

  const exportPdf = () => {
    console.log("导出pdf");
   //需要打印容器最外层的id为 testPdf
   //调用downloadPDF()
    downloadPDF(document.querySelector('#testPdf'), '666',callback)
 
    function callback() {
      console.log('导出成功!');
    }
  }

封装好的导出函数,记得引入js插件

无分页:推荐方法一
有分页:推荐方法二

封装方法一:

import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';

/**
 * ele:需要导出的容器
 * pdfName:导出文件的名字
 * callback: 成功回调
 */
function downloadPDF(ele: any, pdfName: any, callback: any) {
    html2canvas(ele, {
      dpi: 300,
      scale: 3,
      // allowTaint: true,  //允许 canvas 污染, allowTaint参数要去掉,否则是无法通过toDataURL导出canvas数据的
      useCORS: true,  //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
	  width:ele.scrollWidth,
      height:ele.scrollHeight,
    }).then((canvas) => {
      //未生成pdf的html页面高度
      var leftHeight = canvas.height;
      var a4Width = 595.28
      var a4Height = 801.89 //(一张A4高=841.89减去20,使得上下边距空出20,pdf.addImage生成上边距(第四个参数=10)致使使得上下边距各10)
      //一页pdf显示html页面生成的canvas高度;
      var a4HeightRef = Math.floor(canvas.width / a4Width * a4Height);
      //pdf页面偏移
      var position = 0;
      var pageData = canvas.toDataURL('image/jpeg', 1.0);
      var pdf = new JsPDF('x', 'pt', 'a4');
      var index = 1,
        canvas1 = document.createElement('canvas'),
        height;
      pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen');

      function createImpl(canvas) {
        if (leftHeight > 0) {
          index++;
          var checkCount = 0;
          if (leftHeight > a4HeightRef) {
            var i = position + a4HeightRef;
            for (i = position + a4HeightRef; i >= position; i--) {
              var isWrite = true
              for (var j = 0; j < canvas.width; j++) {
                var c = canvas.getContext('2d').getImageData(j, i, 1, 1).data
                if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {
                  isWrite = false
                  break
                }
              }
              if (isWrite) {
                checkCount++
                if (checkCount >= 10) {
                  break
                }
              } else {
                checkCount = 0
              }
            }
            height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef);
            if (height <= 0) {
              height = a4HeightRef;
            }
          } else {
            height = leftHeight;
          }
          canvas1.width = canvas.width;
          canvas1.height = height;
          var ctx = canvas1.getContext('2d');
          ctx.drawImage(canvas, 0, position, canvas.width, height, 0, 0, canvas.width, height);
          if (position != 0) {
            pdf.addPage();
          }
          // 在pdf.addImage(pageData, 'JPEG', 左间距,上间距,宽度,高度)设置在pdf中显示;
          pdf.addImage(canvas1.toDataURL('image/jpeg', 1.0), 'JPEG', 20, 10, a4Width, a4Width / canvas1.width * height);
          leftHeight -= height;
          position += height;
          if (leftHeight > 0) {
            setTimeout(createImpl, 500, canvas);
          } else {
            pdf.save(pdfName);
            callback()
          }
        }
      }

      // 当内容未超过pdf一页显示的范围,无需分页
      if (leftHeight < a4HeightRef) {
      
        pdf.addImage(pageData, 'JPEG', 20, 10, a4Width, a4Width / canvas.width * leftHeight);
        pdf.save(pdfName)
        callback()
      } else {
        try {
          pdf.deletePage(0);
          setTimeout(createImpl, 500, canvas);
        } catch (err) {
          console.log(err);
        }
      }
    })
  }
封装方法二:

原理,在需要分页的地方添加空白高度

import jsPDF from "jspdf";
import html2canvas from "html2canvas";

/**
 * ele:需要导出的容器
 * pdfName:导出文件的名字
* splitClassName: 避免分段截断的类名 当pdf有多页时需要传入此参数 , 避免pdf分页时截断元素 (需要在哪儿分页,就在哪儿加类名) 如表格<tr class="nullClass"></tr>
 * callback: 成功回调
 */
export function downloadPDF(ele: any, pdfName: any, splitClassName: string, callback: any) {
  //(一张A4高=841.89减去20,使得上下边距空出20,pdf.addImage生成上边距(第四个参数=10)致使使得上下边距各10)
  //一页pdf显示html页面生成的canvas高度;
  let a4Width = 595.28;
  let a4Height = 801.89;

  ele.style.height = 'initial';
  let target = ele;
  let pageHeight = target.scrollWidth / a4Width * a4Height;
  // 获取分割dom,此处为class类名为item的dom
  let domList = document.getElementsByClassName(splitClassName);
  // 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空dom,把他挤下去,分割
  let pageNum = 1; //pdf页数
  let eleBounding = ele.getBoundingClientRect();
  for (let i = 0; i < domList.length; i++) {
    let node = domList[i];
    let bound = node.getBoundingClientRect();
    let offset2Ele = bound.top - eleBounding.top
    let currentPage = Math.ceil((bound.bottom - eleBounding.top) / pageHeight); //当前元素应该在哪一页
    if (pageNum < currentPage) {
      pageNum++
      let divParent = domList[i].parentNode; // 获取该div的父节点
      let newNode = document.createElement('div');
      newNode.className = 'emptyDiv';
      newNode.style.background = 'white';
      newNode.style.height = (pageHeight * (pageNum - 1) - offset2Ele + 30) + 'px'; //+30为了在换下一页时有顶部的边距
      newNode.style.width = '100%';
      let next = domList[i].nextSibling; // 获取div的下一个兄弟节点
      // 判断兄弟节点是否存在
      if (next) {
        // 存在则将新节点插入到div的下一个兄弟节点之前,即div之后
        divParent.insertBefore(newNode, node);
      } else {
        // 不存在则直接添加到最后,appendChild默认添加到divParent的最后
        divParent.appendChild(newNode);
      }
    }
  }

  html2canvas(ele, {
    dpi: 300,
    scale: 2,
    // allowTaint: true,  //允许 canvas 污染, allowTaint参数要去掉,否则是无法通过toDataURL导出canvas数据的
    useCORS: true,  //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
    width: ele.scrollWidth,
    height: ele.scrollHeight,
  }).then((canvas) => {
    //未生成pdf的html页面高度
    var leftHeight = canvas.height;
    var a4HeightRef = Math.floor(canvas.width / a4Width * a4Height);
    //pdf页面偏移
    var position = 0;
    var pageData = canvas.toDataURL('image/jpeg', 1.0);
    var pdf = new JsPDF('x', 'pt', 'a4');
    var index = 1,
      canvas1 = document.createElement('canvas'),
      height;
    pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen');

    function createImpl(canvas) {
      if (leftHeight > 0) {
        index++;
        var checkCount = 0;
        if (leftHeight > a4HeightRef) {
          var i = position + a4HeightRef;
          for (i = position + a4HeightRef; i >= position; i--) {
            var isWrite = true
            for (var j = 0; j < canvas.width; j++) {
              var c = canvas.getContext('2d').getImageData(j, i, 1, 1).data
              if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {
                isWrite = false
                break
              }
            }
            if (isWrite) {
              checkCount++
              if (checkCount >= 10) {
                break
              }
            } else {
              checkCount = 0
            }
          }
          height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef);
          if (height <= 0) {
            height = a4HeightRef;
          }
        } else {
          height = leftHeight;
        }
        canvas1.width = canvas.width;
        canvas1.height = height;
        var ctx = canvas1.getContext('2d');
        ctx.drawImage(canvas, 0, position, canvas.width, height, 0, 0, canvas.width, height);
        if (position != 0) {
          pdf.addPage();
        }
        // 在pdf.addImage(pageData, 'JPEG', 左间距,上间距,宽度,高度)设置在pdf中显示;
        pdf.addImage(canvas1.toDataURL('image/jpeg', 1.0), 'JPEG', 70, 56, a4Width - 140, a4Width / canvas1.width * height - 112);

        leftHeight -= height;
        position += height;
        if (leftHeight > 0) {
          setTimeout(createImpl, 500, canvas);
          callback()
        } else {
          pdf.save(pdfName);
          callback()
        }
      }
    }

    // 当内容未超过pdf一页显示的范围,无需分页
    if (leftHeight < a4HeightRef) {

      pdf.addImage(pageData, 'JPEG', 20, 10, a4Width, a4Width / canvas.width * leftHeight);
      pdf.save(pdfName)
      // callback();

    } else {
      try {
        pdf.deletePage(0);
        setTimeout(createImpl, 500, canvas);
      } catch (err) {
        console.log(err);
      }
    }
  })
}


封装方法三:
function downloadPDF2(ele: any, pdfName: any) {
    let eleW = ele.scrollWidth; // 获得该容器的宽
    let eleH = ele.scrollHeight; // 获得该容器的高
    let eleOffsetTop = ele.offsetTop;  // 获得该容器到文档顶部的距离
    let eleOffsetLeft = ele.offsetLeft; // 获得该容器到文档最左的距离
    console.log(eleW,eleH,eleOffsetTop,eleOffsetLeft,'eleOffsetLeft');
    
    var canvas = document.createElement("canvas");
    var abs = 0;
    let win_in = document.documentElement.clientWidth || document.body.clientWidth; // 获得当前可视窗口的宽度(不包含滚动条)
    let win_out = window.innerWidth; // 获得当前窗口的宽度(包含滚动条)
    console.log(win_out,'win_out');
    
    if (win_out > win_in) {
      abs = (win_out - win_in) / 2; // 获得滚动条宽度的一半
    }
    canvas.width = eleW * 2; // 将画布宽高放大两倍
    canvas.height = eleH * 2;
    console.log(canvas,'canvas');
    
    var context = canvas.getContext("2d");
    context.scale(2, 2);
    context.translate(-eleOffsetLeft - abs, -eleOffsetTop);
    
    // 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此
    // translate的时候,要把这个差值去掉
    // html2canvas(element).then( (canvas)=>{ //报错
    // html2canvas(element[0]).then( (canvas)=>{
    html2canvas(ele, {
      dpi: 300,
      // 这里是画布放大的倍数,导出的文档更加清晰
      scale: 1,
      // allowTaint: true, //允许 canvas 污染, allowTaint参数要去掉,否则是无法通过toDataURL导出canvas数据的
      useCORS: true,  //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
      width:ele.scrollWidth,
      height:ele.scrollHeight,
    }).then((canvas) => {
      var contentWidth = canvas.width;
      var contentHeight = canvas.height;
      console.log(contentWidth,contentHeight,'contentHeight');
      
      // 一页pdf显示html页面生成的canvas高度;
      var pageHeight = contentWidth / 592.28 * 841.89;
      // 未生成pdf的html页面高度
      var leftHeight = contentHeight;
      // 页面偏移
      var position = 0;
      // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
      var imgWidth = 595.28;
      var imgHeight = 595.28 / contentWidth * contentHeight;
      var pageData = canvas.toDataURL('image/jpeg', 1.0);
      var pdf = new JsPDF('', 'pt', 'a4');
      // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
      // 当内容未超过pdf一页显示的范围,无需分页
      if (leftHeight < pageHeight) {
        // 在pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置在pdf中显示;
        pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
        // pdf.addImage(pageData, 'JPEG', 20, 40, imgWidth, imgHeight);
      } else { // 分页
        while (leftHeight > 0) {
          pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
          leftHeight -= pageHeight;
          position -= 841.89;
          // 避免添加空白页
          if (leftHeight > 0) {
            pdf.addPage();
          }
        }
      }
      //可动态生成
      pdf.save(pdfName);
    })
  }

纯前端导出word文档方法与技巧

首先介绍一下两个插件,可能用一个,可能用两个,根据需求自行选择
FileSaver.js :下载地址
wordexport.js :下载地址

思路:

**先讲一下大体思路:就是讲需要的导出的页面文本dom节点,用模板字符串拼成一个变量(方便后续的书写),然后用插件中方法导出,就两行代码

用途:

**FileSaver.js用于保存文件,可以保存word、excel、txt、image等文件,有兴趣的可以去官网上多看看

问题总结:

**首先说一下想要导出word,是没有 块 概念的,你所导出的文本,涉及到布局的样式都会失效(如:margin,padding,float,diaplay,position),想要解决可以巧用table去解决排版问题(仅能解决小部分),视情况而定

方法一:

方法一仅用 FileSaver 一个js

外部直接引入js:代码如下

let contentHtml = `
		
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .fu-title {
            width: 100%;
            height: 5.31vw;
            line-height: 5.31vw;
            text-align: center;
            font-family: '宋体';
            font-size: 36px;
            color: #fc3f3f;
        }
    </style>
</head>

<body>
    <div class="fu logHistoryManage_detail">
        <div class="fu-title">日志报表信息</div>
        <form class="fu-form">
            <table border="0" cellspacing="0">
                <tr height="30" border='solid 1px red' style='color:#888'>
                    <td width="610" align="left">${sendDepartName ? sendDepartName : "ohqwzfw"}</td>
                    <td width="610" align="center" ></td>
                    <td width="610" align="right">${sendUserName}   </td>
                </tr>
            </table>
            <hr style='color:red;'/><br>
            
            <div class="form-title" style="height: auto;">${title}</div>
            <div class="form-summary" style="word-wrap: break-word;">
            ${content ? content : ''
            }
            </div>
            <br>
            <!-- 领导批示 -->
            <div>
                
                <h2>领导批示</h2>
                <table border="1" cellspacing="0">
                    <tr height="50">
                        <td width="200" align="center">姓名</td>
                        <td width="600" align="center">批示内容</td>
                        <td width="200" align="center">批示时间</td>
                    </tr>
                    ${leaderIdeaList.length>0?leaderIdeaList.map((item, index) => {
                return `
                        <tr height="100">
                            <td width="200" align="center">${item.optUserName}</td>
                            <td width="600" align="center">${item.remark ? item.remark : '暂无内容'}</td>
                            <td width="200" align="center">${item.createTime ? item.createTime : ''}</td>
                        </tr>            
                         `
            }):`<tr height="100">
            <td width="200" align="center"></td>
            <td width="600" align="center"></td>
            <td width="200" align="center"></td>
        </tr> `
            }
                   
                </table>      
            </div>

        </form>
    </div>
</body>
	
</html>

		`

		//重要的代码就这两行----这里是项目中没有npm包管理外部直接引用的js
        let blob = new Blob([contentHtml], { type: "application/msword;charset=utf-8" });
        saveAs(blob, "日志报表信息.docx");

使用包管理安装 FileSaver

首先需要安装:fileSaver

import FileSaver from 'file-saver';
import htmlDocx from "html-docx-js/dist/html-docx"
import { G } from '@/global';
const { rootUrl, rbacToken } = G;
let cycle_info1 = [
  {
    name: '事件类型',
    key: 'eventTypeName',
  },
  {
    name: '地点定位',
    key: 'locationAddress',
  },
  {
    name: '上报时间',
    key: 'reportTime',
  },
  {
    name: '人员姓名',
    key: 'reportUserName',
  },
  {
    name: '联系方式',
    key: 'reportUserPhone',
  },
]

const model = (reportInfoDetail: any, list: any, eventState: any) => {
  // console.log(reportInfoDetail, list, eventState);

  return (
    `
    <!DOCTYPE html>
      <html>

<head>
  <style>
    .MaxBox {
      padding: 0px 15px;
      overflow-y: auto;
      height: 50vh;
    }

    .fromBox {}

    .formTitle_first {
      color: #1c69f7;
      font-size: 23px;
      font-weight: bold;
      margin-bottom: 10px;
    }

    .formTitle_second {
      font-weight: bold;
      font-size: 16px;
      margin-bottom: 10px;
    }

    .formContent_box {
      margin-bottom: 5px;
    }

    .formContent_box_title {
      min-width: 60px;
    }

    .display_flex {
      display: flex;
    }
  </style>
</head>

<body>
  <div class="MaxBox">
    <div class="fromBox">
      <div class="formTitle_first">上报信息</div>
      <div class="formTitle_second">上报信息</div>
      <div class="formContent_box display_flex" style="display:flex">
        <span class="formContent_box_title" >事件类型:</span>
        <span>${reportInfoDetail['eventTypeName']}</span>
      </div>
      <div class="formContent_box display_flex" style="display:flex">
        <span class="formContent_box_title">地点定位:</span>
        <span>${reportInfoDetail['locationAddress']}</span>
      </div>
      <div class="formContent_box display_flex" style="display:flex">
        <span class="formContent_box_title">上报时间:</span>
        <span>${reportInfoDetail['reportTime']}</span>
      </div>
      <div class="formContent_box display_flex" style="display:flex">
        <span class="formContent_box_title">人员姓名:</span>
        <span>${reportInfoDetail['reportUserName']}</span>
      </div>
      <div class="formContent_box display_flex" style="display:flex">
        <span class="formContent_box_title">联系方式:</span>
        <span>${reportInfoDetail['reportUserPhone']}</span>
      </div>
    
      <div class="formTitle_second">图片附件</div>
      <div class="formContent_box">
        ${reportInfoDetail['picIds']?.map((res1: any, idx1: any) => {
      return `
        <img width='240' height='160' src="${rootUrl}/fyVolunteer/file/download/${res1}?rbacToken=${rbacToken}"
          style='margin-right:5px'
        />
        ${((idx1 + 1) % 2 == 0) ? `<br />` : ''}
        `
    })
    }
      </div>
      <div class="formTitle_second">事件描述</div>
      <div class="formContent_box">${reportInfoDetail['description']}</div>
    </div>
    ${reportInfoDetail.assignInfo.length != 0 ?
      `
      <div class="fromBox">
      <div class="formTitle_first">指派信息</div>
      <div class="formTitle_second  display_flex">指派信息</div>
      <div class="formContent_box">
        <div class="formContent_box_title">指派单位:
          ${reportInfoDetail.assignInfo.map((res: any, idx: any) => {
        return `
              <span style="margin-right:15px">
                ${res.departmentName}
              </span>
              `
      })
      }
        </div >
      </div >
      <div class="formContent_box  display_flex">
          <span class="formContent_box_title">指派时间:</span>
          <span>${!!reportInfoDetail?.assignInfo[0]?.assignTime ? reportInfoDetail?.assignInfo[0]?.assignTime : ""}</span>
      </div>
    </div>
      `: ''

    }  

    <div class="fromBox">
      <div class="formTitle_first">处置信息</div>
      ${reportInfoDetail.handleInfo.length != 0 ?
      reportInfoDetail.handleInfo.map((itm: any, idx: any) => {
        return `
        <div class="formTitle_second">单位${idx + 1}${itm['claimDepartmentName']}</div>
        <div class="formTitle_second">签收信息</div>
        <div class="formContent_box display_flex"
        style="width:32vw;justify-content: space-between;">
          <div>
            <span>签收单位:${itm['claimDepartmentName']}</span>
          </div>
          <div>
            <span>签收时间:${itm['claimTime']}</span>
          </div>
        </div >
        <div class="formTitle_second">图片附件</div>
        <div class="formContent_box">
          ${itm['handleTime'] != null ?
            itm['handlePicIds']?.map((res1: any, idx1: any) => {
              return `
          <img width="240" height="160"
            src="${rootUrl}/fyVolunteer/file/download/${res1}?rbacToken=${rbacToken}"
            style="margin-right:5px"
          />
          ${(idx1 + 1) % 2 == 0 ? `<br />` : ''}
          `
            }) : `<span style="color:#5558e8">无</span>`
          }
        </div>

        <div class="formTitle_second">处置描述</div>
        <div class="formContent_box">${itm.handleTime != null ? itm['handleDescription'] : `<span style="color:#5558e8">未上传处置</span>`}</div>

        <div class="formTitle_second">上报信息</div>
        <div class="formContent_box display_flex"
        style="width:32vw;justify-content: space-between;">
          <div>
            <span>上报单位:${itm['claimDepartmentName']}</span>
          </div>
          <div>
            <span>上报时间:${itm['handleTime'] != null ? itm['handleTime'] : ''}</span>
          </div>
        </div>
        <br/>
        `
      }) : '无数据'
    }
    </div >

    <div class="fromBox">
      <div class="formTitle_first">其他信息</div>

      <div class="formContent_box  display_flex">
        <span class="formContent_box_title">信息状态:</span>
        <span>
          ${list[eventState - 1].desc}
          ${reportInfoDetail?.finishTime != null ? reportInfoDetail?.finishTime : ''}
        </span>
    </div>
    <div class="formContent_box  display_flex">
      <span class="formContent_box_title">采纳状态:</span>
      <span>${reportInfoDetail.acceptInfo == null ? "未采纳" : `已采纳(${reportInfoDetail.acceptInfo.integral})`}</span>
    </div>
  </div>
  </div >
</body >
</html >
  `
  )
}

const loadFile = (info: any) => {
  let html = model(info.reportInfoDetail, info.list, info.eventState)
  let blob = new Blob([html], { type: "application/msword;charset=utf-8" });
  // let blob = htmlDocx.asBlob(html, { orientation: "landscape" });
  FileSaver.saveAs(blob, "信息管理文件.doc");
}


export {
  loadFile
};


方法二:

两个js都需要引入,还需要引入jquery.js,最好1.8版本以上的
在这里插入图片描述
原理和那个差不多,只是理解起来比较简单,代码如下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 注意引入的顺序 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
    <script src='./jquery.wordexport.js'></script>
    <style>
        .word-export,.test {
            display: block;
            padding: 10px;
            width: 80px;
            background-color: rgb(56, 131, 230);
        }
    </style>

<body>
    <span class="word-export">导出word</span>
    <div id="page-content2" style="display:flex;justify-content:space-between;">
        <div id="page-content">
            jquery 测试
        </div>
        <div id="page-content1">
            jquery 测试
        </div>
    </div>

    <script type="text/javascript">

        $(".word-export").click(function (event) {
            // 打印节点就可以
            $("#page-content2").wordExport("测试");
        });

    </script>

</body>

</html>

导出svg

	 let type = 'svg'
	 // html中需要导出的部分的id为sankey
      const element = document.getElementById('sankey');
      const chartInstance = echarts.getInstanceByDom(element);
      if (element) {
        // echarts官网文档实例方法getDataURL
        let picInfo = chartInstance.getDataURL({
          type: 'png',
          pixelRatio: 1.0,  // 放大两倍下载。解决生成图片在移动端模糊问题
          backgroundColor: '#fff',
          excludeComponents: ['toolbox']	// 导出时忽略toolbox组件
        });// 获取到的是一串base64信息


        let mycanvas = document.querySelector('#' + element.id + ' canvas');

        //设置svg标签属性
        let svg0 = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
        svg0.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
        svg0.setAttribute('version', '1.1');
        svg0.setAttribute('height', '800');
        svg0.setAttribute('width', '1700');
        let img3 = document.createElementNS('http://www.w3.org/2000/svg', 'image');
        // base64编码写入href
        img3.href.baseVal = picInfo;
        img3.setAttribute('height', '800');
        svg0.appendChild(img3);
        let h = svg0.outerHTML;
        //给图片对象写入base64编码的svg流
        let data = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(h)));

        const elink = document.createElement('a');
        // 设置默认文件名,this.chartTitle为绘图时生成的标题
        elink.download = '桑基图' + ".svg";
        elink.style.display = 'none';
        elink.href = data;
        document.body.appendChild(elink);
        elink.click();
        URL.revokeObjectURL(elink.href); // 释放URL 对象
        document.body.removeChild(elink);

纯前端导出excel文档方法

import xlsx from 'node-xlsx';
import { saveAs } from 'file-saver';
/**
 * 下载xlsx文件
 * @param data 表格数据 [{},{}]
 * @param name 文件名
 */

export const downloadXlsx = (data: any, fileName: string) => {
  let headerArr: string[] = [];
  let data2 = data.map((item: any, index: number) => {
    let arr2 = [];
    for (let key in item) {
      if (index == 0) headerArr.push(key);
      arr2.push(item[key]);
    }
    return arr2;
  });
  data2.unshift(headerArr);
  //如果你已经将需要下载数据处理成二维数据的话,上面的操作可以不要,上面我是为了把table中的data处理成二维数组
  let result = xlsx.build([{ name: 'sheet1', data: data2 }]);
  const ab = Buffer.from(result, 'binary');
  const blob = new Blob([ab]);
  //可以 file-saver 直接下载,也可以用下面注释掉的创建a链接去下载
  saveAs(blob, fileName);

  // const blobUrl = URL.createObjectURL(blob);
  // const a = document.createElement('a');
  // a.href = blobUrl;
  // a.download = fileName;
  // a.click();
  // window.URL.revokeObjectURL(blobUrl);
};


纯前端导出csv、tsv、txt、fastq等文本文档方法

table导出文本

import Papa from 'papaparse';
import { saveAs } from 'file-saver';
/**
 * 下载csv文件
 * @param origin 列表数据对象 [{},{}]
 * @param fileName 文件名
 */

export const downloadCSV = (origin: any, fileName: string) => {
  const result = Papa.unparse(origin);
  const blob = new Blob(['\uFEFF' + result], { type: 'text/plain;charset=utf-8' });
  saveAs(blob, fileName);
};

字符串导出文本

/**
 * 下载txt fasta fa等文本文件
 * @param text 文本内容
 * @param fileName 文件名
 */
export const saveTextAsFile = (text: any, filename: string) => {
  const blob = new Blob([text], { type: 'text/plain' });
  const url = URL.createObjectURL(blob);

  const a = document.createElement('a');
  a.href = url;
  a.download = filename;

  document.body.appendChild(a);
  a.click();

  document.body.removeChild(a);
  URL.revokeObjectURL(url);
};


//或者  

/**
 * 下载文件
 * @param url 文件路径
 * @param fileName 文件名称
 */
import { saveAs } from 'file-saver';
//安装一下 file-saver包
export const downloadTxt = (url: string, fileName: string) => {
 const fileBlob = fetch(url).then((r) => r.blob())
  const blob = new Blob(['\uFEFF'+fileBlob ], { type: 'text/plain;charset=utf-8' });
  saveAs(blob, fileName);
};

  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

夜空孤狼啸

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

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

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

打赏作者

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

抵扣说明:

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

余额充值