Как реализовать предварительный просмотр pdf-файла в vue?

внешний интерфейс сервер JavaScript Vue.js

Сегодня продукт предлагает требование оптимизации, то есть отображение изображения, которое мы делали раньше, было выполнено с тегом img.Поскольку мы делаем зарубежную систему управления фоном, файлы, загруженные людьми, находятся в формате pdf, а Vue не поддерживает этот формат.Файл отображается, поэтому я поискал в гугле и обнаружил, что есть iframe, embed, vueshowpdf (тест не прост в использовании), pdf и т. д. В этой статье рассказывается о процессе использования pdf плагин.

  • Описание: Тег iframe подходит для некоторых ссылок. Например, эта ссылка может отображаться напрямую, без установки заголовка содержимого на стороне сервера, как показано ниже:


Хотите скопировать код следующим образом:

<iframe src="http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf" width="100%" height="100%">
       This browser does not support PDFs. Please download the PDF to view it: <a href="/test.pdf">Download PDF</a>
</iframe>

Эффект отображения следующий:


Если в pdf много страниц, то функцию листания рассматривать не нужно, можно автоматически листать страницы свайпом вниз, выглядит неплохо, но продолжим читать ----->

Давайте заменим ссылку выше на 'https://ecs7.tokopedia.net/instant-loan/file/29a2218e-bef9-44cb-b92b-8e81bc4d5228_DOC-20171013-WA0035.pdf', что ты нашел? Посмотрите на скриншот. . . Это же ссылка на pdf, как это может не работать?


Какова ситуация? Окно загрузки должно быть загружено, прежде чем вы сможете его увидеть. Это сильно повлияет на опыт и займет мой диск при локальной загрузке. Нет, нет, нет, нет, нет, нет, нет-нет, вставьте ссылку выше в браузер, и нажмите Enter, чтобы увидеть заголовок ответа:

content-disposition:attachment; filename="DOC-20171013-WA0035.pdf"

Вот и все, мы должны открыть окно загрузки, потому что эти файлы хранятся на удаленном сервере, думая о том, чтобы позволить бэкэнду увидеть, могут ли они обнаружить этот заголовок ответа, им лень с этим бороться, и тогда они могут только разберитесь с этим сами, ввиду этого В этом случае в интернете есть много решений, и я их протестировал. Я также позаимствовал статью в середине и сделал простую обработку в соответствии со своими потребностями.

https://www.2cto.com/kf/201803/728492.html 

Процесс выглядит следующим образом:

  1. Выполнить npm install pdf-dist --save
  2. Создайте два файла в каталоге комментариев: pdf.vue и index.js.

<!-- pdf.vue -->

<template>      <div id="container" :class="{'back': isShow}">      <canvas id="the-canvas"></canvas>      <!-- //添加关闭pdf功能 -->      <span :class="{'close':isShow}" @click="closePdf">close</span>      <p class="foot" v-if="pdfDoc">        <Button class="left" @click="onPrevPage" v-if="pageNum>1">上一页</Button>        <Button class="right" @click="onNextPage" v-if="pageNum<pdfDoc.numPages">下一页</Button>      </p>      </div>  </template><script>import PDFJS from 'pdfjs-dist' export default {  data () {    return {      isShow: false,//通过该属性动态添加类,让pdf显示或隐藏      pdfDoc: null,//可以打印发现是一个对象,里面有页数信息等      pageNum: 1,      pageRendering: false,      pageNumPending: null,      scale: 0.9    }  },  methods: {    closePdf(){      this.isShow = false    },    showPDF (url) {      this.isShow = true      let _this = this      PDFJS.getDocument(url).then(function (pdf) {        _this.pdfDoc = pdf        _this.renderPage(1)      })    },    renderPage (num) {      this.pageRendering = true      let _this = this      this.pdfDoc.getPage(num).then(function (page) {        var viewport = page.getViewport(_this.scale)        let canvas = document.getElementById('the-canvas')        canvas.height = viewport.height        canvas.width = viewport.width        // Render PDF page into canvas context        var renderContext = {          canvasContext: canvas.getContext('2d'),          viewport: viewport        }        var renderTask = page.render(renderContext)         // Wait for rendering to finish        renderTask.promise.then(function () {          _this.pageRendering = false          if (_this.pageNumPending !== null) {            // New page rendering is pending            this.renderPage(_this.pageNumPending)            _this.pageNumPending = null          }        })      })    },    queueRenderPage (num) {      if (this.pageRendering) {        this.pageNumPending = num      } else {        this.renderPage(num)      }    },    onPrevPage () {      if (this.pageNum <= 1) {        return      }      this.pageNum--      this.queueRenderPage(this.pageNum)    },    onNextPage () {      if (this.pageNum >= this.pdfDoc.numPages) {        return      }      this.pageNum++      this.queueRenderPage(this.pageNum)    }  }}</script><style scoped="" type="text/css">.back {  background-color: rgba(0, 0, 0, 0.788);  position:fixed;  width: 100%;  height: 100%;  top: 0;  left: 0;  text-align: center;  padding: 20px;  z-index: 100;  overflow: scroll;}.close{  position: absolute;  right: 20px;  top: 20px;  z-index: 200;  color: #fff;  cursor: pointer;} .foot {  position: absolute;  bottom: 50px;  left: 50%;  transform: translate(-50%,0);}</style>

// index.jsimport PDF from './pdf' var $vmexport default {  install (Vue, options) {    if (!$vm) {      const PDFPlugin = Vue.extend(PDF)      $vm = new PDFPlugin().$mount()      document.body.appendChild($vm.$el)    }    Vue.prototype.$showPDF = function (url) {      $vm.showPDF(url)    }  }}

3. Ввести в main.js

import pdf from './components/pdf'
Vue.use(pdf)

Таким образом, его можно использовать глобально, и его можно использовать напрямую, когда он используется.В этой статье событие щелчка добавляется в место, где отображается изображение, и функция может запускаться при нажатии;

function showPdf(){
      let url = 'http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf'        // let url = 'https://ecs7.tokopedia.net/instant-loan/file/29a2218e-bef9-44cb-b92b-8e81bc4d5228_DOC-20171013-WA0035.pdf'        this.$showPDF(url)}

В статье добавлена ​​функция закрытия.Нажмите закрыть, чтобы закрыть отображение PDF.В то же время в компоненте также есть функция подкачки.Если количество страниц больше 1, будет отображаться кнопка следующей страницы;


Вышеупомянутый процесс моей собственной реализации.Что касается кроссдоменной проблемы,то я с ней пока не сталкивался.Теперь есть возможность получить доступ локально.Посмотрю,работает ли онлайн.Если не работает, Я добавлю метод для его реализации позже.

     

Скажи своему дорогому я накапливать понемногу каждый день и позволять себе постоянно расти! ! ! !