当前位置 : 主页 > 网络编程 > JavaScript >

Vue实现docx、pdf格式文件在线预览功能

来源:互联网 收集:自由互联 发布时间:2023-02-08
目录 介绍 docx 安装 使用 PDF 安装 引入和使用 pdf的放大和缩小 多格式的文件渲染函数映射 不支持的文件提示处理 总结 介绍 在业务中,如果遇到文档管理类的功能,会出现需要在线预
目录
  • 介绍
  • docx
    • 安装
    • 使用
  • PDF
    • 安装
    • 引入和使用
    • pdf的放大和缩小
  • 多格式的文件渲染函数映射
    • 不支持的文件提示处理
      • 总结

        介绍

        在业务中,如果遇到文档管理类的功能,会出现需要在线预览的业务需求,本文主要是通过第三方库来实现文档预览功能,并将其封装成preview组件

        docx

        docx的实现需要使用docx-preview插件

        安装

        npm i docx-preview
        

        使用

        创建一个容器标签

        <div ref="file" v-show="extend == 'docx'"></div>
        

        引入并创建渲染函数

        import { renderAsync } from "docx-preview";
        renderDocx() {
              renderAsync(this.fileData, this.$refs.file, null, {
                className: "docx", //默认和文档样式类的类名/前缀
                inWrapper: true, //启用围绕文档内容呈现包装器
                ignoreWidth: false, //禁用页面的渲染宽度
                ignoreHeight: false, //禁用页面的渲染高度
                ignoreFonts: false, //禁用字体渲染
                breakPages: true, //在分页符上启用分页
                ignoreLastRenderedPageBreak: true, //在lastRenderedPageBreak元素上禁用分页
                experimental: false, //启用实验功能(制表符停止计算)
                trimXmlDeclaration: true, //如果为true,则在解析之前将从xml文档中删除xml声明
                useBase64URL: false, //如果为true,图像、字体等将转换为base 64 URL,否则使用URL.createObjectURL
                useMathMLPolyfill: false, //包括用于铬、边等的MathML多填充。
                showChanges: false, //启用文档更改的实验渲染(插入/删除)
                debug: false, //启用额外的日志记录
              });
            },

        PDF

        pdf的预览需要使用PDFJS这个插件,通过将文件流解析写到canvas上实现预览效果

        安装

        npm i pdfjs-dist
        

        引入和使用

        <canvas
          v-for="num in numPages"
          :key="num"
          :id="'canvas_' + num"
          class="canvas"
        ></canvas>
        

        此处pdf的渲染数据this.fileData必须是一个ArrayBuffer格式的数据,如果请求的的数据是Blob格式必须要先使用Blob.arrayBuffer()转换

        async renderPdf(num = 1) {
              this.fileData.getPage(num).then(page => {
                // 设置canvas相关的属性
                const canvas = document.getElementById("canvas_" + num);
                const ctx = canvas.getContext("2d");
                const dpr = window.devicePixelRatio || 1;
                const bsr =
                  ctx.webkitBackingStorePixelRatio ||
                  ctx.mozBackingStorePixelRatio ||
                  ctx.msBackingStorePixelRatio ||
                  ctx.oBackingStorePixelRatio ||
                  ctx.backingStorePixelRatio ||
                  1;
                const ratio = dpr / bsr;
                const viewport = page.getViewport({ scale: this.pdfScale }); // 设置放缩比率
                canvas.width = viewport.width * ratio;
                canvas.height = viewport.height * ratio;
                canvas.style.width = viewport.width + "px";
                canvas.style.height = viewport.height + "px";
                ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
                const renderContext = {
                  canvasContext: ctx,
                  viewport: viewport,
                };
                // 数据渲染到canvas画布上
                page.render(renderContext);
                if (this.numPages > num) {
                  setTimeout(() => {
                    return this.renderPdf(num + 1);
                  });
                }
              });
            },

        pdf的放大和缩小

        pdf文件渲染后如果不能调整大小会因为源文件的大小和文件内容,出现模糊的问题,所以进行缩放渲染是有必要的

        // pdf放大
        setPdfZoomin() {
          const max = 2;
          if (this.pdfScale >= max) {
            return;
          }
          this.pdfScale = this.pdfScale + 0.2;
          this.renderPdf();
        },
        // pdf缩小
        setPdfZoomout() {
          const min = 0.6;
          if (this.pdfScale <= min) {
            return;
          }
          this.pdfScale = this.pdfScale - 0.1;
          this.renderPdf();
        },

        多格式的文件渲染函数映射

        因为将多种文件渲染放在一个文件中,所以处理函数需要做映射处理,执行对应格式的文件渲染

        renderPreview(extend) {
            const handle = {
            docx: () => {
              this.extend = "docx";
              this.$nextTick(() => this.renderDocx());
            },
            pdf: () => {
              this.extend = "pdf";
              new Blob([this.fileData]).arrayBuffer().then(res => {
                PDFJS.getDocument(res).promise.then(pdfDoc => {
                  this.numPages = pdfDoc.numPages; // pdf的总页数
                  this.fileData = pdfDoc;
                  this.$nextTick(() => this.renderPdf());
                });
              });
            },
            };
            this.isLoading = false;
            if (!Object.hasOwn(handle, extend)) {
            this.extendName = extend;
            return (this.extend = "other");
            }
            handle[extend]();
        },

        不支持的文件提示处理

        在这个文件中,目前只支持docx和pdf的预览,如果出现了不支持的文件,需要增加一个提示处理,告知用户 例如如下的文件提示

        <div class="container" v-show="extend == 'other'">
          <a-alert
            :message="`不支持.${this.extendName}格式的在线预览,请下载后预览或转换为支持的格式`"
            description="支持docx, pdf格式的在线预览"
            type="info"
            show-icon
          />
        </div>

        总结

        本文只是简单的总结了关于文件预览的纯前端实现和封装方式,对于业务的思路简单整理,如果是对于有更复杂的场景,还需要有更加具体的拆分和优化。

        到此这篇关于Vue实现docx、pdf格式文件在线预览功能的文章就介绍到这了,更多相关Vue文件在线预览内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!

        上一篇:vue2.x引入threejs的实例代码
        下一篇:没有了
        网友评论