Vue 采用blob下载后端返回的pdf流或者excel流文件乱码问题解决方案

news2025/7/7 17:18:20

流文件乱码问题解决方案

    • 问题介绍:
    • 一、前端方式解决:
  • 二、后端方式解决:
    • 三、文件预览实现
    • 四、点击按钮打开新窗口预览

问题介绍:

打开或者预览全是乱码。预览pdf如下图:
在这里插入图片描述
解决办法:

1. 后端接口返回的blob文件流,你下载下来的文件是乱码的?

解决办法 :让你的后端设置流的编码为utf-8。请跟后端大佬说,一定要给blob格式的文件流。

2. 后端返回的blob文件流,并且已经设置了utf-8,但是你接受的接口返回值,依然是乱码?

解决办法: 肯定没有设置 responseType: “arraybuffer”。

一、前端方式解决:

预览pdf如下图:
在这里插入图片描述

这个charset=utf-8一定要添加,不添加可能乱码,如果后台返回的格式里面有,那就没必要了!
代码:
const binaryData = []
binaryData.push(res.data)
// 获取blob链接
this.pdfUrl = window.URL.createObjectURL(new Blob(binaryData, { type: ‘application/pdf;charset=utf-8’ }))
window.open(this.pdfUrl)

pdf下载如下图:
在这里插入图片描述

代码如下:
this.pdfUrl = window.URL.createObjectURL(new Blob([res.data], { type: application/pdf;charset=utf-8 }))
const fname = 合同 // 下载文件的名字
const link = document.createElement(‘a’)
console.log(this.pdfUrl)
link.href = this.pdfUrl
link.setAttribute(‘download’, fname)
document.body.appendChild(link)
link.click()
代码:
export default {
  name: 'pdf',
  async mounted () {
    this.pdfHeight = '100%'
    this.ewpId = this.$route.query.ewpId
    this.pdfUrl = await this.getPdf(this.baseUrl + '/rcgl/TalPolicy/onlinePreview?id=' + this.ewpId + '&BDSOFT-TOKEN=' + this.userToken)
  },
  data () {
    return {
      baseUrl: process.env.VUE_APP_BASE_API,
      pdfUrl: '',
      ewpId: '',
      pdfHeight: 0
    }
  },
  methods: {
    async getPdf (url) {
      // eslint-disable-next-line no-undef
      const data = await axios.get(url, {
        responseType: 'arraybuffer'
      })
      const blob = new Blob([data.data], { type: 'application/pdf' })
      return URL.createObjectURL(blob)
    }
  },
  computed: {
    ...mapState('global', {
      userToken: state => state.token,
      unitId: state => state.userInfo.b00
    })
  }
}

二、后端方式解决:

因为有的文件可能含有中文,因此在文件传输过程中会涉及到编码问题。后台的代码需要将输出流的编码格式设置为UTF-8。

response.setContentType("application/octet-stream;charset=UTF-8");

另一种方式就是:(优先级最高)

response.setCharacterEncoding("UTF-8"); // 设置文件流编码格式 不然中文会乱码

这样前端接收到输出流的时候是以Blob类型接收的。

代码:
 @Override
    public void onlinePreview(String filePath, HttpServletResponse response) throws Exception {
        //获取文件类型
        String[] str = filePath.split("\\.");
        if (str.length == 0) {
            throw new Exception("文件格式不正确");
        }
        String suffix = str[str.length - 1];
        if (!suffix.equals("txt") && !suffix.equals("doc") && !suffix.equals("docx") && !suffix.equals("xls")
                && !suffix.equals("xlsx") && !suffix.equals("ppt") && !suffix.equals("pptx")) {
            throw new Exception("文件格式不支持预览");
        }
        InputStream in = FileConvertUtil.convertLocaleFile(filePath, suffix);
        response.setContentType("application/octet-stream;charset=UTF-8");
        OutputStream outputStream = response.getOutputStream();
        //创建存放文件内容的数组
        byte[] buff = new byte[1024];
        //所读取的内容使用n来接收
        int n;
        //当没有读取完时,继续读取,循环
        while ((n = in.read(buff)) != -1) {
            //将字节数组的数据全部写入到输出流中
            outputStream.write(buff, 0, n);
        }
        //强制将缓存区的数据进行输出
        outputStream.flush();
        //关流
        outputStream.close();
        in.close();

    }

三、文件预览实现

controller 代码

@ApiOperation(value = "系统文件在线预览", notes = "系统文件在线预览")
    @GetMapping(Urls.TalPolicy.onlinePreview)
    public void onlinePreview(String id, HttpServletResponse  response) throws Exception {
        Assert.notNull(id, "用户id不能为空");
        TalPolicy Policy = TalPolicyService.getAllById(id);
        if (Policy != null) {
            String fid = Policy.getFileid();
            if (!StringUtils.isEmpty(fid)) {
                SAttachmentFile sAttachmentFile = fileManagerService.getById(fid);
                String filePath = sAttachmentFile.getFilepath();
                TalPolicyService.onlinePreview(filePath, response);
            }
        }
    }

