如何在vue項目中使用jszip對文件進行加壓和解壓

jszip-in-vue

本文主要介紹jszip在vue中如何使用html

本文涉及到Promise對象和async函數的使用,建議先提早去了解一下vue

關於jszip的使用官方文檔已經介紹的很是詳細了,並且也有示例:https://stuk.github.io/jszip/...node

我這裏主要是結合項目的需求而後抽離出來的demo,主要是對圖片的加壓和解壓git

解壓

使用.loadAsync(data)能夠加載zip文件,data必須是二進制流,我這裏是使用html原生的input上傳文件來獲取文件流,若是須要讀取本地文件能夠使用JSZipUtils.getBinaryContent(zipPath, callback)github

JSZipUtils.getBinaryContent('path/to/content.zip', function(err, data) {
    if(err) {
        throw err; // or handle err
    }

    JSZip.loadAsync(data).then(function () {
        // ...
    });
});

// or, with promises:

new JSZip.external.Promise(function (resolve, reject) {
    JSZipUtils.getBinaryContent('path/to/content.zip', function(err, data) {
        if (err) {
            reject(err);
        } else {
            resolve(data);
        }
    });
}).then(function (data) {
    return JSZip.loadAsync(data);
})
.then(...)

使用.file(name).async()讀取文件裏面的內容。canvas

zip.file("hello.txt").async("string").then(function (data) {
  // 以字符串形式輸出文本內容
});

if (JSZip.support.uint8array) {
  zip.file("hello.txt").async("uint8array").then(function (data) {
    // 使用二進制數組存儲文本內容
  });
}

以上的方法都是Promise實例,能夠用then方法指定resolved狀態的回調函數。segmentfault

本示例中經過上傳文件獲取文件並將其解壓將文件內容顯示在頁面上跨域

const zipFile = e.target.files[0]
const jszip = new JSZip()
jszip.loadAsync(zipFile).then((zip) => { // 讀取zip
    for (let key in zip.files) { // 判斷是不是目錄
        if (!zip.files[key].dir) {
            if (/\.(png|jpg|jpeg|gif)$/.test(zip.files[key].name)) { // 判斷是不是圖片格式
                let base = zip.file(zip.files[key].name).async(
                    'base64') // 將圖片轉化爲base64格式
                base.then(res => {
                    this.dataList.push({
                        fileName: zip.files[key].name,
                        type: 'img',
                        content: `data:image/png;base64,${res}`
                    })
                })
            }
            if (/\.(txt)$/.test(zip.files[key].name)) { // 判斷是不是文本文件
                let base = zip.file(zip.files[key].name).async(
                    'string') // 以字符串形式輸出文本內容
                base.then(res => {
                    this.dataList.push({
                        fileName: zip.files[key].name,
                        type: 'text',
                        content: res
                    })
                })
            }
        }
    }
})

加壓

使用.file(name, content)將內容寫進文件數組

zip.file("Hello.txt", "Hello world\n");

使用.generateAsync(option)將文件轉換爲流文件,並使用FileSaver的saveAs(content, fileaname)將文件保存到本地promise

zip.generateAsync({type:"blob"})
.then(function (blob) {
    saveAs(blob, "hello.zip");
});

本示例主要是對圖片進行加壓。先將圖片轉換爲base64格式(使用canvas),再將其轉換爲二進制流進行加壓。由於是使用img.onload異步加載圖片,必須等待圖片加載完後才能將其進行加壓,因此須要用async函數將異步轉換爲同步。

/**
 *
 * @param url 圖片路徑
 * @param ext 圖片格式
 * @param callback 結果回調
 */
async getUrlBase64(url, ext) {
    return new Promise((resolve, reject) => {
        var canvas = document.createElement('canvas') // 建立canvas DOM元素
        var ctx = canvas.getContext('2d')
        var img = new Image()
        img.crossOrigin = 'Anonymous' // 處理跨域
        img.src = url
        img.onload = () => {
            canvas.width = img.width // 指定畫板的高度,自定義
            canvas.height = img.height // 指定畫板的寬度,自定義
            ctx.drawImage(img, 0, 0) // 參數可自定義
            var dataURL = canvas.toDataURL('image/' + ext)
            resolve(dataURL) // 回調函數獲取Base64編碼
            canvas = null
        }
    })
},
async exportZip() {
    const imgList = this.imgList
    const proList = []
    const zip = new JSZip()
    const cache = {}
    await imgList.forEach(item => { // 等待全部圖片轉換完成
        const pro = this.getUrlBase64(item, '.jpg').then(base64 => {
            const fileName = item.replace(/(.*\/)*([^.]+)/i,"$2")
            zip.file(fileName, base64.substring(base64.indexOf(',') + 1), {
                base64: true
            })
            cache[fileName] = base64
        })
        proList.push(pro)
    })
    Promise.all(proList).then(res => {
        zip.generateAsync({
            type: 'blob'
        }).then(content => { // 生成二進制流
            saveAs(content, 'images.zip') // 利用file-saver保存文件
        })
    })
}

以上讀取和保存文件的方法只使用於在瀏覽器中使用,若是須要在node.js中讀取和保存文件的話能夠使用node.js內置模塊fs。

以上,若是有錯誤的地方歡迎指正

GitHub地址

https://github.com/1366053981...

參考文檔

https://blog.csdn.net/qq_3285...

https://segmentfault.com/a/11...

博客地址
CSDN

相關文章
相關標籤/搜索