微信小程序webview中打开pdf、ppt、doc、xls等链接

2,452 阅读1分钟

微信小程序打开pdf、ppt、doc、xls等链接时,ios和android是不一样的。ios使用小程序原生web-view加载链接即可,而android需要使用wx.downloadFile + wx.openDocument方式才能正常加载。

  1. 服务端HTML页面(PHP)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Open PDF</title>
    <!-- 引入微信JSSDK -->
    <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

</head>
<body>

<a href="javascript:void(0)" onclick="openMiniProgram('https://rs.zqrb.cn/roadshow/77/h5/pdf/gonggao1.pdf')">https://rs.zqrb.cn/roadshow/77/h5/pdf/gonggao1.pdf</a>

<script>
/*
调用微信JSSDK,打开文档。也可以使用getEnv异步判断是否为小程序环境,我这里只用了简单的UA判断。
wx.miniProgram.getEnv(function(res) {
      callback(res.miniprogram); // true: 小程序, false: 其他
});
*/
function openMiniProgram(pdfUrl) {
  //判断H5页面是否被嵌入微信小程序的web-view组件中
  if (window.wx && wx.miniProgram) {
    //判断是否为小程序环境
    const isMiniProgramUA = /MiniProgram/i.test(navigator.userAgent);
    if (isMiniProgramUA) {
        // 使用微信JSSDK调用接口
		wx.miniProgram.navigateTo({
			url: '/pkg_other/pages/pdfviewer/pdfviewer?pdfUrl=' + encodeURIComponent(pdfUrl)
		});
    }else{
		// 可以在PC浏览器的手机模式下,也能打开PDF
		window.open(pdfUrl);
	}
   } else {
    //如果不在小程序环境中,可以在这里实现其他逻辑,比如在新窗口中打开 PDF
	//window.location.href = pdfUrl;
	window.open(pdfUrl);
  }
}
</script>
</body>
</html>
  1. 微信小程序中(pdfviewer.js)
// pkg_other/pages/pdfviewer/pdfviewer.js
Page({
  data: {},

  onLoad(options) {
    if (options.pdfUrl) {
      this.loadPdf(decodeURIComponent(options.pdfUrl));
    }
  },

  loadPdf: function (pdfUrl) {
    // console.log("loadPdf", pdfUrl)
    // ios 直接使用webview加载;android 使用 wx.downloadFile + wx.openDocument
    if (getApp().globalData.platform === 'ios') {
      wx.redirectTo({
        url: '/pkg_other/pages/web/web?title=""&url=' + pdfUrl
      });
      return;
    }

    let file = pdfUrl;
    let fileType = null;
    if (file.endsWith('.doc')) {
      fileType = 'doc';
    } else if (file.endsWith('.docx')) {
      fileType = 'docx';
    } else if (file.endsWith('.xls')) {
      fileType = 'xls';
    } else if (file.endsWith('.xlsx')) {
      fileType = 'xlsx';
    } else if (file.endsWith('.ppt')) {
      fileType = 'ppt';
    } else if (file.endsWith('.pptx')) {
      fileType = 'pptx';
    } else if (file.endsWith('.pdf')) {
      fileType = 'pdf';
    }

    if (fileType) {
      const that = this;
      wx.showLoading({
        title: '正在加载...',
      });
      wx.downloadFile({
        url: pdfUrl,
        success: (res) => {
          wx.hideLoading();
          wx.openDocument({
            filePath: res.tempFilePath,
            fileType: fileType,
            showMenu: true,
            success: function () {
              console.log('PDF文件打开成功');
            },
            fail: function (err) {
              console.error('PDF文件打开失败', err);
            },
            complete() { // 接口调用结束的回调函数(调用成功、失败都会执行)
              that.handleBack();
            }
          });
        },
        fail: (err) => {
          wx.hideLoading();
          console.error('PDF文件下载失败', err);
          that.handleBack();
        },
      });
    } else {
      wx.previewMedia({
        sources: [{
          type: "image",
          url: pdfUrl
        }]
      })
    }
  },

  /*
    wx.miniProgram.navigateTo({
	     url: '/pkg_other/pages/pdfviewer/pdfviewer?pdfUrl=' + encodeURIComponent(pdfUrl)
    });

    如果网页端是 wx.miniProgram.redirectTo 则不需此方法。
  */
  handleBack() {
    wx.navigateBack({
      delta: 1,
    });
  },

 //其它方法省略...
})

web.js

Page({
  data: {
    title: '',
    url: '',
  },

  onLoad(options) {
    this.setData({
      title: options.title,
      url: options.url
    })
  },
})

web.wxml

<web-view src="{{url}}" bindload="onWebViewLoad"/>