前端base64转pdf预览方案(js处理、小程序处理)
本章分为js处理、小程序处理
JS处理PDF的base64数据进行预览
两种预览方式:跳转新窗口预览;当前页面预览(使用embed标签等、或需引入pdf.js)
跳转新窗口预览
转blob类型(注意要设置类型为application/pdf打开才是预览,不然就是直接下载)
——使用createObjectURL转url格式(处理后会变成blob://... 这种格式)
——打开(两种打开方式:img标签直接打开、window.open窗口打开)
拓展:
具体的MIME类型:
text/html: 对于一般网页
text/plain: 对于一般文本
text/css :对于级联样式表
text/javascript :对于脚本
application/octet-stream: 意味着“下载这个文件”
application/x-java-applet :对于 Java applets
application/pdf :对于 PDF 文档
let bytes = Uint8Array.from(atob(base64Data), character => character.charCodeAt(0)); //atob将base64转为二进制数据,unit8Array将二进制数据转为字节数组
let blob = new Blob([bytes], { type: 'application/pdf' });//将字节数组包装成一个PDF的Blob对象(二进制大对象)
let url = URL.createObjectURL(blob);//为Blob对象创建一个临时的本地URL
window.open(url, "_blank");//访问pdf
iframe内嵌视图预览
可使用html的iframe 标签 embed 标签 object 标签、
效果:
let bytes = Uint8Array.from(atob(base64Data), character => character.charCodeAt(0));
let blob = new Blob([bytes], { type: 'application/pdf' });
let url = URL.createObjectURL(blob);
<embed src={url} type="application/pdf" ></embed>
<iframe src={url}" ></iframe>
<object src={url} type="application/pdf" ></object>
引入pdf.js
效果:

- 首先,项目中需要引入pdf.js
注意:不同版本的pdf.js的引入在项目中的引入方式不同,这里下载的是3.8.162的版本
npm install --save pdfjs-deist
或
yarn add --save pdfjs-dist@3.8.162
- 项目中引入并使用
import {GlobalWorkerOptions,getDocument} from 'pdfjs-dist/legacy/build/pdf.js' //getDocument 用于加载 PDF,GlobalWorkerOptions 用于配置工作线程
import * as workerSrc from 'pdfjs-dist/build/pdf.worker.entry.js'//pdf.worker.entry.js,负责 PDF 解析的底层计算,不阻塞主线程
/**
*
* @param {canvas的id} id
* @param {pdf的base64数据} base64Data
* @param {缩放数值,1为正常值,<1缩小,>1放大} scale
*/
export const getPDFCanvas = (id,base64Data,scale=2.5) => {
const pdfData = atob(base64Data) //将 Base64 编码的字符串解码为原始二进制数据(以 ASCII 字符形式表示)
//配置 PDF 工作线程。为 PDF.js 设置工作线程脚本路径,确保解析 PDF 时使用独立线程,避免卡顿页面
GlobalWorkerOptions.workerSrc = workerSrc
// 加载 PDF 文档
let loadingTask = getDocument({data: pdfData});
loadingTask.promise.then(function(pdf) {
console.log('PDF loaded');
// 获取第一页
let pageNumber = 1;
pdf.getPage(pageNumber).then(function(page) {
console.log('Page loaded');
//计算渲染视口(根据缩放比例)
let viewport = page.getViewport({scale: scale});
// 准备 canvas 元素(设置宽高与视口一致)
let canvas = document.getElementById(id);
let context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// 将 PDF 页面渲染到 canvas
let renderContext = {
canvasContext: context,
viewport: viewport
};
let renderTask = page.render(renderContext);
renderTask.promise.then(function () {
console.log('Page rendered');
});
});
}, function (reason) {
// PDF loading error
console.error(reason);
});
}
在组件中使用:
getPDFCanvas('pdf-cavas',base64数据,1.5)
<canvas id="pdf-canvas"></canvas>
小程序处理PDF的base64数据进行预览(Taro开发微信小程序为例)
Taro.getFileSystemManager()将文件保存到本地——Taro.openDocument()打开
const checkPDF = (item) =>{
const { result, recordName} = item
const fullPath = Taro.env.USER_DATA_PATH + '/' + recordName
const FileSystermManagement = Taro.getFileSystemManager()
FileSystermManagement.writeFile({
filePath: fullPath,
data: Taro.base64ToArrayBuffer(result?.replace(/[\r\n]/g, '')),
encoding: 'binary',
success: (res) => {
console.log('完成写入文件', res)
Taro.openDocument({
filePath: fullPath,
showMenu: true,
fileType:'pdf',
success: (r) => {
console.log('完成打开文件', r)
},
fail:(error)=>{
},
complete: () => {
Toast.close()
},
})
},
})
}
微信小程序查看PDF文件(已经有现成的链接的情况)
有现成PDF链接的情况下,先downloadFiles下载PDF再openDocument打开查看
import { useEffect, useState } from "react"
import Router, { NavigateType } from 'tarojs-router-next'
import Taro, { useRouter } from '@tarojs/taro'
import { Button, Loading } from "@taroify/core"
import { View } from "@tarojs/components"
import { Dialog } from '@taroify/core'
const Index = (props) => {
const { url, title } = Router?.getParams()
const [loading, setLoading] = useState(false)
const [openFileUrl, setOpenFileUrl] = useState()
useEffect(() => {
Taro.setNavigationBarTitle({
title: title || '查看文件',
})
downloadFile(url)
}, [url, title])
const downloadFile = (url) => {
setLoading(true)
Taro.downloadFile({
url: url || '',
success: function (res) {
const filePath = res?.tempFilePath
setOpenFileUrl(filePath)
openFile(filePath)
},
fail: function (params) {
setLoading(false)
Dialog.alert({
message: '访问失败',
confirm: '确定',
onConfirm: () => {
Router.back()
},
})
}
})
}
const openFile = (filePath) => {
setLoading(true)
wx.openDocument({
filePath: filePath,
success: function (res) {
setLoading(false)
console.log('打开文档成功')
},
finally: function () {
setLoading(false)
}
})
}
return <View style={{ width: '100vw', height: '100vh' }} className="flex items-center justify-center">
{
loading ? <Loading size="30px" type="spinner"></Loading>
:
<Button color="default" onClick={() => {
if (openFileUrl) {
openFile(openFileUrl)
} else {
downloadFile(url)
}
}}>查看文件</Button>
}
<Dialog id="dialog" />
</View>
}
export default Index

浙公网安备 33010602011771号