首页 > 其他分享 >使用 pdf.js 通过文件流方式加载pdf文件

使用 pdf.js 通过文件流方式加载pdf文件

时间:2025-01-17 17:54:55浏览次数:1  
标签:文件 URL js PDF var pdf

关于Pdf.js的基础知识,请参考我的博客 

       上面两篇博客中介绍的内容都是基于直接加载远程服务器中静态PDF文件(即URL地址)来渲染PDF的,实际业务场景中,如与第三方系统对接过程中,第三方系统不直接公开PDF的URL地址,而是通过接口提供PDF文件流,这种方式处理起来就相对麻烦一点。本篇文章详细介绍使用Pdf.js插件通过读取pdf文件流的方式来渲染PDF文件。

先看效果

点击按钮打开PDF渲染页面

 

下面介绍实现的完整流程

第1步:编写WebAPI接口,返回PDF文件流 假设pdf文件在服务器的D盘测试目录下,通过File.OpenRead()方法读取并返回pdf文件流。
 1 using Microsoft.AspNetCore.Mvc;
 2 
 3 namespace SparkWuTong.WebApiX6.Controllers;
 4 
 5 [ApiController]
 6 [Route("api/[controller]/[action]")]
 7 public class FileTestController : ControllerBase
 8 {
 9     [HttpGet]
10     [HttpPost]
11     public async Task<IActionResult> ReadFileStream()
12     {
13         var filePath = "D:\\测试\\发票.pdf";
14         var stream = System.IO.File.OpenRead(filePath);
15         var result = new FileStreamResult(stream, "application/octet-stream")
16         {
17             FileDownloadName = "发票.pdf" // 可选:设置下载文件名
18         };
19 
20         return await Task.FromResult(result);
21     }
22 }

还有另外一种情况,读取远程服务器中PDF文件,如下示例

 1 using Microsoft.AspNetCore.Mvc;
 2 
 3 namespace SparkWuTong.WebApiX6.Controllers;
 4 
 5 [ApiController]
 6 [Route("api/[controller]/[action]")]
 7 public class FileTestController : ControllerBase
 8 {
 9     [HttpGet]
10     [HttpPost]
11     public async Task<IActionResult> ReadFileStream()
12     {
13         var fileUrl = "http://localhost:5600/plugins/pdf-js/test_file.pdf";
14         HttpClient client = new HttpClient();
15         var stream = await client.GetStreamAsync(fileUrl);
16 
17         return new FileStreamResult(stream, "application/octet-stream")
18         {
19             FileDownloadName = "测试文件.pdf" // 可选:设置下载文件名
20         };
21     }
22 }

提示:两种读取pdf文件的方式都可以使用,具体依赖于实际应用场景。

第2步:基于jQuery ajax 封装读取接口并返回文件流的方法

jQuery是大家开发中最常用的脚本库之一,其中 ajax() 方法的能力超级强大,经常用于发送 get/post请求服务器的资源,绝大部分情况下响应格式为 application/json。如果发送请求到上述WebAPI接口是无法正常接收数据的,因为接口返回内容的是文件流。为了能够接收到文件流,这里需要做特殊的配置:

  •  核心1:(1515行)设置 mimeType 为 text/plain; charset=x-user-defined 意思是将以普通文本的格式接收 WebAPI 返回的内容(非常规的 application/json)。
  •  核心2:(1518 至 1524行)接收到 data 数据后,将其转换为 pdf.js 库中定义的 Uint8Array 类型。实现思路参考 pdf.js 中的方法。

 

  • 核心3:(1527行)利用浏览器的File对象将字节数组转换为pdf文件,类型为 application/pdf;charset-UTF-8。
  • 核心4:(1528行)为pdf文件创建一个临时访问的地址。格式为  blob:http://localhost:5600/75f4c795-52fb-4aaa-9204-9744e92649abjiang

将生成的blob地址拷贝到浏览器中访问,并不能成功。

----------------------------------------------------------------------------

URL.createObjectURL() 方法会根据传入的参数创建一个指向该参数对象的URL。这个URL的生命仅存在于它被创建的这个文档里,新的对象URL指向执行的File对象或者是Blob对象。

语法格式为

objectURL = URL.createObjectURL(blob || file);
  • 参数:

  File对象或者Blob对象

    • File对象就是一个文件,比如我用input type="file"标签来上传文件,那么里面的每个文件都是一个File对象。
    • Blob对象就是二进制数据,比如通过new Blob()创建的对象就是Blob对象。又比如,在XMLHttpRequest里,如果指定responseType为blob,那么得到的返回值也是一个blob对象。
  • 注意点:

  每次调用createObjectURL的时候,一个新的URL对象就被创建了。即使你已经为同一个文件创建过一个URL,如果你不再需要这个对象,要释放它,需要使用URL.revokeObjectURL()方法。当页面被关闭,浏览器会自动释放它,但是为了最佳性能和内存使用,当确保不再用得到它的时候,就应该释放它。

