普通视图

发现新文章,点击刷新页面。
今天 — 2025年11月27日首页

UniApp PDF文件下载与预览功能完整实现指南

作者 CyberShen
2025年11月27日 15:49

功能概述

在UniApp开发中,实现PDF文件的下载与预览是一项常见需求。本文将详细介绍如何使用UniApp框架实现这一功能,并提供完整的代码示例和注意事项。以下是完整的实现代码,支持多端兼容和错误处理:

const handleDownload = (item: any) => {
  uni.showLoading({title:'下载中...'})
  // 定义存储路径
  const filePath = `${uni.env.USER_DATA_PATH}/${item.name}.pdf`
  uni.downloadFile({
    url: item.fileUrl,
    success: (data:any) => {
      uni.getFileSystemManager().saveFile({
        tempFilePath: data.tempFilePath,
        filePath: filePath, // 目标路径(可选)
        success: (res1:any) => {
          uni.openDocument({
            filePath: res1.savedFilePath,
            fileType: 'pdf',
            showMenu: true,
            fail: () => {
              uni.showToast({icon:'none',title:'打开失败'})
            },
          });
        },
        fail: err => {
          uni.showToast({icon:'none',title:'保存失败'})
        }
      })
    },
    fail: (err) => {
      console.log(err);
      uni.showToast({
        icon: 'none',
        mask: true,
        title: '失败请重新下载',
      });
    },
    complete: () => {
      uni.hideLoading()
    },
  })
}

实现原理分析

1. 下载流程

UniApp提供了uni.downloadFileAPI用于文件下载,此方法会将远程文件下载到临时路径。下载成功后,通过uni.getFileSystemManager().saveFile()将文件从临时路径保存到指定位置,使其持久化存储。

2. 预览功能

保存成功后,使用uni.openDocumentAPI打开PDF文件。该API会自动调用系统中已安装的PDF阅读器来打开文件,提供良好的用户体验。

多端兼容性处理

不同平台的实现差异

根据目标平台的不同,可能需要采用不同的实现方案:

  1. H5平台:可以使用window.open直接在新标签页打开PDF链接
  2. 微信小程序:需在微信公众平台配置downloadFile合法域名
  3. APP端:可使用上述代码实现,也可集成原生PDF插件获得更好体验

多端兼容代码示例

exportPDF() {
  // #ifdef H5
  window.open(pdfUrl)
  // #endif
  
  // #ifdef MP-WEIXIN
  uni.downloadFile({
    url: pdfUrl,
    success: res => {
      if (res.statusCode === 200) {
        uni.openDocument({
          filePath: res.tempFilePath,
          showMenu: true,
          success: function(file) {
            console.log("文件打开成功")
          }
        })
      }
    }
  })
  // #endif
  
  // #ifdef APP-PLUS
  // 使用前面提供的handleDownload方法
  // #endif
}

优化与扩展功能

1. 自定义保存路径

默认情况下,文件保存在应用沙盒目录内。如需保存到用户自定义目录(如手机存储的特定文件夹),可以使用以下方法:

// Android平台保存到自定义目录
const downLoadFile = (file) => {
  let dtask = plus.downloader.createDownload(file.fileUrl, {
    filename: "file://storage/emulated/0/自定义文件夹/" + file.originalName
  }, function(d, status) {
    if (status == 200) {
      let fileSaveUrl = plus.io.convertLocalFileSystemURL(d.filename)
      plus.runtime.openFile(d.filename)
    }
  })
  dtask.start()
}

2. 下载进度显示

可以添加进度监听,提升用户体验:

const downloadTask = uni.downloadFile({
  url: item.fileUrl,
  success: (data) => {
    // 成功处理
  }
})

downloadTask.onProgressUpdate((res) => {
  console.log('下载进度' + res.progress)
  console.log('已下载' + res.totalBytesWritten)
  console.log('总大小' + res.totalBytesExpectedToWrite)
})

3. 使用PDF.js实现内嵌预览

对于需要应用内预览的场景,可以集成PDF.js:

<template>
  <web-view :src="webViewUrl"></web-view>
</template>

<script>
export default {
  data() {
    return {
      pdfUrl: '',
      webViewUrl: ''
    }
  },
  onLoad(options) {
    this.pdfUrl = options.url
    // 使用PDF.js的viewer.html预览
    this.webViewUrl = `/static/pdfjs/web/viewer.html?file=${encodeURIComponent(this.pdfUrl)}`
  }
}
</script>

常见问题与解决方案

1. 文件打开失败

  • 原因:设备上没有安装PDF阅读器
  • 解决方案:提示用户安装相关应用,或使用PDF.js等在线预览方案

2. 下载权限问题

  • Android平台:需要申请存储权限
// 申请存储权限
plus.android.requestPermissions([
  'android.permission.WRITE_EXTERNAL_STORAGE',
  'android.permission.READ_EXTERNAL_STORAGE'
], successCallback, errorCallback)

3. 域名白名单限制

  • 微信小程序:需在微信公众平台配置downloadFile合法域名

4. 二进制流文件处理

如果后端返回的是文件流而非直接链接,需要特殊处理:

uni.request({
  url: fileUrl,
  responseType: 'arraybuffer',
  success: (response) => {
    let blob = new Blob([response.data], {type: 'application/pdf;charset=UTF-8'})
    let pdfUrl = window.URL.createObjectURL(blob)
    // 使用此URL进行预览或下载
  }
})

总结

本文详细介绍了在UniApp中实现PDF文件下载与预览的完整方案。核心代码使用了uni.downloadFileuni.openDocumentAPI,具有良好的跨平台兼容性。针对不同平台和特殊需求,也提供了相应的优化方案和扩展功能。关键点总结:

  1. 核心流程:下载→保存→预览
  2. 多端兼容:通过条件编译实现各平台最佳体验
  3. 用户体验:添加进度提示和错误处理
  4. 灵活扩展:支持自定义路径和内嵌预览等功能

此方案已在多个项目中实践验证,稳定可靠,可以作为UniApp项目文件处理的基础实现。

❌
❌