vue 开发中遇到的功能模块

2022-02-25 09:16:16 浏览数 (1)

1. 后端post接口以流的方式返回excel数据,前端下载成excel文件

  1. axios 接口传参 否则乱码:responseType: 'arraybuffer',
代码语言:javascript复制
// 结果是blob流,将流导出excel
export function outExcel() {
  return request({
    url: '/api/logistics/ucu/exportExcel',
    method: 'post',
    responseType: 'arraybuffer',
  })
}
  1. 安装依赖 cnpm install js-file-download --save
  2. 组件中使用
代码语言:javascript复制
downloadExcel() {
      const loading = this.$loading({
        lock: true,
        text: '下载中请等待...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      api.outExcel().then(res => {
        if (res) {
          loading.close()
          this.$message.success('导出成功')
          fileDownload(res, '您需要的xls文件.xls')
        }
      })
    },

2. 后端将图片以base64格式传递,前端接收base64码后渲染页面

在模板中

代码语言:javascript复制
<img :src="'data:image/png;base64,'   imgBase64" />

在组件中

代码语言:javascript复制
export default {
  name: "App",
  data() {
    return {
      imgBase64: "接收的base64码"
    };
  }
};

3. vue 将页面内容转化成图片,并下载(只适合PC端)

参考:https://www.jianshu.com/p/0cc51943147d

  1. 安装依赖 cnpm i html2canvas -S
  2. 在组件中
代码语言:javascript复制
<template>
  <div class="main" id="app">
    <div id="screenViewBox">
      <div class="drawContent">
      <div class="title">资金划转成功!</div>
      <div class="content">
        <div class="row">
          <div class="rowLeft">业务类型</div>
          <div class="rowRight">个人资金监管-转账</div>
        </div>
        <div class="row">
          <div class="rowLeft">买方姓名</div>
          <div class="rowRight">张三</div>
        </div>
        <div class="row">
          <div class="rowLeft">卖方姓名</div>
          <div class="rowRight">李四</div>
        </div>
        <div class="row">
          <div class="rowLeft">转出账号</div>
          <div class="rowRight">623188888888123</div>
        </div>
        <div class="row">
          <div class="rowLeft">转出户名</div>
          <div class="rowRight">张三</div>
        </div>
        <div class="row">
          <div class="rowLeft">转入户名</div>
          <div class="rowRight">李四</div>
        </div>
        <div class="row">
          <div class="rowLeft">转入卡号</div>
          <div class="rowRight">623188888888778</div>
        </div>
        <div class="row">
          <div class="rowLeft">转出金额</div>
          <div class="rowRight">20,000元</div>
        </div>
        <div class="row">
          <div class="rowLeft">大写金额</div>
          <div class="rowRight">贰万元整</div>
        </div>
      </div>
      <div class="seal">
        <img src="./assets/image/seal.png" alt="" />
      </div>
    </div>
    </div>
    <div class="btn" @click="savePoster()">
      下载
    </div>
  </div>
</template>

<script>
import Canvas2Image from "@/utils/canvas2Image.js";
import html2canvas from "html2canvas";
export default {
  data() {
    return {};
  },
  methods: {},
  mounted() {

  },
  methods: {
    savePoster() {
      let that = this;
      //打开loading
      //生成图片之前,需先将整体的滚动条隐藏掉,否则生成出来的照片会偏移
      document.getElementById("app").style.overflowY = "hidden";
      //两个参数:所需要截图的元素id,截图后要执行的函数, canvas为截图后返回的最后一个canvas
      var shareContent = document.getElementById("screenViewBox");
      var width = shareContent.offsetWidth;
      var height = shareContent.offsetHeight;
      var canvas = document.createElement("canvas");
      var scale = 5; //这里为了下载出更清晰的图片,值越大越清晰

      canvas.width = width * scale;
      canvas.height = height * scale;
      canvas.getContext("2d").scale(scale, scale);

      var opts = {
        scale: 1, //不管上面的scale是多少倍,这里只能取1,否则会显示不完全
        canvas: canvas,
        logging: true,
        width: width,
        height: height
      };
      let downloadName = "下载的图片名称";
      html2canvas(shareContent, opts).then(function(canvas) {
        //这个方式是直接将canvas保存为图片的,具体参数可自行查看源码
        var img = Canvas2Image.saveAsImage(
          canvas,
          canvas.width,
          canvas.height,
          "PNG",
          downloadName
        );
        //这个方式只是提供展示图片的功能,暂时没有用到
        var img = Canvas2Image.convertToPNG(canvas, canvas.width, canvas.height,'PNG');
         document.body.appendChild(img);

        //生成图片之前,需先将整体的滚动恢复为之前的状态
        document.getElementById("app").style.overflowY = "scroll";
      });
    }
  }
};
</script>
<style lang="less">
body {
  background: rgb(245, 245, 249);
  padding: 0;
  margin: 0;
}
.canvas {
  background: #fff;
  height: 400px;
  width: 90%;
  margin: 20px 0 0 5%;
}
.drawContent {
  position: relative;
  width: 90%;
  background: #fff;
  margin: 30px 0 0 5%;
  padding: 20px 20px 20px 40px;
  box-sizing: border-box;
  .title {
    font-size: 16px;
    color: #333333;
    letter-spacing: 0;
    text-align: center;
    font-weight: 500;
  }
  .content {
    padding: 30px 0 0 0;
    .row {
      display: flex;
      line-height: 150%;
      .rowLeft {
        font-size: 12px;
        color: #999999;
        font-weight: 400;
        width: 40%;
      }
      .rowRight {
        font-size: 12px;
        color: #000000;
        font-weight: 400;
      }
    }
  }
  .seal {
    position: absolute;
    right: 30px;
    bottom: 40px;
    width: 104px;
    height: 66px;
    z-index: 100;
    img {
      width: 104px;
      height: 66px;
    }
  }
}
.btn {
  margin: 40px 0 0 5%;
  width: 90%;
  background: #5A98F8;
  text-align: center;
  height: 50px;
  line-height: 50px;
  color: #fff;
  border-radius: 6px;
}
</style>
  1. 在src/utils/canvas2Image.js中
