Vue3 实现 PDF 预览与下载 缩放 上一页和下一页 放大和 缩小 功能

标题:Vue3 实现 PDF 预览与下载功能

在现代的 Web 应用程序中,PDF 文件是一种非常常见的文件格式,因为它在多个平台和设备上都能保持一致的文档格式,并且不易受病毒攻击。因此,在许多项目中实现 PDF 预览和下载功能是非常必要的。本文将介绍如何使用 Vue3 和 PDF.js 实现 PDF 预览和下载功能。

PDF 预览功能的实现

在本次教程中,我们将使用 Vue3 和 vue-pdf-embed 插件来实现 PDF 预览功能。vue-pdf-embed 是一个基于 PDF.js 的 Vue 组件库,可以轻松嵌入 PDF 文件并进行预览。

首先,我们需要安装 vue-pdf-embed vue3-pdfjs 依赖:

npm install [email protected]

npm install [email protected]

接着,在 Vue3 组件中引入 vue-pdf-embed 并定义 PDF 预览的相关参数:

<template>
  <a-spin :spinning="state.loading" tip="加载中...">
    <div class="pdf-preview">
      <div class="pdf-wrap">
        <vue-pdf-embed
          :page="state.pageNum"
          :source="state.source"
          :style="scale"
          class="vue-pdf-embed"
        />
      div>
      <div class="page-tool">
        <div class="page-tool-item" @click="lastPage">上一页div>
        <div class="page-tool-item" @click="nextPage">下一页div>
        <div class="page-tool-item">
          {{ state.pageNum }}/{{ state.numPages }}
        div>
        <div class="page-tool-item" @click="pageZoomOut">放大div>
        <div class="page-tool-item" @click="pageZoomIn">缩小div>
        <div class="page-tool-item" @click="downloadPDF">下载div>
      div>
    div>
  a-spin>
template>
<script lang="ts" setup>
import VuePdfEmbed from "vue-pdf-embed";
import { createLoadingTask } from "vue3-pdfjs";

import { reactive, onMounted, computed } from "vue";

const props = defineProps({
  pdfUrl: {
    type: String,
    required: true,
  },
});

const state = reactive({
  source: props.pdfUrl, // 预览pdf文件地址
  pageNum: 1, //当前页面
  scale: 1, // 缩放比例
  numPages: 0, // 总页数
  loading: "",//加载效果
});
// 下载pdf
function downloadPDF() {
  fetch(encodeURI(props.pdfUrl)).then((res) => {
    res.blob().then((myBlob) => {
      const href = URL.createObjectURL(myBlob);
      const a = document.createElement("a");
      a.href = href;
      a.download = "report.pdf"; // 下载文件重命名,并指定文件扩展名为 ".pdf"
      document.body.appendChild(a); // 将元素添加到文档中,以便进行点击下载
      a.click();
      document.body.removeChild(a); // 下载完成后移除元素
    });
  });
}

onMounted(() => {
  const loadingTask = createLoadingTask(state.source);
  state.loading = true; // 添加一个loading状态
  loadingTask.promise.then((pdf: { numPages: number }) => {
    state.numPages = pdf.numPages;
    state.loading = false; // 加载完成后将loading状态设置为false
  });
});

const scale = computed(() => `transform:scale(${state.scale})`);

function lastPage() {
  if (state.pageNum > 1) {
    state.pageNum -= 1;
  }
}

function nextPage() {
  if (state.pageNum < state.numPages) {
    state.pageNum += 1;
  }
}

function pageZoomOut() {
  if (state.scale < 2) {
    state.scale += 0.1;
  }
}

function pageZoomIn() {
  if (state.scale > 1) {
    state.scale -= 0.1;
  }
}
script>
<style lang="css" scoped>
.pdf-preview {
  position: relative;
  height: 100%;
  padding: 20px 0;
  box-sizing: border-box;
  background-color: #e9e9e9;
}

.pdf-wrap {
  overflow-y: auto;
}

.vue-pdf-embed {
  text-align: center;
  width: 515px;
  border: 1px solid #e5e5e5;
  margin: 0 auto;
  box-sizing: border-box;
}

.page-tool {
  position: absolute;
  bottom: 35px;
  padding-left: 15px;
  padding-right: 15px;
  display: flex;
  align-items: center;
  background: rgb(66, 66, 66);
  color: white;
  border-radius: 19px;
  z-index: 100;
  cursor: pointer;
  margin-left: 50%;
  transform: translateX(-50%);
}

.page-tool-item {
  padding: 8px 15px;
  padding-left: 10px;
  cursor: pointer;
}
style>

父组件使用

 <PdfPreview v-if="data && data.content" :pdfUrl="data.content" />

代码解释:

使用 组件来进行 PDF 预览;
使用组件参数 :source 来定义 PDF 文件的地址;
使用组件参数 :page 来定义当前预览页码;
使用组件参数 :style 来定义文档缩放比例;
定义 downloadPDF() 函数用于下载 PDF 文件;
在 onMounted() 钩子函数中使用 createLoadingTask() 方法加载 PDF 文件,并获取总页数;
使用 reactive 创建响应式数据,包括 PDF 文件地址、当前页码、缩放比例和总页数;
使用计算属性 scale 计算文档缩放比例;
定义函数 lastPage() 和 nextPage() 用于实现页面翻页功能;
定义函数 pageZoomIn() 和 pageZoomOut() 用于实现文档缩放功能。
PDF 下载功能的实现

在上面的代码中,我们已经编写了 downloadPDF() 函数,用于实现 PDF 文件的下载。该函数使用 fetch 获取文件数据并将其转换为 blob 对象,然后创建一个 标签并设置其 href 属性为 blob 对象的 URL,最后在文档中插入该标签并模拟点击该标签以实现下载。

你可能感兴趣的:(vue,vue.js,javascript,前端,pdf)