# PDF预览

# 开始

有一个列表,每一项都是一个pdf,现在需要下载和预览功能。

# 实现预览vue-pdf版本(可能有跨域问题)

<template>
  <sweet-modal ref="previewRef" id="preview">
    <div class="doc-webhook-pdf">
      <BaseLoading :showLoading="onProgress<100"></BaseLoading>
      <div class="show-pdf">
        <pdf
             ref="apiPdf"
             v-for="i in numPages"
             :key="i"
             :page="i"
             :src="src">
        </pdf>
      </div>
    </div>
  </sweet-modal>
</template>
import pdf from 'vue-pdf/src/vuePdfNoSss';
import BaseLoading from 'component/loading/base-loading';

export default {
  components: {
    pdf,
    BaseLoading,
  },
  data() {
    return {
      src: '',
      onProgress: 0,
      numPages: undefined,
    };
  },
  props: {},
  computed: {},
  watch: {},
  methods: {
    // 下载pdf方式 展示pdf
    open(id) {
      this.clear();
      this.$refs.previewRef.open();
      try {
        this.$http.post("/api/company/bill/download", {
          id,
        }, {
          responseType: 'blob'
        }).then((res) => {
          let url = this.getObjectURL(res);
          this.showPDF(url)
          return;
        });
      } catch (error) {
        console.error('error: ', error);
      }
    },
    // 转化 文件流=>URL
    getObjectURL(file) {
      var binaryData = [];
      binaryData.push(file);
      let url = null;
      if (window.createObjectURL !== undefined) { // basic
        url = window.createObjectURL(new Blob(binaryData, {
          type: 'application/pdf'
        }));
      } else if (window.webkitURL !== undefined) { // webkit or chrome
        try {
          url = window.webkitURL.createObjectURL(new Blob(binaryData, {
            type: 'application/pdf'
          }));
        } catch (error) {}
      } else if (window.URL !== undefined) { // mozilla(firefox)
        try {
          url = window.URL.createObjectURL(new Blob(binaryData, {
            type: 'application/pdf'
          }));
        } catch (error) {}
      }
      return url;
    },
    // 展示pdf
    showPDF(url) {
      setTimeout(() => {
        this.src = new pdf.createLoadingTask(url, {
          onProgress: this.handleProgress,
        });
        this.src.promise.then(pdf => {
          this.numPages = pdf.numPages;
        });
      }, 100)
    },
    // 清除操作,重置参数
    clear() {
      this.src = ''
      this.onProgress = 0
      this.numPages = undefined
    },
    // 进度
    handleProgress(e) {
      const {
        loaded,
        total
      } = e
      this.onProgress = +Number(loaded / total * 100).toFixed(1)
    },
    // 关闭弹窗
    close() {
      this.$refs.previewRef.close();
    },
  },
  created() {},
  mounted() {}
}

#preview {
  .sweet-modal {
    max-height: 600px;
    overflow-y: scroll;
  }

  .doc-webhook-pdf {
    position: relative;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .show-pdf {
    width: 100%;
    height: 100%;
  }
}

# 实现下载PDF

function downFile(res, fileName) {
  const blob = new Blob([res], {
    type: `application/pdf;charset=UTF-8`
  });

  if (window.navigator.msSaveOrOpenBlob) {
    // 兼容ie11
    window.navigator.msSaveOrOpenBlob(blob, fileName);
  } else {
    const url = URL.createObjectURL(blob);
    const downloadElement = document.createElement("a");
    downloadElement.href = url;
    downloadElement.download = fileName;
    document.body.appendChild(downloadElement);
    downloadElement.click();
    downloadElement.remove();
    URL.revokeObjectURL(url);
  }
}

this.showLoading = true;
try {
  this.$http.post("/api/company/bill/download", {
    id,
  }, {
    responseType: 'blob'
  }).then((res) => {
    this.showLoading = false;
    downFile(res, `${bill_no}.pdf`)
    return;
  });
} catch (error) {
  console.error('error: ', error);
}

# 实现预览iframe版本

<template>
  <sweet-modal ref="previewRef" id="preview">
    <div class="doc-pdf">
      <div class="show-pdf">
        <iframe :src="src" frameborder="0" style="width: 100%; height: 100%"></iframe>
      </div>
    </div>
  </sweet-modal>
</template>
import BaseLoading from 'component/loading/base-loading';

export default {
components: {
BaseLoading,
},
data() {
return {
src: '',
};
},
props: {},
computed: {},
watch: {},
methods: {
open(id) {
// 通过id获取pdf文件流
// 文件流转URl
// '#toolbar=0'隐藏iframe的控制功能,比如下载、缩放等
this.src = ''
this.$refs.previewRef.open();
try {
this.$http.post("/api/company/bill/download", {
id,
}, {
responseType: 'blob'
}).then((res) => {
let url = URL.createObjectURL(res);
this.src = url + '#toolbar=0'
return;
});
} catch (error) {
console.error('error: ', error);
}
},
/*------------------------ 关闭 ----------------------------*/
close() {
this.$refs.previewRef.close();
},
},
created() {},
mounted() {}
}
#preview {
  .sweet-modal {
    max-height: 600px;
    overflow-y: scroll;
  }

  .doc-pdf {
    position: relative;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .show-pdf {
    width: 100%;
    height: 500px;
  }
}