利用html2Canvas将表格下载为html

文章讲述了如何在前端点击按钮时,通过请求后端接口获取数据,动态生成表格并将其隐藏。作者介绍了使用html2canvas将表格转为图片再下载的尝试,以及后来选择的将表格作为字符串直接拼入HTML页面并下载的更高效方法,强调了跨域问题和html2canvas的性能瓶颈。
摘要由CSDN通过智能技术生成

给到我的需求是点击按钮时请求后端接口,根据后端返回的数据,生成表格,并将表格的内容直接下载为html,如下图。
在这里插入图片描述
平常做的下载都是后端返回二进制流,这次前端做下载那就必须把页面先画出来,因为下载下来的表格在页面上是不显示的,所以要画出来再隐藏一下,隐藏的时候可选方式有很多,但是v-if,v-show这种会导致页面重构的不建议使用(事实也证明v-if和v-show在这种场景是不能使用的,因为这种场景要求表格是实际存在的元素)所以我选择了绝对定位加上z-index:-999的方式,让表格隐藏在文档流下面。
1:html代码-表格样式

    <div
      id="canvas-file1"
      style="
        width: 800px;
        line-height: 20px;
        font-size: 14px;
        position: absolute;
        z-index: -999;
      "
    >
      <table
        width="800px"
        border="1px"
        cellspacing="0px"
        cellpadding="10px"
        align="center"
        bgcolor="#fff"
        style="margin-top: 10px"
      >
        <tr>
          <th>商品名称</th>
          <th>规格</th>
          <th>数量</th>
          <th>金额(元)</th>
        </tr>
        <tbody align="center">
          <template v-for="item in table1.goodsDetailsInfoVOList">
            <tr v-if="item.hasChildren">
              <td :rowspan="item.children.length + 1">
                {{ item.goodsName }}
              </td>
              <td>{{ item.goodsSpec }}</td>
              <td>{{ item.goodsNum }}</td>
              <td>{{ item.payAmount }}</td>
            </tr>
            <tr v-for="item in item.children">
              <td>{{ item.goodsSpec }}</td>
              <td>{{ item.goodsNum }}</td>
              <td>{{ item.payAmount }}</td>
            </tr>
          </template>
        </tbody>
      </table>
    </div>

表格画好以后,考虑两种下载的方法,一种是将表格转成图片,然后将图片转成html页面下载。第二种是将表格作为字符串拼接到html页面中,然后下载。(后续发现第一种方法累赘了,当时也不知道怎么想的)
记录一下第一种方法,html2canvas方法里面接受两个参数,第一个就是dom对象,第二个是转canvas时的一些自定义配置项,生成后该方法会调用then回调,将canvas传递出来,我们就可以拿到了。但是有一个值得一提的问题,就是我发现html转canvas的过程是相当缓慢的,这也是后面我放弃这种方法的原因

const handleSubmitExportGoods = () => {
  exportGoodsLoading.value = true;
  setTimeout(() => {
    let arr = [];
    for (let i = 0; i < 100; i++) {
      arr.push({ a: i, b: i + 1, c: i + 2 });
    }
    table1.value = {
      list: arr,
      time: "2023-7-31 09:15:18",
      title: "活动名称",
      titleTime: "2023-7-25 09:00:00 发布",
    };
    nextTick(() => {
      html2canvas(document.getElementById("canvas-file1"), {
        backgroundColor: "transparent", //背景图片透明
        allowTaint: true, //跨域
        useCORS: true, //跨域
      }).then((canvas) => {
        exportGoodsLoading.value = false;
        let oImg = new Image();
        oImg = canvas.toDataURL("image/png"); // 导出图片
        const html = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title></title></head><body style="margin:0"><img src="${oImg}"></img></body></html>`;
        let blob = new Blob([html], { type: "text/html" });
        let url = window.URL.createObjectURL(blob);
        let a = document.createElement("a");
        a.download = "订单";
        a.style.display = "none";
        a.href = url;
        document.body.appendChild(a);
        a.click();
        a.remove();**
      });
    });
  }, 500);
};

然后就是第二种方法,把table拼到html里面,直接上代码

const downloadFile = (domName, fileName) => {
  let htmlStr = document.getElementById(domName).innerHTML;
  const html = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title></title></head><body style="margin:0">${htmlStr}</body></html>`;
  let blob = new Blob([html], { type: "text/html" });
  let url = window.URL.createObjectURL(blob);
  let a = document.createElement("a");
  a.download = fileName;
  a.style.display = "none";
  a.href = url;
  document.body.appendChild(a);
  a.click();
  a.remove();
};
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值