vue supports txt, docx, xlsx, mp4 format file preview (pure front-end)

Foreword

In daily work, we have already encountered the function of previewing files after uploading them, such as docx, doc, xls, xlsx, ppt, pdf, txt, pictures, videos and other formats. In fact, back-end personnel can also write interfaces Analysis, in line with the mentality of not wanting to trouble others, if you can solve it yourself, you will never trouble others. Here is a brief introduction to the preview of txt, docx, xlsx, and mp4 files.

1. txt text preview

1. Install axios in the vue project npm i axios -S or yarn add axios

2. Prepare a txt file and enter some content in it.

3. Use axios to request the txt file

The complete code of the page is as follows

<template>
    <div class="txt" style="white-space: pre-wrap;">{<!-- -->{ textContent }}</div>
</template>
<script setup lang="ts">
    import { ref } from 'vue';
    import axios from 'axios';

    const textContent = ref<any>("");
    //This can be an http address or a local address
    const url = "http://10.3.1.171:7878/123.txt";
    axios.get(url,{
        responseType: "text",
    }).then(res=>{
        textContent.value = res.data;
    })

</script>

The results are as follows

It was found that he could successfully get the text content, but our text not only contains numbers, English, but also Chinese

4. At this time we write some Chinese into txt

Let’s look at the results again

Oops, garbled codes appear at this time. Why do garbled codes appear? ? ?

The reason is very simple. The default encoding used by axios is UTF-8, while the default encoding of txt is ANSI, which is GBK. Once you understand the cause of the error, it will be easier to solve. There are two solutions.

1.Directly modify the encoding of txt to UTF-8. For modification methods, please refer to: How to modify the default encoding format of txt files? _Baidu knows

The result after the modification is completed is as follows

We found that the result was what we wanted. Do you think everything is over here? NO, NO, NO, this method is not recommended. We cannot design and code every file. What we pursue is perfection and never work overtime… bite the bullet and keep working, with a spirit of ingenuity. I have to polish my art, haha, so there is a second solution

2. Convert the return value to encoding on axios

After reading the axios documentation, I found a transformResponse field configuration.

We can use this configuration item to transcode the returned data and convert it before processing.

The responseType is set to blob, and we use the stream method to implement it. The following is the complete code

<template>
    <div><div class="txt" style="white-space: pre-wrap;">{<!-- -->{ textContent }}</div></div>
</template>
<script setup lang="ts">
    import { ref } from 'vue';
    import axios from 'axios';


    const textContent = ref<any>("");

    const url = "http://10.3.1.171:7878/123.txt";


    const transformData = (data:any)=>{
        return new Promise((resolve)=>{
            let reader = new FileReader();
            reader.readAsText(data,'GBK');
            reader.onload = ()=>{
                resolve(reader.result)
            }
        })
    }

    axios.get(url,{
        responseType:"blob",
        transformResponse: [
            async function (data) {
                return await transformData(data);
            },
        ],
    }).then(res=>{
        res.data.then((data:any)=>{
            textContent.value = data;
        })
    })

</script>

The promise used here returns the data read by fileReader, and the encoding is set to GBK in fileReader, so that the encoding is consistent with txt. Next

Let’s recreate a txt file

Then test it again, the results are as follows

The result is what we finally want. The preview of txt is now complete. Here we just demonstrate how to load txt text. It can be made into a component for easy use in the future.

2. Preview of docx file

We borrow the third-party plug-in @vue-office/docx to process the preview of docx files. Here we directly make it into a component, and the sub-component can provide a url. The code is as follows

First use yarn or npm to install @vue-office/docx

<!-- docx document viewer -->
<template>
    <teleport to="body">
        <div class="sx-docx-wrapper change-y-translate">
            <vue-office-docx :src="url" style="height: 100%; margin: 0; padding: 0" @rendered="rendered"/>
            <span class="icon-close" @click="emits('close')"></span>
        </div>
    </teleport>
</template>
<script lang="ts" setup>

    //Introduce VueOfficeDocx component
    import VueOfficeDocx from "@vue-office/docx";
    //Introduce related styles
    import "@vue-office/docx/lib/index.css";

    const props = defineProps({
        url:{
            type:String,
            default:""
        }
    })


    const emits = defineEmits<{
        (e:"close"):void
    }>()

    const rendered = ()=>{
        console.log("Rendering completed");
    }
    
</script>
<style lang="scss" scoped>
    .sx-docx-wrapper{
        position:fixed;
        width:100%;
        height:100%;
        background:rgba(0,0,0,0.6);
        overflow:hidden;
        top:0;
        left:0;
        z-index:9999;
        display:flex;
        justify-content:center;
        align-items:center;

        .icon-close{
            position:absolute;
            top:10px;
            right:20px;
            width:30px;
            height:30px;
            background:url("/img/close.png") center no-repeat;
            background-size:100%;
            cursor:pointer;
        }
    }
</style> 

The effect is as follows

3. xlsx file preview

The implementation method is similar to docx, but the plug-in is different.

1. npm i @vue-office/excel or yarn add @vue-office/excel

2. The code is encapsulated as follows

<!-- excel document viewer -->
<template>
    <teleport to="body">
        <div class="sx-excel-wrapper change-y-translate">
            <vue-office-excel
                :src="url"
                @rendered="renderedHandler"
                @error="errorHandler"
                style="width:80%;"
            />
            <span class="icon-close" @click="emits('close')"></span>
        </div>
    </teleport>
</template>
<script lang="ts" setup>

    //Introduce VueOfficeExcel component
    import VueOfficeExcel from "@vue-office/excel";
    //Introduce related styles
    import "@vue-office/excel/lib/index.css";

    const props = defineProps({
        url:{
            type:String,
            default:""
        }
    })


    const emits = defineEmits<{
        (e:"close"):void
    }>()

    const renderedHandler = ()=>{
        console.log("Rendering completed");
    }

    const errorHandler = ()=>{
        console.log("Rendering failed");
    }
   
    
</script>
<style lang="scss" scoped>
    .sx-excel-wrapper{
        position:fixed;
        width:100%;
        height:100%;
        background:rgba(0,0,0,0.6);
        overflow:hidden;
        top:0;
        left:0;
        z-index:9999;
        display:flex;
        justify-content:center;
        align-items:center;

        .icon-close{
            position:absolute;
            top:10px;
            right:20px;
            width:30px;
            height:30px;
            background:url("/img/close.png") center no-repeat;
            background-size:100%;
            cursor:pointer;
        }
    }
</style> 

The operation effect is as follows

4. Preview of mp4 files

We use the Xigua video plug-in to achieve mp4 preview

1. Install xgplayer yarn add xgplayer or npm i xgplayer

2. The packaging code is as follows

<!-- Xigua video player plug-in https://h5player.bytedance.com/guide/#Installation -->
<template>
    <teleport to="body">
        <div class="sx-xgplayer-wrapper change-y-translate">
            <div class="video-section">
                <div id="video"></div>
                <span class="icon-close" @click="emits('close')"></span>
            </div>
        </div>
    </teleport>
</template>
<script lang="ts" setup>
    import Player, { Events } from 'xgplayer'
    import 'xgplayer/dist/index.min.css';
    import { onMounted,onUnmounted } from 'vue';

    let player:any = null;
    const props = defineProps({
        url:{
            type:String,
            default:""
        }
    })

    const emits = defineEmits<{
        (e:"close"):void
    }>()


    onMounted(()=>{
        player = new Player({
            id: 'video',
            url: props.url,
            height: '100%',
            width: '100%',
            lang:'zh-cn'
        })
    })

    onUnmounted(()=>{
        player.destroy() // Destroy the player
        player = null // Null the instance reference
    })

   
    
</script>
<style lang="scss" scoped>
    .sx-xgplayer-wrapper{
        position:fixed;
        width:100%;
        height:100%;
        background:rgba(0,0,0,0.6);
        overflow:hidden;
        top:0;
        left:0;
        z-index:9999;
        display:flex;
        justify-content:center;
        align-items:center;

        .video-section{
            width:1200px;
            height:660px;
            background:#000;
            padding:20px;
            position:relative;
            box-shadow: 0 1px 8px 1px #5c5c5c;
        }

        .icon-close{
            position:absolute;
            top:10px;
            right:10px;
            width:20px;
            height:20px;
            background:url("/img/close.png") center no-repeat;
            background-size:100%;
            cursor:pointer;
        }
    }
</style> 

Please refer to the Xigua development documentation for related configuration items. The document address is in the code! ! !

Let’s see the effect achieved

At this point, the preview functions for docx, xlsx, txt, mp4, etc. have been implemented. Get off work! ! !

Enlightenment: If you don’t become hysterical and exhausted, how can you break out of the cocoon and become a butterfly and be reborn in Nirvana?