前端实现文件预览(pdf、excel、word、图片)

前端实现文件预览(pdf、excel、word、图片)前端实现文件预览功能需求 实现一个在线预览 pdf excel word 图片等文件的功能 介绍 支持 pdf xlsx docx jpg png jpeg 以下使用 Vue3 代码实现所有功能 建议以下的预览文件标签可以在外层包裹一层弹窗

欢迎大家来到IT世界,在知识的湖畔探索吧!

前端实现文件预览功能

需求:实现一个在线预览pdf、excel、word、图片等文件的功能。
介绍:支持pdf、xlsx、docx、jpg、png、jpeg。
以下使用Vue3代码实现所有功能,建议以下的预览文件标签可以在外层包裹一层弹窗。

图片预览

iframe标签能够将另一个HTML页面嵌入到当前页面中,我们的图片也能够使用iframe标签来进行展示。

</code></pre><p data-track='7'><span style='letter-spacing: 1.5px;'><strong><u><span style='color: #26C6DA; --tt-darkmode-color: #26C6DA;'>sandbox</span></u></strong><u><span style='color: #2B2B2B; --tt-darkmode-color: #A3A3A3;'> </span></u><span style='color: #2B2B2B; --tt-darkmode-color: #A3A3A3;'>这个属性如果是单纯预览图片可以不使用,该属性对呈现在 iframe 框架中的内容启用一些额外的限制条件。属性值可以为空字符串(这种情况下会启用所有限制),也可以是用空格分隔的一系列指定的字符串。</span></span></p><li data-track='8'>allow-scripts: 允许嵌入的浏览上下文运行脚本(但不能创建弹窗)。如果没有使用该关键字,就无法运行脚本。</li><li data-track='9'>allow-top-navigation: 允许将框架内所加载页面中的超链接导航到父级窗口</li><li data-track='10'>allow-same-popups: 允许弹窗 (例如 window.open, target="_blank")。如果没有使用该关键字,相应的功能将自动被禁用。</li><li data-track='14'>allow-same-origin: 如果没有使用该关键字,嵌入的浏览上下文将被视为来自一个独立的源,这将使 same-origin policy 同源检查失败。使用了这个属性,那么当前页面和iframe打开的页面视为同源。</li><h1 class='pgc-h-arrow-right' data-track='15'>word文档预览(docx)</h1><pre class='syl-page-code'><code>先下载npm包
npm i docx-preview --save</code></pre><p class='pgc-p syl-page-br' data-track='16' style><br></p><pre class='syl-page-code'><code><div class='docxRef'></div>

&lt;script&gt;
import { renderAsync } from 'docx-preview';

function fn() {
// 这里的res.data是 blob文件流,如果自己的不是blob文件流
// 可以通过URL.createObjectURL(参数) 参数为File格式,转换为blob文件流
    let blob = res.data
    let childRef = document.getElementsByClassName('docxRef');
    renderAsync(blob, childRef[0]) //渲染
}
fn()