service 代码

void onlinePreview(String filePath, HttpServletResponse  response) throws Exception;

serviceimpl代码

 @Override
    public void onlinePreview(String filePath, HttpServletResponse response) throws Exception {
        //获取文件类型
        String[] str = filePath.split("\\.");
        if (str.length == 0) {
            throw new Exception("文件格式不正确");
        }
        String suffix = str[str.length - 1];
        if (!suffix.equals("txt") && !suffix.equals("doc") && !suffix.equals("docx") && !suffix.equals("xls")
                && !suffix.equals("xlsx") && !suffix.equals("ppt") && !suffix.equals("pptx")) {
            throw new Exception("文件格式不支持预览");
        }
        InputStream in = FileConvertUtil.convertLocaleFile(filePath, suffix);
        response.setContentType("application/octet-stream;charset=UTF-8");
        OutputStream outputStream = response.getOutputStream();
        //创建存放文件内容的数组
        byte[] buff = new byte[1024];
        //所读取的内容使用n来接收
        int n;
        //当没有读取完时,继续读取,循环
        while ((n = in.read(buff)) != -1) {
            //将字节数组的数据全部写入到输出流中
            outputStream.write(buff, 0, n);
        }
        //强制将缓存区的数据进行输出
        outputStream.flush();
        //关流
        outputStream.close();
        in.close();

    }

工具类及其他详情步骤参考:
java用openOffice实现在线预览

四、点击按钮打开新窗口预览

 <el-table-column
          label="操作"
          align="center"
          width="120px">
          <template slot-scope="scope">
            <div style="line-height: 1; font-size: 0;">
              <el-button size="mini" @click="prewelRow(scope.row)">查看</el-button>
            </div>
          </template>
        </el-table-column>
data () {
    return {
      baseUrl: process.env.VUE_APP_BASE_API
      }
      },
computed: {
    ...mapState('global', {
      userToken: state => state.token,
      unitId: state => state.userInfo.b00
    })
  }