有的同学会说为什么一定要求用jQuery ajax()呢,确实还有很多其他便捷的方法来读取文件流,比如 fetch()方法就非常的简单

 1 var newPdfUrl = 'http://localhost:5610/api/FileTest/ReadFileStream';
 2 fetch(newPdfUrl)
 3     .then(function (response) {
 4         if (response.ok) {
 5             return response.arrayBuffer();
 6         }
 7         else {
 8             spark.alertErrorX("从服务器获取pdf文件失败!");
 9         }
10     })
11     .then(buffer => {
12        // TODO 
13     })
14     .catch(function (err) {
15         log('------插件读取pdf文件发生异常:' + err);
16     });

还有原生的  XMLHttpRequest 对象也可以直接读取文件流

 1 var xhr = new XMLHttpRequest();
 2 xhr.open('GET', pdfUrl, true);
 3 xhr.responseType = 'blob';
 4 xhr.onreadystatechange = function () {
 5     if (xhr.readyState !== 4) {
 6         return;
 7     }
 8 
 9     var status = xhr.status;
10     if ((status >= 200 && status < 300) || status === 304) {
11        // TODO 
12     }
13 };
14 xhr.send();
第3步:利用 pdf.js 的 viewer.html 渲染文件

  • 12行,定义一个iframe,用于加载pdf.js中提供的示例页面 view.html。
  • 32行,将第2步中创建的blob url 赋值给  view.html 页面的 file 参数。

完成以上步骤后,在网页中即可完整的渲染pdf文件了

 

标签:文件,URL,js,PDF,var,pdf
From: https://www.cnblogs.com/SavionZhang/p/18676306

相关文章

  • UEFI 中的inf、dsc、FDF文件都是什么作用?DEC是什么
    在UEFI开发中,inf、dsc、FDF和DEC文件是EDKII构建系统的重要组成部分,各自有不同的作用。1.INF文件(ModuleInformationFile)作用:描述模块的构建信息,如源代码、依赖库、编译选项等。内容:包括模块类型、GUID、源文件、库依赖、PCD变量等。用途:用于定义单个模块的......
  • Linux操作命令之文件服务
    一、vsftpd服务vsftpd服务:c/sb/s 浏览器/服务器模式        软件包:                服务端:vsftpd-3.0.2-25.el7.x86_64.rpm                客户端:lftp-4.4.8-11.el7.x86_64.rpm        端口:        ......
  • C# winform 文件被占用的问题
    stringpath=@"C:1.xlsx";try{using(varstream=File.OpenRead(path)){//导入数据List<DataEntity>rows=stream.Query<DataEntity>().ToList();foreach(varsinrows){if(!s.Na......
  • JSP美发信息综合服务与管理系统5hxk2(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、研究背景与意义随着人们生活水平的提高,越来越多的人开始注重个人形象和美容美发。传统的手工管理方式已经无法满足现代美发店的需求,因此,开发美......
  • JSP芒果分销系统s94qu--程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、题目芒果分销系统的设计与实现二、研究背景及意义随着信息技术的飞速发展,农业与信息技术的融合已成为推动农业现代化进程的关键力量。果农及......
  • 网站目录中的PHP脚本无法写入,导致缓存文件生成失败
    根据您的描述,您遇到了网站目录中的PHP脚本无法写入的问题,这直接影响了缓存文件的生成,进而导致网站运行不正常。具体来说,espcms_datacache/_templates 和 espcms_datacache/dbcache 目录下的PHP文件无法写入,这对网站性能和功能产生了负面影响。要解决这个问题,您可以按照以下步......
  • www目录文件不能解压 - 虚拟主机/数据库问题
    您好,当您遇到在www目录下无法解压文件的问题时,这可能是由多个因素共同作用的结果。以下是一些常见的原因及其对应的解决方案:压缩文件完整性:首先,请确保上传的压缩文件(如ZIP、RAR)本身没有损坏。可以在本地计算机上尝试解压该文件,以确认其是否可以正常打开。如果本地也无法解压,......
  • Mac传输文件神器ToDesk,支持安卓、Windows、IOS
    家里的电脑是苹果机,公司的电脑却是戴尔Windows系统,有时候需要互传一下文件但人却不在目标设备的身边,委托他人开机通过邮件代传又不便,QQ微信又不能在两台电脑设备上同时登,这种情况怎么办?当置于公司Mac中的文件紧急需要传输到手机、平板中或者其他设备中的内容需要传输到MacBook中时......
  • 【前端进阶】在AI浪潮下前端如何结合应用于程序中,如:Brain.js创建模型
    前端和人工智能(AI)的结合可以创造非常丰富的用户体验,从简单的基于规则的交互到复杂的机器学习模型驱动的功能。在Web应用程序中集成AI可以增强用户交互、个性化内容推荐、图像和语音识别、自然语言处理等。前端与AI的结合应用聊天机器人(Chatbots):通过集成NLP(自然语言处理)技......
  • Linux 查看目录下的文件夹命令与 find 查找某个目录但不包括该目录本身
    在Linux系统中,管理和查找文件及文件夹是日常运维和开发过程中常见的任务。本文将介绍如何查看目录下的文件夹,并使用 find 命令查找特定目录下的内容,但排除该目录本身。我们将详细讨论以下内容:使用 ls 命令查看目录下的文件夹。使用 find 命令查找特定目录内容并排除该......