前端处理blob和后端Java实现预览pdf

遇到的问题

线上地址我们访问,是无法下载的,跨域了,但是我们设置我们本地,下载就不会报错跨域,因此我们需要将这个在线地址的数据获取下来,就是二进制获取下来,然后用标签保存下来

blob介绍

BLOBBinary Large Object的缩写,意为"大的二进制对象"。

对Blob对象可做如下操作

  1. 创建Blob URL 是指向存储在浏览器缓存或磁盘中的blob的一个引用。
  2. 通过postMessage()在窗口和工作进程间传输blob数据
  3. 将blob存储在客户端数据库
  4. 通过XMLHTTPRequest的send()方法将blob上传到服务器

快速入门

javascript 复制代码
 <script type="text/javascript">
            function dowmload (url){
                // 首先获取服务端的数据
                const xhr = new XMLHttpRequest();
                //获取图片的内容,传入url地址
                xhr.open('GET', url)
                //获取二进制的文件
                xhr.responseType ='blob'
                //发送我们请求
                xhr.send()
                //监听,
                xhr.onload = function(){
                    // 加载回来的数据就在我们的blob里,xhr.response后端返回的数据
                    const fileBlob = xhr.response
                    // 将返回的blob转成url地址,就可以实现本地预览
                    const fileUrl = URL.createObjectURL(fileBlob)
                    // 实现下载,创建a标签
                   const elemneta =  document.createElement('a')
                   //设置属性
                    elemneta.setAttribute('href',fileUrl)
                    elemneta.setAttribute('download','')
                    //放入body当中
                    document.body.appendChild(elemneta)

                }
            }
            let Imgurl  = 'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d6f5149e490240a4be8235606f09f89b~tplv-k3u1fbpfcp-no-mark:480:400:0:0.awebp?'
            dowmload(Imgurl)
    </script>

下图就是我们返回的fileBlob,这样我们就拿到了图片的数据,然后就是下载下来

实战应用

实现预览pdf的功能

前端Vue部分

首先获取请求地址,设置请求,然后通过blob对象创建新的url

this.$router.resolve() 方法,生成一个路由对象routeUrl,该方法接受一个参数对象,其中path属性指定了路由路径为'/previewPdf'

query属性指定了路由参数为**{ url: this.previewUrl },其中this.previewUrl是之前生成的用于预览PDF的URL**。

然后,通过访问routeUrl.href属性,获取生成的URL字符串,并使用window.open()方法在一个新的浏览器窗口中打开该URL。

'_blank'参数表示在新窗口中打开。

javascript 复制代码
 
openUrl = "http://"+ window.location.host + openUrl;
   // request是引入的
                request({
                    url: openUrl,
                    method: 'get',
                    responseType: 'blob'
                }).then(res => {
                  console.log(res)
                  var data = res.data;
                  var binaryData = [];
                  binaryData.push(data);
                    //过blob对象创建新的url
                  this.previewUrl = window.URL.createObjectURL(new Blob(binaryData,  {type: "application/pdf;charset=utf-8"} ));
                  // vue路由跳转并以问号形式携带vue-pdf预览时所需要的pdf地址
                  const routeUrl = this.$router.resolve({
                    path: '/previewPdf',
                    query: { url: this.previewUrl, }
                  });
                  window.open(routeUrl.href, '_blank')
                  this.loading.close();
                });

后端java部分

首先获取文件的字节数组

将字节数组转换成blob对象,并从blob对象中获取字节数组

response.getOutputStream()方法获取响应的输出流outputStream,该流用于将内容发送到客户端

response.setContentLength((int) blob.length())方法设置响应内容的长度为字节数组的长度。这将告诉客户端可以期望接收到的内容长度。

然后,通过response.setContentType("application/pdf")方法设置响应的内容类型为PDF文件。这将告诉客户端接收到的是一个PDF文件。

最后,使用outputStream.write(bytes)将字节数组写入响应输出流,将内容发送到客户端进行下载或显示。

java 复制代码
@GetMapping("/getFileByte")
    public void getFileByte(HttpServletResponse response, String fileId) throws Exception {
        byte[] byteArray= FmpRuntime.getFileByte(fileId);
        Blob blob = new SerialBlob(byteArray);
        byte[] bytes = blob.getBytes(1, (int) blob.length()); // 从Blob对象中获取字节数组
        ServletOutputStream outputStream = response.getOutputStream(); // 获取响应输出流
        response.setContentLength((int) blob.length()); // 设置响应内容长度
        response.setContentType("application/pdf"); // 设置响应类型为PNG图片
        outputStream.write(bytes); // 将字节数组写入响应输出流
        outputStream.flush(); // 刷新响应输出流
    }
相关推荐
谁在黄金彼岸21 分钟前
Lance模型解读
后端
神奇小汤圆26 分钟前
深入理解MySQL事务隔离级别:MVCC机制与Next-Key Lock如何解决幻读问题?
后端
万少29 分钟前
一封邮件,让我重新打开了搁置半年的鸿蒙应用
前端·javascript·后端
Java编程爱好者1 小时前
手把手看懂 Java 字节码:讲透 Integer 判等、静态方法重写与 try-finally 核心底层
后端
踏浪无痕1 小时前
k8s发布服务,nacos未服务未下线紧急处理流程
后端
TYKJ0231 小时前
物理安全:顶级机房为什么需要刷脸+指纹+工牌
后端
程序员黑豆1 小时前
AI全栈开发 - Java:注释
前端·后端·ai编程
小二·1 小时前
Spring Boot 3 + Vue 3 全栈开发实战
vue.js·spring boot·后端
仿生joe会梦见漫天的大雪吗2 小时前
CTF学习笔记03:密码口令 —— 从弱口令到字典爆破
后端
自进化Agent智能体2 小时前
从零到一玩转Hermes Agent:VPS部署 × 模型配置 × 记忆架构 × 多Agent协作
后端