小程序页面保存为图片并下载(保姆级教学)

1,426 阅读2分钟

实现方案

1.使用canvas(缺陷:需要将数据和css全部传递,页面复杂时。工作量大难以实现) 2.使用web-view引入h5页面,h5页面使用html2canvas将页面保存为base64,传入小程序,调用wxApi保存为本地图片

实现代码

小程序端

wxml

<view>
  <web-view  src="h5地址" bindmessage='handleMessage' ></web-view>
</view>

js

 data: {
    filePath: '',
  },

// 获取h5传递过来的base64信息
  handleMessage(res) {
    let base64 = res.detail.data[0].message
    this.saveImageToPhotosAlbum(base64)
  },
// base64格式处理获取文件保存地址
 saveImageToPhotosAlbum(data) {
 let base64 = data.replace(/^data:image\/\w+;base64,/, "");//去掉data:image/png;base64,
    //就是这里需要获取微信环境的保存路径,所以最好把转好的base64传到小程序端来下载    
    this.setData({
      filePath: wx.env.USER_DATA_PATH + '/detail.png'  //保存图片的名字
    })
    this.base64ToSrc(base64)
  },
  
   //将base64转为图片
  base64ToSrc(base64) {
    const that = this;
    //获取文件管理器对象
    var fsm = wx.getFileSystemManager();
    fsm.writeFile({
      filePath: this.data.filePath,
      data: base64,
      encoding: 'base64',
      success() {
    //将base64图片文件保存至用户系统相册
        that.downloadHsjcReport(base64)

      },
      fail() {
        console.log('ERROR');
      },
    });
  },
  
   //将base64图片文件保存至用户系统相册
  downloadHsjcReport(base64) {
    const that = this;
    wx.showLoading({
      title: '正在保存...',
      mask: true
    });
    //保存图片到相册
    wx.saveImageToPhotosAlbum({
      filePath: this.data.filePath,
      success: function (res) {
        wx.hideLoading();
        wx.setStorageSync('isBase', false)
        wx.showToast({
          title: '保存成功!',
          icon: 'success',
          duration: 2000//持续的时间
        })
      },
      fail: function (err) {
        wx.hideLoading();
        if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {
          wx.showModal({
            title: '提示',
            content: '需要您授权保存相册',
            showCancel: false,
            success: modalSuccess => {
              wx.openSetting({
                success(settingdata) {

                  if (settingdata.authSetting['scope.writePhotosAlbum']) {
                    wx.showModal({
                      title: '提示',
                      content: '获取权限成功,再次点击下载按钮进行保存',
                      showCancel: false,
                    })
                  } else {
                    wx.showModal({
                      title: '提示',
                      content: '获取权限失败,将无法保存图片到相册',
                      showCancel: false,
                    })
                  }
                },
                fail(failData) {
                  console.log("failData", failData)
                },
                complete(finishData) {
                  console.log("finishData", finishData)
                }
              })
            }
          })
        }
      }
    })
  },
  

h5端

依赖
npm install weixin-js-sdk --save
import wx from "weixin-webview-jssdk"
npm install --save html2canvas
import html2canvas from 'html2canvas'
页面
<div ref='imgDom'> 需要保存为图片的dom  </div>
<div @click="saveDom">保存页面</div>
js Vue3
// 获取页面dom
const imgDom = ref(null);

//保存图片
const saveDome=()=>{
 html2canvas(imgDom.value, {
        useCORS: true // 开启跨域设置,需要后台设置cors
    }).then((canvas) => {
        // toDataURL函数生成img标签的可用数据  图片格式转成 base64
        convertCanvasToImg(canvas)
    })
    }
    
 // 将数据转为base64传递给小程序
 const convertCanvasToImg = (canvas) => {
    let base64 = canvas.toDataURL('img/png', 1)
    wx.miniProgram.postMessage({
        //这里一定要将数据放在dada中
        data: {
            message: base64,
        }
    });
    wx.miniProgram.navigateBack({ delta: 1 }) //注意这里.

}
// 踩坑点:
小程序端web-view 的bindmessage事件 只会在组件销毁、分享是才会触发,注意掌握触发时机