代码语言:javascript复制
/**
 * covert canvas to image
 * and save the image file
 */
 const Canvas2Image = (function () {
  // check if support sth.
  const $support = (function () {
      const canvas = document.createElement("canvas"),
          ctx = canvas.getContext("2d");

      return {
          canvas: !!ctx,
          imageData: !!ctx.getImageData,
          dataURL: !!canvas.toDataURL,
          btoa: !!window.btoa,
      };
  })();

  const downloadMime = "image/octet-stream";

  function scaleCanvas(canvas, width, height) {
      const w = canvas.width,
          h = canvas.height;
      if (width === undefined) {
          width = w;
      }
      if (height === undefined) {
          height = h;
      }

      let retCanvas = document.createElement("canvas");
      let retCtx = retCanvas.getContext("2d");
      retCanvas.width = width;
      retCanvas.height = height;
      retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
      // retCtx.drawImage(canvas, 0,0, w, h, 10, 10, width, height);
      return retCanvas;
  }

  function getDataURL(canvas, type, width, height) {
      canvas = scaleCanvas(canvas, width, height);
      return canvas.toDataURL(type);
  }

  // save file to local with file name and file type
  function saveFile(strData, fileType, fileName = "name") {
      // document.location.href = strData;
      let saveLink = document.createElement("a");
      // download file name
      saveLink.download = fileName   "."   fileType;
      // download file data
      saveLink.href = strData;
      // start download
      saveLink.click();
  }

  function genImage(strData) {
      let img = document.createElement("img");
      img.src = strData;
      return img;
  }

  function fixType(type) {
      type = type.toLowerCase().replace(/jpg/i, "jpeg");
      const r = type.match(/png|jpeg|bmp|gif/)[0];
      return "image/"   r;
  }

  function encodeData(data) {
      if (!window.btoa) {
          // eslint-disable-next-line no-throw-literal
          throw "btoa undefined";
      }
      let str = "";
      if (typeof data == "string") {
          str = data;
      } else {
          for (let i = 0; i < data.length; i  ) {
              str  = String.fromCharCode(data[i]);
          }
      }

      return btoa(str);
  }

  function getImageData(canvas) {
    const w = canvas.width,
        h = canvas.height;
    return canvas.getContext("2d").getImageData(50, 30, w, h);
}

  function makeURI(strData, type) {
      return "data:"   type   ";base64,"   strData;
  }

  /**
   * create bitmap image
   * 按照规则生成图片响应头和响应体
   */
  const genBitmapImage = function (oData) {
      const biWidth = oData.width;
      const biHeight = oData.height;
      const biSizeImage = biWidth * biHeight * 3;
      const bfSize = biSizeImage   54; // total header size = 54 bytes
      const BITMAPFILEHEADER = [
          // WORD bfType -- The file type signature; must be "BM"
          0x42,
          0x4d,
          // DWORD bfSize -- The size, in bytes, of the bitmap file
          bfSize & 0xff,
          (bfSize >> 8) & 0xff,
          (bfSize >> 16) & 0xff,
          (bfSize >> 24) & 0xff,
          // WORD bfReserved1 -- Reserved; must be zero
          0,
          0,
          // WORD bfReserved2 -- Reserved; must be zero
          0,
          0,
          // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
          54,
          0,
          0,
          0,
      ];

      const BITMAPINFOHEADER = [
          // DWORD biSize -- The number of bytes required by the structure
          40,
          0,
          0,
          0,
          // LONG biWidth -- The width of the bitmap, in pixels
          biWidth & 0xff,
          (biWidth >> 8) & 0xff,
          (biWidth >> 16) & 0xff,
          (biWidth >> 24) & 0xff,
          // LONG biHeight -- The height of the bitmap, in pixels
          biHeight & 0xff,
          (biHeight >> 8) & 0xff,
          (biHeight >> 16) & 0xff,
          (biHeight >> 24) & 0xff,
          1,
          0,
          24,
          0,
          0,
          0,
          0,
          0,
          biSizeImage & 0xff,
          (biSizeImage >> 8) & 0xff,
          (biSizeImage >> 16) & 0xff,
          (biSizeImage >> 24) & 0xff,
          // LONG biXPelsPerMeter, unused
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
      ];

      const iPadding = (4 - ((biWidth * 3) % 4)) % 4;

      const aImgData = oData.data;

      let strPixelData = "";
      const biWidth4 = biWidth << 2;
      let y = biHeight;
      const fromCharCode = String.fromCharCode;

      do {
          const iOffsetY = biWidth4 * (y - 1);
          let strPixelRow = "";
          for (let x = 0; x < biWidth; x  ) {
              const iOffsetX = x << 2;
              strPixelRow  =
                  fromCharCode(aImgData[iOffsetY   iOffsetX   2])  
                  fromCharCode(aImgData[iOffsetY   iOffsetX   1])  
                  fromCharCode(aImgData[iOffsetY   iOffsetX]);
          }

          for (let c = 0; c < iPadding; c  ) {
              strPixelRow  = String.fromCharCode(0);
          }

          strPixelData  = strPixelRow;
      } while (--y);

      return (
          encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER))  
          encodeData(strPixelData)
      );
  };

  /**
   * saveAsImage
   * @param canvas canvasElement
   * @param width {String} image type
   * @param height {Number} [optional] png width
   * @param type {string} [optional] png height
   * @param fileName {String} image name
   */
  const saveAsImage = function (canvas, width, height, type, fileName) {
      // save file type
      const fileType = type;
      if ($support.canvas && $support.dataURL) {
          if (typeof canvas == "string") {
              canvas = document.getElementById(canvas);
          }
          if (type === undefined) {
              type = "png";
          }
          type = fixType(type);
          if (/bmp/.test(type)) {
              const data = getImageData(scaleCanvas(canvas, width, height));
              const strData = genBitmapImage(data);
              // use new parameter: fileType
              saveFile(makeURI(strData, downloadMime), fileType, fileName);
          } else {
              const strData = getDataURL(canvas, type, width, height);
              // use new parameter: fileType
              saveFile(strData.replace(type, downloadMime), fileType, fileName);
          }
      }
  };

  const convertToImage = function (canvas, width, height, type) {
      if ($support.canvas && $support.dataURL) {
          if (typeof canvas == "string") {
              canvas = document.getElementById(canvas);
          }
          if (type === undefined) {
              type = "png";
          }
          type = fixType(type);

          if (/bmp/.test(type)) {
              const data = getImageData(scaleCanvas(canvas, width, height));
              const strData = genBitmapImage(data);
              return genImage(makeURI(strData, "image/bmp"));
          } else {
              const strData = getDataURL(canvas, type, width, height);
              return genImage(strData);
          }
      }
  };

  return {
      saveAsImage: saveAsImage,
      saveAsPNG: function (canvas, width, height, fileName) {
          return saveAsImage(canvas, width, height, "png", fileName);
      },
      saveAsJPEG: function (canvas, width, height, fileName) {
          return saveAsImage(canvas, width, height, "jpeg", fileName);
      },
      saveAsGIF: function (canvas, width, height, fileName) {
          return saveAsImage(canvas, width, height, "gif", fileName);
      },
      saveAsBMP: function (canvas, width, height, fileName) {
          return saveAsImage(canvas, width, height, "bmp", fileName);
      },

      convertToImage: convertToImage,
      convertToPNG: function (canvas, width, height) {
          return convertToImage(canvas, width, height, "png");
      },
      convertToJPEG: function (canvas, width, height) {
          return convertToImage(canvas, width, height, "jpeg");
      },
      convertToGIF: function (canvas, width, height) {
          return convertToImage(canvas, width, height, "gif");
      },
      convertToBMP: function (canvas, width, height) {
          return convertToImage(canvas, width, height, "bmp");
      },
  };
})();

// Export function, used in npm
export default Canvas2Image;
npm

0 人点赞