分享

后端返回PDF文件流,前端处理展示及打印

 hncdman 2023-02-14 发布于湖南

版权

国庆突如其来的加班q.q,上午接到的需求,只能起床啦

自己也是第一次接触这种业务需求,进行了一顿cv大法,网上有很多版本,个人学习借鉴(cv)了一下,在这里做个学习记录,欢迎各位指正优化,参考学习,如有侵权立即删除。

printDialog.vue(PDF使用弹窗展示,确认btn打印)

HTML

<template>

  <div>

    <el-dialog title="打印" :visible.sync="dialogVisible" width="50%">

        <div class="box">

          <pdf ref="pdf" :src="pdfUrl"></pdf>

        </div>

      <span slot="footer" class="dialog-footer">

        <el-button @click="dialogVisible = false">取 消</el-button>

        <el-button

          type="primary"

        @click="$refs.pdf.print()"

          >确 定</el-button

        >

      </span>

    </el-dialog>

  </div>

</template>

js

<script>

//插件vue-pdf-signature

import pdf from "vue-pdf-signature";

import CMapReaderFactory from "vue-pdf-signature/src/CMapReaderFactory.js";

export default {

    components: {

    pdf,

  },

  data() {

    return {

      dialogVisible: false,

      pdfUrl:''

    };

  },

  methods:{

      init(res){

          this.dialogVisible = true;

          this.getObjectURL(res)

      },

      // 将返回的文件流数据转换为url(data: 文件流数据)

    getObjectURL(data) {

      let url = null;

      let file = new Blob([data], { type: "application/pdf" });

      if (window.createObjectURL != undefined) {

        // 通用

        url = window.createObjectURL(file);

      } else if (window.webkitURL != undefined) {

        // 兼容谷歌

        try {

          url = window.webkitURL.createObjectURL(file);

        } catch (error) {}

      } else if (window.URL != undefined) {

        // 兼容其他

        try {

          url = window.URL.createObjectURL(file);

        } catch (error) {}

      }

      //这里是重点,将处理的url使用CMapReaderFactory方法在进行处理

      url = pdf.createLoadingTask({ url: url, CMapReaderFactory });

      // 将转化后url赋值

      this.pdfUrl = url;

    },

  }

};

</script>

父组件.vue(btn点击)

HTMl

<el-button size="small" type="primary" @click="subscriptionPrinting()"

          >打印</el-button>

//弹窗

<print-dialog ref="printDialog" ></print-dialog>

js

<script>

import printDialog from "./printDialog.vue";

export default {

  components: {

    printDialog,

  },

  methods:{

  subscriptionPrinting() {

      this.$http

        .get(

          `请求~~~`,

          {

            responseType: "blob",//这个必须带

          }

        )

        .then(({ data: res }) => {

          this.$refs['printDialog'].init(res);

        });

    },

  }

</script>

以上就是全部代码了,坑还是比较多的以下来进行总结

1.插件的使用

  使用的是vue-pdf-signature而不是vue-pdf,是因为vue-pdf在第一次正常打开会正常显示,第二次打开会显示空白,控制台会提示报错(Error during font loading: Failed to execute 'postMessage' on 'Worker': ArrayBuffer at index 0 is already detached),vue-pdf-signature是大佬针对vue-pdf出现的这一问题进行的改良版。细看可前往大佬链接~

vue-pdf踩坑指南_快进小树林的博客-CSDN博客

2.不显示中文

  通过引入CMapReaderFactory.js解决,但是引入会出现1所描述的问题,所以采用了vue-pdf-signature进行解决(崇拜大佬ing)

3.向后端请求解析失败问题(显示空白,控制台提示报错)

  在请求中添加{

             responseType: "blob",//这个必须带

            }即可解决。

  请求回的文件流所做的数据处理在上面代码有注释,详看翻上

4.打印调用$refs.pdf.print()即可。

————————————————

版权声明:本文为CSDN博主「荒芜 i」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/zsz_1309297338/article/details/127185435

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多