&lt;/script&gt;</code></pre><p data-track='18'><span style='letter-spacing: 1.5px;'><strong><u><span style='color: #26C6DA; --tt-darkmode-color: #26C6DA;'>blob文件流</span></u></strong></span></p><div class='pgc-img'><img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' img_width='732' img_height='222' image_type='1' mime_type='image/webp' web_uri='tos-cn-i-6w9my0ksvp/293a00be3c3f4a9f91bb9a2fab8178c3' class='syl-page-img syl-img-loading' style='height:0px;background:url(https://sf1-cdn-tos.toutiaostatic.com/obj/mp/syl-page/toutiaoicon_loading_textpage@3x.RQmcZRIc.png) no-repeat center center;width:732px;padding-bottom:30.33%' data-src='https://p3-sign.toutiaoimg.com/tos-cn-i-6w9my0ksvp/293a00be3c3f4a9f91bb9a2fab8178c3~tplv-tt-origin-web:gif.jpeg?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1741731714&x-signature=xpkLExdcZrxVBnuNHMFU%2BYBIl40%3D'><p class='pgc-img-caption'></p></div><h1 class='pgc-h-arrow-right' data-track='19'>预览excel文件(xlsx)</h1><pre class='syl-page-code'><code>下载包
npm install xlsx@0.16.0</code></pre><p class='pgc-p syl-page-br' data-track='20' style><br></p><pre class='syl-page-code'><code><div class='xlsxClass'></div>
const reader = new FileReader();
//通过readAsArrayBuffer将blob转换为ArrayBuffer对
reader.readAsArrayBuffer(res.data) // 这里的res.data是blob文件流
reader.onload = (event) =&gt; {
  // 读取ArrayBuffer数据变成Uint8Array
  var data = new Uint8Array(event.target.result);
  // 这里的data里面的类型和后面的type类型要对应
  var workbook = XLSX.read(data, { type: "array" });
  var sheetNames = workbook.SheetNames; // 工作表名称
  var worksheet = workbook.Sheets[sheetNames[0]];
  // var excelData = XLSX.utils.sheet_to_json(worksheet); //JSON
  let html = XLSX.utils.sheet_to_html(worksheet);
  document.getElementsByClassName('xlsxClass')[0].innerHTML = html
};</code></pre><h1 class='pgc-h-arrow-right' data-track='22'>pdf预览</h1><pre class='syl-page-code'><code>下载包 npm install pdfjs-dist
我使用的是npm install pdfjs-dist@2.0.943版本,以下例子使用的是vue3+vite创建的项目
以下例子通过canvas来渲染pdf</code></pre><p class='pgc-p syl-page-br' data-track='24' style><br></p><pre class='syl-page-code'><code><template>
  <div class='box'>
    <div class='tool-bar'>
      <div>{{ pdfParams.pageNumber }} / {{ pdfParams.total }}</div>
      <button type='primary' :disabled='pdfParams.pageNumber == pdfParams.total' click='nextPage'>下一页
      </button>
      <button type='primary' :disabled='pdfParams.pageNumber == 1' click='prevPage'>上一页</button>
    </div>
    <canvas id='pdf-render'></canvas>
  </div>
</template>
</code></pre><p class='pgc-p syl-page-br' data-track='26' style><br></p><pre class='syl-page-code'><code>&lt;script setup&gt;
import { onMounted, ref, reactive } from 'vue'
const pdfParams = reactive({
  pageNumber: 1, // 当前页
  total: 0, // 总页数
});

// 不要定义为ref或reactive格式,就定义为普通的变量
let pdfDoc = null;
// 这里必须使用异步去引用pdf文件,直接去import会报错,也不知道为什么
onMounted(async ()=&gt; {
  let pdfjs = await import('pdfjs-dist/build/pdf')
  let pdfjsWorker = await import('pdfjs-dist/build/pdf.worker.entry')
  pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker
  // 此文件位于public/test2.pdf
  let url = ref('/test2.pdf')
  pdfjs.getDocument(url.value).promise.then(doc =&gt; {
    pdfDoc = doc
    pdfParams.total = doc.numPages
    getPdfPage(1)
  })
})

// 加载pdf的某一页
const getPdfPage = (number) =&gt; {
  pdfDoc.getPage(number).then(page =&gt; {
    const viewport = page.getViewport()
    const canvas = document.getElementById('pdf-render')
    const context = canvas.getContext('2d')
    canvas.width = viewport.viewBox[2]
    canvas.height = viewport.viewBox[3]
    viewport.width = viewport.viewBox[2]
    viewport.height = viewport.viewBox[3]
    canvas.style.width = Math.floor(viewport.width) + 'px'
    canvas.style.height = Math.floor(viewport.height) + 'px'

    let renderContext = {
      canvasContext: context,
      viewport: viewport,
      // 这里transform的六个参数,使用的是transform中的Matrix(矩阵)
      transform: [1, 0, 0, -1, 0, viewport.height]
    }
    // 进行渲染
    page.render(renderContext)
  })
}
// 下一页功能
const prevPage = () =&gt; {
  if(pdfParams.pageNumber &gt; 1) {
    pdfParams.pageNumber -= 1
  } else {
    pdfParams.pageNumber  = 1
  }
  getPdfPage(pdfParams.pageNumber)
}
// 上一页功能
const nextPage = () =&gt; {
  if(pdfParams.pageNumber &lt; pdfParams.total) {
    pdfParams.pageNumber += 1
  } else {
    pdfParams.pageNumber = pdfParams.total
  }
  getPdfPage(pdfParams.pageNumber)
}
&lt;/script&gt;</code></pre><div class='pgc-img'><img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' img_width='735' img_height='704' image_type='1' mime_type='image/webp' web_uri='tos-cn-i-6w9my0ksvp/9348be49066049a39febf3f223783299' class='syl-page-img syl-img-loading' style='height:0px;background:url(https://sf1-cdn-tos.toutiaostatic.com/obj/mp/syl-page/toutiaoicon_loading_textpage@3x.RQmcZRIc.png) no-repeat center center;width:735px;padding-bottom:95.78%' data-src='https://p26-sign.toutiaoimg.com/tos-cn-i-6w9my0ksvp/9348be49066049a39febf3f223783299~tplv-tt-origin-web:gif.jpeg?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1741731714&x-signature=fYbGBiRTRuQzcQ6i5g0ma8oMQls%3D'><p class='pgc-img-caption'></p></div><p data-track='28'><strong>以上注意点:</strong></p><ul><li data-track='29'>必须异步引用pdf的文件!!!</li><li data-track='30'>pdf演示文件位于public/test2.pdf</li><li data-track='31'>transform: [1, 0, 0, -1, 0, viewport.height],使用了transform中的Matrix(矩阵)</li><li data-track='32'>下一页和上一页功能都需要重新渲染</li></ul><p data-track='34'><br><span>原文链接:<br>https://juejin.cn/post/7246609845272395837</span><br><br></p></article></div></div></div></div></div></div><div class="action"><div tabindex="0" role="button" aria-label="举报" class="detail-report"><i></i><span>举报</span></div></div><div style="margin:20px 0 40px"><div role="region" aria-label="评论区" class="ttp-comment-block"><div id="comment-area" class="ttp-comment-wrapper"><div class="title">评论 <span>0</span></div><div class="main-input"><div class="ttp-avatar auth-none"></div><div class="ttp-comment-input"><div class="login-mask"><p>请先<!-- --> <button>登录</button> <!-- -->后发表评论~</p></div></div></div><ul class="comment-list"></ul></div></div></div><div><div class="divide"></div></div><div class="show-monitor"><div><div role="region" aria-label="相关推荐" class="detail-end-feed"><div style="margin-top:20px"></div></div></div></div><div class="seo-hot-link-list"><span>热门:</span><ul><li><a href="https://www.douyin.com/qishui/playlist/7477846840843601955" target="_blank" title="此情可待损">此情可待损</a></li><li><a href="https://www.douyin.com/qishui/playlist/7477846840843536419" target="_blank" title="雪下的碎">雪下的碎</a></li><li><a href="https://www.douyin.com/qishui/playlist/7477846839808362511" target="_blank" title="三十三唱歌">三十三唱歌</a></li><li><a href="https://www.douyin.com/qishui/playlist/7477846849177520167" target="_blank" title="望春风东风破">望春风东风破</a></li><li><a href="https://www.douyin.com/qishui/playlist/7477846847898634251" target="_blank" title="数十字全集孝歌">数十字全集孝歌</a></li><li><a href="https://www.douyin.com/qishui/playlist/7477846846057596969" target="_blank" title="躲过雨的屋檐箫独奏">躲过雨的屋檐箫</a></li><li><a href="https://www.douyin.com/qishui/playlist/7477846846057531433" target="_blank" title="ttf是什么歌">ttf是什么歌</a></li><li><a href="https://www.douyin.com/qishui/playlist/7477846846057433129" target="_blank" title="宝宝哄睡神器曲 婴儿对话神器婴儿语">宝宝哄睡神器曲</a></li><li><a href="https://www.douyin.com/qishui/playlist/7477846842382944282" target="_blank" title="没有见你的理由">没有见你的理由</a></li><li><a href="https://www.douyin.com/qishui/playlist/7477846840843454499" target="_blank" title="高山十流水">高山十流水</a></li></ul></div></div><div class="right-sidebar"><div class="show-monitor"><div role="complementary" aria-label="作者信息" class="media-info"><div class="user-info"><a aria-label="作者头像" class="user-avatar" target="_blank" rel="noopener nofollow" href="/c/user/token/MS4wLjABAAAAdAGemQPKr9g83aKEjrKYLBdjrZWMq33xss8tSi7qOJ1yeSBAP0LIuKlzIEO-IR4V/?source=tuwen_detail&amp;entrance_gid=7283696265131590201"><img src="https://sf3-cdn-tos.toutiaostatic.com/img/user-avatar/241e45e63e4c1865e7ea6bf04f2a852a~300x300.image" alt="爱敲键盘的晓晓 头像"/></a><a class="user-name" target="_blank" rel="noopener nofollow" href="/c/user/token/MS4wLjABAAAAdAGemQPKr9g83aKEjrKYLBdjrZWMq33xss8tSi7qOJ1yeSBAP0LIuKlzIEO-IR4V/?source=tuwen_detail&amp;entrance_gid=7283696265131590201">爱敲键盘的晓晓</a><button aria-pressed="false" type="button" class="user-subscribe-wrapper"><i class="bui-icon icon-add_small"></i><span>关注</span></button></div><div class="related-title"><span>TA的热门作品</span></div><svg aria-labelledby="author-related-list-loading-aria" role="img" viewBox="0 0 308 470"><title id="author-related-list-loading-aria">Loading...</title><rect role="presentation" x="0" y="0" width="100%" height="100%" clip-path="url(#author-related-list-loading-diff)" style="fill:url(#author-related-list-loading-animated-diff)"></rect><defs role="presentation"><clipPath id="author-related-list-loading-diff"><rect x="5" y="16" rx="5" ry="5" width="96" height="72"></rect><rect x="113" y="20" rx="2" ry="2" width="180" height="10"></rect><rect x="114" y="40" rx="2" ry="2" width="120" height="10"></rect><rect x="5" y="110" rx="5" ry="5" width="96" height="72"></rect><rect x="113" y="114" rx="2" ry="2" width="180" height="10"></rect><rect x="114" y="134" rx="2" ry="2" width="120" height="10"></rect><rect x="5" y="204" rx="5" ry="5" width="96" height="72"></rect><rect x="113" y="208" rx="2" ry="2" width="180" height="10"></rect><rect x="113" y="228" rx="2" ry="2" width="120" height="10"></rect><rect x="5" y="296" rx="5" ry="5" width="96" height="72"></rect><rect x="113" y="300" rx="2" ry="2" width="180" height="10"></rect><rect x="113" y="320" rx="2" ry="2" width="120" height="10"></rect><rect x="5" y="388" rx="5" ry="5" width="96" height="72"></rect><rect x="113" y="392" rx="2" ry="2" width="180" height="10"></rect><rect x="113" y="412" rx="2" ry="2" width="120" height="10"></rect></clipPath><linearGradient id="author-related-list-loading-animated-diff"><stop offset="0%" stop-color="#f5f6f7" stop-opacity="1"></stop><stop offset="50%" stop-color="#eee" stop-opacity="1"></stop><stop offset="100%" stop-color="#f5f6f7" stop-opacity="1"></stop></linearGradient></defs></svg><a class="look-more" href="/c/user/token/MS4wLjABAAAAdAGemQPKr9g83aKEjrKYLBdjrZWMq33xss8tSi7qOJ1yeSBAP0LIuKlzIEO-IR4V/?source=tuwen_detail&amp;entrance_gid=7283696265131590201" target="_blank" rel="noopener nofollow noreferrer"><span>查看更多</span><i class="icon-arrow"></i></a><div style="height:12px"></div></div></div><div class="show-monitor"><div role="complementary" aria-label="头条热榜" class="detail-hotboard"><div style="display:none;width:318px;height:611px"></div><div style="position:static;top:88px;z-index:100" class=""><div class="ttp-hot-board"><div class="title-bar"><h2 class="title">头条热榜</h2><button type="button" class="refresh">换一换</button></div><ol></ol></div><div class="download-app-banner"><div class="download-app-banner-left"><div class="download-app-banner-title">扫码下载今日头条APP</div><div class="download-app-banner-desc">看最新、最热资讯内容</div></div><div class="download-app-banner-right" style="background-image:url(https://lf3-static.bytednsdoc.com/obj/eden-cn/beeh7nuvjvho/qrcode.png)"></div></div></div></div></div><div class="show-monitor"><div style="display:none;width:318px;height:518px"></div><div style="position:static;top:88px;z-index:100" class=""><div role="complementary" aria-label="精彩视频" class="hot-video"><div class="pane-header video-header"><h2 class="header icon-video">精彩视频</h2><button type="button" class="right" aria-label="换一换精彩视频"><img src="https://lf-dw.toutiaostatic.com/obj/toutiao-duanwai/toutiao/toutiao_web_pc/svgs/rotate_new.3094a784.svg" style="transform:rotate(0deg)" alt=""/><span>换一换</span></button></div><div class="video-list"></div></div></div></div><div><div></div></div></div></div><div class="ttp-toolbar"><ul class="tool-container"><li tabindex="0" role="button" aria-label="去首页" class="tool-item home"><div class="bubble ttp-popup-container" style="transform:scale(0)">点击回到头条首页<button class="icon-close" type="button"></button></div>首页</li><li tabindex="0" role="button" aria-label="反馈" class="tool-item feedback">反馈</li><li tabindex="0" role="button" aria-label="下载" class="tool-item download">下载<div class="download-panel ttp-popup-container" style="transform:scale(0.8)"><div class="title">扫码下载今日头条</div><i style="background-image:url(https://lf3-static.bytednsdoc.com/obj/eden-cn/beeh7nuvjvho/qrcode.png)"></i></div></li><li tabindex="0" role="button" aria-label="回到顶部" class="tool-item top">顶部</li></ul></div><div></div></div><script nonce="mLAKgR4qm1kh_dB9tZBS-" type="text/javascript" src="https://lf-dw.toutiaostatic.com/obj/toutiao-duanwai/toutiao/toutiao_web_pc/common/syl_page.b67e737d.js" crossorigin="anonymous"></script><script nonce="mLAKgR4qm1kh_dB9tZBS-" type="text/javascript" src="https://lf-dw.toutiaostatic.com/obj/toutiao-duanwai/toutiao/toutiao_web_pc/common/htmlparser2.7ef956fe.js" crossorigin="anonymous"></script><script nonce="mLAKgR4qm1kh_dB9tZBS-" type="text/javascript" src="https://lf-dw.toutiaostatic.com/obj/toutiao-duanwai/toutiao/toutiao_web_pc/common/tt_pc_bricks.0d274a27.js" crossorigin="anonymous"></script><script nonce="mLAKgR4qm1kh_dB9tZBS-" type="text/javascript" src="https://lf-dw.toutiaostatic.com/obj/toutiao-duanwai/toutiao/toutiao_web_pc/common/collect.9c3f3aed.js" crossorigin="anonymous"></script><script nonce="mLAKgR4qm1kh_dB9tZBS-" type="text/javascript" src="https://lf-dw.toutiaostatic.com/obj/toutiao-duanwai/toutiao/toutiao_web_pc/common/react.ab24d615.js" crossorigin="anonymous"></script><script nonce="mLAKgR4qm1kh_dB9tZBS-" type="text/javascript" src="https://lf-dw.toutiaostatic.com/obj/toutiao-duanwai/toutiao/toutiao_web_pc/common/runtime.432dd451.js" crossorigin="anonymous"></script><script nonce="mLAKgR4qm1kh_dB9tZBS-" type="text/javascript" src="https://lf-dw.toutiaostatic.com/obj/toutiao-duanwai/toutiao/toutiao_web_pc/common/vendor.ebda6d23.js" crossorigin="anonymous"></script><script nonce="mLAKgR4qm1kh_dB9tZBS-" type="text/javascript" src="https://lf-dw.toutiaostatic.com/obj/toutiao-duanwai/toutiao/toutiao_web_pc/pages/newsDetail/index.e17f3003.js" crossorigin="anonymous"></script></body></html>

欢迎大家来到IT世界,在知识的湖畔探索吧!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/112547.html

(0)
上一篇 6小时前
下一篇 5小时前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信