methods: {
 prewelRow: async function (row) {
      const pdfUrl = await this.getPdf(this.baseUrl + '/rcgl/TalPolicy/onlinePreview?id=' + row.recordid + '&TOKEN=' +   	   		this.userToken)
      window.open(pdfUrl)
    },

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/405961.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在vue中实现文件预览功能

文件流 如何将各种文件的文件流(blob)转化为线上可以直接预览的数据&#xff0c;这里简单介绍四种不同类型的文件预览。分别是pdf&#xff0c;docx&#xff0c;xlsx&#xff0c;jpg/png/jpeg等。有一个事情是需要重点注意的&#xff0c;文件流必须保证能够被正常下载解析后才可…

前端使用jswebrtc实现视频流播放

JSWebrtc对浏览器的Webrtc做了简单的封装,支持SRS的RTC流的播放. html代码: JSWeb播放器可以通过HTML创建,只需给指定元素添加CSS样式 jswebrtc即可: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta na…

猿创征文|我的前端——【HTML5】基础成长学习之路

文章目录 前言 一、网页的基本组成 1.什么是网页 2.什么是HTML 3.网页的形成 二、常用的浏览器 1.常用的浏览器 2.浏览器内核 三、Web标准 1.为什么需要web标准 2.Web标准的构成 前言 在一次机缘巧合之下了解并接触到CSDN&#xff0c;从此开启了我IT学习之路&#x…

API 低代码开发:接口大师,一套开发、管理和提供接口的产品框架

目录 一、简介 二、“器”有所用 三、“三大”平台/系统使用手册 ⭐️1、API接口系统手册⭐️ 访问在线接口 在线接口文档列表 接口文档详情页 搜索接口 ⭐️2、Platform开放平台手册⭐️ 访问开放平台 注册并登录开发者账号 创建应用 查看接口权限 调用开发接口 获…

uniCloud使用

uni-app 是是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;开发者编写一套代码&#xff0c;可发布到iOS、Android、Web&#xff08;响应式&#xff09;、以及各种小程序&#xff08;微信/支付宝/百度/头条/QQ/钉钉/淘宝&#xff09;、快应用等多个平台。 1 创建uni-app项…

前端获取mac地址

1.通过getMac库获取mac地址 通过getMac库来获取&#xff1a;getmac - npmGet the MAC address of the current machine you are on.. Latest version: 5.20.0, last published: a year ago. Start using getmac in your project by running npm i getmac. There are 201 other…

CSS 如何实现文字渐变色 ?

CSS 实现文字渐变色 CSS 实现文字渐变&#xff0c;有两种方法&#xff1a; 1. background 属性 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><style>.text-gradient {background-image: linear-gradien…

【微信小程序】WXSS和全局、页面配置

&#x1f352;观众老爷们好呀&#xff0c;小程序系列更新&#xff0c;上文我们讲解了小程序中WXML 中的条件渲染和列表渲染&#xff0c;那么接下来&#xff0c;就让我们走进微信小程序的WXSS以及小程序配置吧&#xff01; &#x1f352;今天的内容也是非常重要&#xff0c;赶紧…

8种css居中实现的详细实现方式了

这是一篇关于居中对齐方式的总结 开篇之前&#xff0c;先问一下大家都知道几种居中的实现方式&#xff1f; 面试时答出来两三个就不错了&#xff0c;就怕面试官还让你继续说。今天就来总结一下这些居中的方式 使用flex布局设置居中。使用flex 时也能通过给子项设置margin: au…

VUE-CLI/VUE-ROUTER

个人简介 > &#x1f4e6;个人主页&#xff1a;是Lay的主页 > &#x1f3c6;学习方向&#xff1a;JAVA后端开发 > &#x1f4e3;种一棵树最好的时间是十年前&#xff0c;其次是现在&#xff01; > ⏰往期文章&#xff1a;【Java基础】面向对象进阶(二) > &…

前端向后端传值的几种方式总结

一、HTML的标签form表单提交&#xff08;常用&#xff09; from表单把所有属于表单中的内容提交给后台&#xff0c;例如输入框&#xff0c;单选框&#xff0c;多选框&#xff0c;文本域&#xff0c;文件域等。 在后台可通过对应的name属性获取相应的值。from表单中的action属性…

vue踩坑--background-image路径问题

在前端开发中&#xff0c;background-image属性非常常见&#xff0c;有很多时候需要使用内联样式来绑定此属性&#xff0c;但是在vue项目中&#xff0c;如果如下面代码填写路径会找不到图片 项目中图片都放在src/img文件夹&#xff0c;img和background-image引用都用相对路径&a…

农业病虫害数据集与算法——调研整理

整理自博客 农业病虫害研究图库 陈雷&#xff1b;袁媛.农业病虫害研究图库.(V1).中国科学院合肥物质科学研究院[创建机构],2021-10-27.国家基础学科公共科学数据中心[发布机构],CSTR:16666.11.nbsdc.feoakuia;http://resolve.pid21.cn/CSTR:16666.11.nbsdc.feoakuia 下载链接&…

火狐浏览器谷歌浏览器Edge浏览器修改默认UA(User-Agent)

1.火狐浏览器&#xff08;Firefox) 1.1 使用浏览器设置进行修改 1&#xff09;在火狐浏览器地址栏输入“about:config”&#xff0c;按下回车进入设置菜单 2&#xff09;输入并找到“general.useragent.override”&#xff0c;选择”字符串“选项&#xff0c;再点击右侧的➕…

Openlayers 快速上手教程

&#x1f4e2;欢迎点赞&#x1f44d;/ 收藏⭐/ 留言&#x1f4dd;如有错误敬请指正&#xff01; 1. Openlayers简介 Openlayers 是开源的前端地图框架&#xff0c;官网地址&#xff1a;https://openlayers.org/ 它的作用主要是用于展现数据并且提供相应的地图操作工具。 1.1 …

SpringCloud 分布式微服务架构

SpringCloud 分布式架构前言SpringCloud微服务单体架构和微服务分布式架构单体架构分析微服务分布式架构分析服务拆分和远程调用服务拆分 案例需求准备远程调用初步Eureka注册中心服务注册与负载均衡服务注册Ribbon负载均衡指定负载均衡规则Nocas 注册中心环境配置启动服务注册…

vue3+动态路由

动态路由&#xff0c;也就是不是写死的路由&#xff0c;根据自己的需求加载不同的页面&#xff1b;现在很多的后台管理项目就是根据用户角色的不同分配不同的功能菜单&#xff08;页面&#xff09;&#xff1b; 根据用户登录的角色返回可以访问的页面路由&#xff0c;前端将路由…

JSON parse error: Cannot deserialize value of type `java.util.Date` from String

DateTimePicker DateTimeFormat("yyyy-MM-dd HH:mm:ss")日期格式转换异常 最近在学习,练习一个项目使用的日期格式是yyyy-MM-dd HH:mm:ss格式的,在后端Java与MySQL这边的转换中一开始格式没有统一间歇性的就会报异常,后面采用了一个DateTimeFormat("yyyy-MM-d…

vue组件的动态加载

​ 平常的vue项目开发&#xff0c;已经很难遇见一千行&#xff0c;甚至几千行代码的页面了&#xff0c;毕竟大家都会去拆分组件。但如果一个页面需要通过十几个组件或者几十个组件中的某几个组件去排列组合渲染&#xff0c;此时用动态加载就很有必要了。 ​ 我自己在开发过程中…

v-if与v-for为什么不建议一起使用?

1、作用 v-if指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回true值的时候被渲染。 v-for指令基于一个数组来渲染一个列表。v-for指令需要使用item in items 形式的特殊语法&#xff0c;其中items是源数据数组或者对象&#xff0c;而item则是被迭代的数组元素的…