uniapp 安卓、IOS、H5、微信小程序实现PDF在线预览

小程序 0

    在使用uniapp开发移动端时,微信开发者工具里webview能正常打开后端接口返回的pdf文件流。正式发布后,在配置了业务域名和服务器域名的前提下,预览pdf文件却只能看到白屏,因此我猜测微信小程序不能通过webview读取文件流。这个想法有问题的话请大家给与指正。

    后来我通过uniapp api将文件下载在临时目录,再调用api打开,实现了微信小程序的预览。但在安卓端会调用安装的WPS打开,如果用户没有安装pdf阅读器,则无法打开,造成了不好的用户体验。因此,手机端我用pdf.js实现在线预览。

    苹果IOS直接使用webview预览pdf。

    h5我刚开始的时候使用webview无法预览。报错: no enabled plugin supports this MIME type。所以h5也使用pdf.js实现在线预览,但是我遇到cors跨域问题。后来采用blob实现了在线预览。

后端的api接口如下:

/**     * @功能:pdf预览     */    @IgnoreAuth    @RequestMapping("/pdf/preview/**")    public void pdfPreviewIframe(HttpServletRequest request, HttpServletResponse response) {        String imgPath = extractPathFromPattern(request);        // 其余处理略        InputStream inputStream = null;        OutputStream outputStream = null;        try {            inputStream = MinioUtil.getMinioFile(imgPath);            outputStream = response.getOutputStream();            response.setContentType("application/pdf; charset=UTF-8");            byte[] buf = new byte[1024];            int len;            while ((len = inputStream.read(buf)) > 0) {                outputStream.write(buf, 0, len);            }            response.flushBuffer();        } catch (Exception e) {            log.error("预览文件失败" + e.getMessage());        } finally {            if (inputStream != null) {                try {                    inputStream.close();                } catch (IOException e) {                    log.error(e.getMessage(), e);                }            }            if (outputStream != null) {                try {                    outputStream.close();                } catch (IOException e) {                    log.info("imgPath:{}", imgPath);                    log.error(e.getMessage(), e);                }            }        }    }

一、下载pdf.js

http://mozilla.github.io/pdf.js/getting_started

二、解压文件并引入到项目

说明:网上很多案例说,在项目目录下创建hybrid文件夹,把解压后的文件全部放到里面的方式我试了后行不通。

查阅了官方文档,发现是我肤浅了。

必须严格按照上面说是的目录才行。 

在static目录下新建pdfview目录,将解压后的文件拷贝到该目录下。如下图所示:

注释viewer.mjs代码,pdf.js不支持加载跨域文件,会报 “file origin does not match viewer’”错误:

三、 webview内预览pdf

<template>	<view>		<web-view :src="fileUrl"></web-view>	</view></template><script>	export default {		data() {			return {				fileUrl: "",				pdfViewUrl: '/static/pdfview/web/viewer.html'			}		},		onLoad(options) {			this.fileUrl = decodeURI(options.fileUrl)			if (!!options.isPdfView) {				this.fileUrl = this.pdfViewUrl + '?file=' + encodeURI(this.fileUrl)			}		},		methods: {		}	}</script><style></style>

 四、安卓、微信小程序分别预览

            //h5预览pdf			h5PdfView(item) {				uni.showLoading({					title: '加载中...'				})				uni.request({					url: this.baseFileURL + '/pdf/preview/' + item.resourceId,					method: 'POST',					responseType: 'arraybuffer'				}).then(res => {					uni.hideLoading()										let pdfData = res.data					let blob = new Blob([pdfData], {						type: 'application/pdf;charset=UTF-8'					})					pdfData = window.URL.createObjectURL(blob)					this.h5PdfUrl = encodeURIComponent(pdfData)					uni.navigateTo({						url: '/subpages/webview/webview?fileUrl=' + this.h5PdfUrl + "&isPdfView=true",					})				})			},			//pdf预览			pdfView(item) {				item.fileUrl = this.baseFileURL + '/pdf/preview/' + item.resourceId				// #ifdef APP-PLUS				switch (uni.getSystemInfoSync().platform) {					case "android":						console.log("android")						uni.navigateTo({							url: '/subpages/webview/webview?fileUrl=' + encodeURI(item.fileUrl) +								"&isPdfView=true",						})						break;					case "ios":						console.log("ios")						uni.navigateTo({							url: '/subpages/webview/webview?fileUrl=' + encodeURI(item.fileUrl),						})						break;				}				// #endif				// #ifdef H5				this.h5PdfView(item)				// #endif 				//  #ifdef MP-WEIXIN				let fileName = item.resourceId.substring(item.resourceId.lastIndexOf('/') + 1);				uni.downloadFile({					url: item.fileUrl, //文件地址					filePath: wx.env.USER_DATA_PATH + '/' + fileName,					success: function(res) {						const filePath = res.filePath || res.tempFilePath;						uni.openDocument({							filePath: filePath,							showMenu: false,							success: function(res) {}						});					}				});				// #endif			}

五:预览效果

也许您对下面的内容还感兴趣: