uniapp实现PDF的预览
文章目录
- 前言
- 一、文件流办法
- 二、PDFJS办法
- 三、uniapp插件办法
- 四、补充
前言
因为涉及文件权限,所以需要API二次包装后给客户端。
 也就,不能让客户端直接链接读取。
 比较坎坷,记录一下
一、文件流办法
API将PDF转文件流,传输给客户端
            if (process.env.VUE_APP_PLATFORM === 'h5') {// H5方案:生成Blob URLconst blob = new Blob([arrayBuffer], { type: 'application/pdf' });this.pdfUrl = URL.createObjectURL(blob);return;}
H5还是很容易实现的。
 APP就无法实现,plus.io.PUBLIC_DOCUMENTS、uni.env.USER_DATA_PATH都不能可用。读写网络一通配置还是报错。
二、PDFJS办法
https://mozilla.github.io/pdf.js/ 官网下载 按指示配置
static/└── pdfjs/├── build/│   ├── pdf.js│    └── pdf.worker.js└── web/└── viewer.html<template><web-view :src="pdfViewerUrl"></web-view>
</template><script>
export default {data() {return {pdfViewerUrl: ''}},onLoad(options) {const pdfUrl = decodeURIComponent(options.pdfUrl)// 使用绝对路径指向static目录下的viewer.html,并传递PDF文件URLthis.pdfViewerUrl = `/static/pdfjs/web/viewer.html?file=${encodeURIComponent(pdfUrl)}`}
}
</script>
但是调试问题很多啊:
 1、file origin does not match viewer’s(跨域)
 2、Failed to load module script” 错误(MIME 类型)
 搞不定
三、uniapp插件办法
移动端-H5-小程序在线预览pdf,图片,视频
 在插件市场找到个可以用的,自己改了改
 public static string pdf(string path,string uid){try{string filename = $"tmp_{uid}.pdf";string topath = $"wwwroot\\pdf\\{filename}";string directoryPath = Path.GetDirectoryName(topath);if (!Directory.Exists(directoryPath)){Directory.CreateDirectory(directoryPath);}File.Copy(path, topath, true); // 第三个参数表示覆盖已存在的文件return "true";}catch (Exception ex){return "nosrc";}}后端C#,将pdf 挪个窝,移到webapi临时文件。
<template><view><!-- PDF容器 --><ss-preview :fileUrl="fileUrl" :fileType="fileType" :imageList="imageList"></ss-preview></view>
</template><script>export default {data() {return {fileUrl: '',fileType: '2',imageList: [],};},onLoad() {let uid=this.$assist.gdata("user").id;let src =this.$mConfig.baseUrl+ `/pdf/tmp_${uid}.pdf`;let fileUrl = decodeURIComponent(src)this.fileUrl = fileUrl;},onNavigationBarButtonTap(e) {this.navTo('scan');},onBackPress(options) {this.navTo(this.$assist.gdata("mypage"))// 阻止默认返回行为return true;},methods: {async navTo(url) {this.$mRouter.push({route: url});},},};
</script>
然后UNIAPP里直接读取 PDF就行。安卓测试成功。
 缺点就是 这控件的渲染太快,我干脆在点击链接的时候触发后端,复制完后回传bool,前端再跳PDF页面显示
 不知道v-if 能解决这问题不。
 
四、补充
虽然PDF显示没问题了,API中的临时PDF是根据用户名区分,
 即解决了,多用户冲突问题,也不会导致文件很多的情况。
但是也衍生了一个问题,访问 A.PDF 或 B.PDF,他们的临时路径都是 API\tem_0.pdf ,缓存会导致页面内容不会刷新。这就需要加一个临时版本号:
let src =this.$mConfig.baseUrl+ `/pdf/tmp_${uid}.pdf`;
改为
let src =this.$mConfig.baseUrl+ `/pdf/tmp_${uid}.pdf?t=` + new Date().getTime();
// this.$mConfig.baseUrl= http://localhost:8090/  就是我的WebApi地址/* 
Webapi的 Program.cs 别忘了加入下面的代码,打开静态文件
app.UseStaticFiles(new StaticFileOptions
{FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")),
});*/
