• 前端实现在线预览Word文件


    在这里插入图片描述

    简介

    在项目中遇到了个需求,大致需求这样的:用户在上传文件前需要先预览一下内容,确认内容是否正确,正确的情况下才可以上传
    那么这里面会涉及到一个在上传前的文档的预览操作,下面就记录一下踩坑记录

    docx-preview

    这是一个 纯前端的JavaScript库,它的优点是能 纯前端,可以 不靠后端,对 .docx 的文件进行在线预览,缺点是 不支持doc,不支持doc,不支持doc,重要的事说三遍;
    github地址如下:docx-preview,有兴趣的小伙伴可以仔细看一下官方介绍;

    安装

    npm install docx-preview -S
    
    • 1

    如果一直安装失败,可以试试使用 cnpm 进行安装

    cnpm install docx-preview -S
    
    • 1

    另外,由于 解析的需要,使用时需要 额外 安装引入一个解析库jszip,由于该库并非是以module的方式,需要在html中的header标签里引入,文件地址:https://unpkg.com/jszip/dist/jszip.min.js

    <!DOCTYPE html>
    <html lang="">
        <head>
            <meta charset="utf-8" />
            <script src="https://unpkg.com/jszip/dist/jszip.min.js"></script>
        </head>
        <body>
        </body>
    </html>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    建议在项目中直接将该文件直接下载下来,然后放入项目中;

    使用

    先看一下官方示例

    <!--optional polyfill for promise-->
    <script src="https://unpkg.com/promise-polyfill/dist/polyfill.min.js"></script>
    <!--lib uses jszip-->
    <script src="https://unpkg.com/jszip/dist/jszip.min.js"></script>
    <script src="docx-preview.min.js"></script>
    <script>
        var docData = <document Blob>;
    
        docx.renderAsync(docData, document.getElementById("container"))
            .then(x => console.log("docx: finished"));
    </script>
    <body>
        ...
        <div id="container"></div>
        ...
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    简单的说,它有3个参数,第一个参数是接接收的文件数据流第二个参数为容器,并且它有一个then的回调函数,执行成功会执行该函数,不过这个并非是它的全部API,具体的API可以前往github自行查找,这些个api实际应该用的非常少,这几个已经够用了;

    Vue中使用docx-preview示例

    本章节实现一个本地选择文件,并在线展示的示例,大致步骤如下:

    1. 选择一个docx的文件,并获取该文件;
    2. 文件转化成blob格式;
    3. 将Blob格式的数据流展示传入dox-preview中,并展示;

    首先是第一步,Html部分如下,组件使用的是 IViewUpload组件,用 element 也一样,目的都是通过组件获得选择的文件

    <Upload
        action
        name="file"
        id="file"
        multiple="multiple"
        :auto-upload="false"
        :before-upload="init"
    >
        <Button size="small" type="primary">点击上传</Button>
    </Upload>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    选择文件后读取该文件

     init(file) {
        var reader = new FileReader();
        reader.onload = (e) => {
    
        };
        // 传入一个参数对象即可得到基于该参数对象的文本内容
        reader.readAsDataURL(file);
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    第二步,读取文件数据,将其 转成Blob格式 的数据流

     let arr = e.target.result.split(",");
    let data = window.atob(arr[1]);
    let mime = arr[0].match(/:(.*?);/)[1];
    let ia = new Uint8Array(data.length);
    for (var i = 0; i < data.length; i++) {
        ia[i] = data.charCodeAt(i);
    }
    const blob = new Blob([ia], { type: mime });
    console.log(blob);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    第三步,塞进 docx-preview 中进行展示

    docx.renderAsync(blob, this.$refs.demoDocContainer).then(
        (x) => {
            console.log(x);
        }
    ); // 渲染到页面
    
    • 1
    • 2
    • 3
    • 4
    • 5

    即可完成展示,效果如下:
    在这里插入图片描述

    完整代码如下

    <template>
        <div id="app">
            <Upload
                action
                name="file"
                id="file"
                multiple="multiple"
                :auto-upload="false"
                :before-upload="init"
            >
                <Button size="small" type="primary">点击上传</Button>
            </Upload>
            <div class="doc-preview" ref="demoDocContainer">1</div>
        </div>
    </template>
    <script>
    let docx = require("docx-preview");
    export default {
        name: "docx-demo",
        methods: {
            init(file) {
                var reader = new FileReader();
                reader.onload = (e) => {
                    let arr = e.target.result.split(",");
                    let data = window.atob(arr[1]);
                    let mime = arr[0].match(/:(.*?);/)[1];
                    let ia = new Uint8Array(data.length);
                    for (var i = 0; i < data.length; i++) {
                        ia[i] = data.charCodeAt(i);
                    }
                    const blob = new Blob([ia], { type: mime });
                    docx.renderAsync(blob, this.$refs.demoDocContainer).then(
                        (x) => {
                            console.log(x);
                        }
                    ); // 渲染到页面
                };
                // 传入一个参数对象即可得到基于该参数对象的文本内容
                reader.readAsDataURL(file);
            },
        },
    };
    </script>
    <style lang="less">
    #app {
        font-family: Avenir, Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
    }
    .doc-preview {
        width: 100%;
        height: 800px;
        background-color: #f5f5f5;
    }
    </style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    错误处理

    在使用的使用遇到一个错误,如下
    在这里插入图片描述

    后来发现原因是选择的文件格式是 doc格式 的,因此无法被识别,特此在强调一下,该组件只能识别docx格式,不支持识别doc格式的word

    doc格式识别

    如果一定要识别doc格式的文件,那么 纯前端应该是不行的了(主要是个人没找到合适的办法,如果有大佬研究过着一块,麻烦留言告知,万分感谢),因此不管是下面哪种方法需要后台配合,大致方法有以下这种;

    转PDF格式

    如题,把doc格式的文件传递给后台,后台取到后将其转换格式,转成PDF格式,之后就方便了,前台可以通过类似于 pdfjs 等工具库进行前台展示,pdfjs官网如下:https://mozilla.github.io/pdf.js/,具体用法可以自行官网查看,
    下载的话可以在官网下载,也可以在npm上进行安装
    在这里插入图片描述

    当然,除了pdfjs,还有一种,就是通过 iframe 进行展示,这种方法更简单,不过稍微原始了点,并且说实话,到了现在 Iframe 并不被w3c所推荐了,但是很多时候确实好用,比如现在,用法如下

    <iframe :src="url"></iframe>
    
    • 1

    url为该文件在后台的地址,由于iframe的特性,可以直接在区域内显示路径显示的文件…

    小结

    如果不需要识别doc文件,建议使用 docx-preview 进行在线预览,如果 一定要兼容doc,建议转成PDF格式后,通过 pdfjs 或者 Iframe 等库文件进行预览;

  • 相关阅读:
    openwrt开发使用-arping
    git从入门到会用
    尚医通 (十五) --------- 平台管理前端搭建
    GBase 8c 分析表
    2022年全球市场胃管泵总体规模、主要生产商、主要地区、产品和应用细分研究报告
    《代码整洁之道》精读与演绎----毛星云
    vue+.net入门级书签项目
    行为型:观察者模式
    uniapp组件传值的方法(父传子,子传父,对象传值)案例
    [sqoop]hive导入mysql,其中mysql的列存在默认值列
  • 原文地址:https://blog.csdn.net/zy21131437/article/details/126304514