前端局部导出PDF(非图片,可编辑)功能,iframe无感预览,部署在qiankun微前端主应用里也适用√

1 篇文章 0 订阅

前端局部导出PDF(非图片,可编辑)功能,iframe无感预览,部署在qiankun主应用里也适用√

1、使用windows.print()
2、待导出部分放在隐藏的iframe里面,达到无感预览的交互体验
3、需要考虑部署在qiankun主应用中样式丢失的问题


有【导出pdf】按钮的页面
<template>
  <div>
    <iframe
      id="frame"
      :src="getPath"
      ref="iframe"
      style="display: none"
    ></iframe>
  </div>
</template>
<script>
  export default {
    name: 'ApiDialog',
    data() {
      return {
        multipleSelection: [],
      }
    },
    mounted() {
      window.addEventListener('message', (e) => {
        let data = e.data
        if (data.key === '咩哈哈') {
          //刷新iframe
          this.$refs.iframe.contentWindow.location.reload(true)
        }
      })
    },
    computed: {
      getPath() {
        let _path = window.location.href
        _path = _path.replace('open-api', 'preview-pdf')
        return _path
      },
    },
    methods: {
      previewPdf() {
        if (this.multipleSelection.length === 0) {
          this.$message.warning('请选择要预览的数据!')
        } else {
          this.$refs.iframe.contentWindow.postMessage(
            {
              key: '啦啦啦',
              params: {
                // 传过去的值
                previewList: JSON.stringify(this.multipleSelection),
              },
            },
            '*'
          )
        }
      },
    },
  }
</script>

待导出为pdf的页面
<template>
  <div>
    <!--startprint-->
    <div
      v-for="(item, index) in previewList"
      :key="index"
      style="padding-left: 20px; line-height: 1.2"
    >
      <div>
        <h3>
          {{ index + 1 }}.&nbsp;&nbsp;{{ item.apiName }}
        </h3>
      </div>
      <p>所属服务:{{ item.serviceName }}</p>
      <p>接口描述:{{ item.apiDesc }}</p>
      <p>接口路径:{{ item.apiPath }}</p>
      <p>
        接口类型:
        <span
          class="ct-tag"
          :style="{ background: getRequestTypeColor(item.apiMethod) }"
        >
          {{ item.apiMethod }}
        </span>
      </p>
      <p>接口入参:-</p>
      <p>接口反参:-</p>
      <el-divider></el-divider>
    </div>
    <!--endprint-->
  </div>
</template>
<script>
  import { getRequestTypeColor } from '@/mapping'
  export default {
    name: 'PreviewPdf',
    props: {},
    data() {
      return {
        getRequestTypeColor,
        previewList: [],
      }
    },
    created() {},
    mounted() {
      window.addEventListener(
        'message',
        (e) => {
          let data = e.data
          if (data.key === '啦啦啦') {
            //iframe不接收[object array],所以需要转成字符串传递
            this.previewList = JSON.parse(data.params.previewList)
            this.$nextTick(() => {
              this.doPrint()
              window.parent.postMessage(
                {
                  key: '咩哈哈',
                },
                '*'
              )
            })
          }
        },
        false
      )
    },
    methods: {
      doPrint() {
        //为了匹配qiankun主应用(其实是主应用强制加的layout,没有考虑到子应用某些场景不需要主应用layout例如子应用的有些页面需要全屏or打印的需求),直接替换的话打包出来的自定义css也会被替换掉,
        //应该有更好的解决方法,因为el-tag什么的样式也不生效,偷懒自己重写了个tag样式
        //另外这个正则表达式会使ide报红= =。
        let reg = /<div id="__qiankun_microapp(([\s\S])*?)<\/style><\/div>/g
        let html = window.document.body.innerHTML
        let arr = html.match(reg)
        if (arr) {
          window.document.body.innerHTML = arr[0]
          window.print()
        } else {
          //因为在子应用的页面路由里给它配了一份左侧菜单(layout),如果不配的话只用下面两行就可以了:
          //window.document.body.innerHTML=html
          //window.print()
          let bdhtml = html
          const sprnstr = '<!--startprint-->'
          const eprnstr = '<!--endprint-->'
          let prnhtml = bdhtml.substr(bdhtml.indexOf(sprnstr) + 17)
          prnhtml = prnhtml.substring(0, prnhtml.indexOf(eprnstr))
          window.document.body.innerHTML = prnhtml
          window.print()
        }
      },
    },
  }
</script>

<style lang="scss" media="print" scoped>
  .ct-tag {
    color: white;
    border-radius: 4px;
    display: inline-block;
    height: 24px;
    padding: 0 8px;
    line-height: 22px;
    font-size: 12px;
    //使打印时的背景色生效
    -webkit-print-color-adjust: exact;
  }
</style>
有帮助的话点个赞再走吧~ 也可以加我一起讨论学习鸭o( ̄▽ ̄)ブ

请添加图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值