今天产品经理又提了一个需求.
在系统中上传文件时,需要支持多文件和文件夹上传,并且需要在文件上传时需要将多文件压缩成zip包,下载的时候,直接下载zip包
听到这个需求,我的第一反应就是js应该没有强大吧,因为压缩和访问文件夹,涉及到了文件系统的读取和修改,后来经过一番探索还真让我给实现出来了.
主要用到的库是 jszip
则 则这里简单对jszip做下简单介绍,更详细的功能和api请移步官网.
jszip是是一个创建,读取和写入.zip文件的js库, api优化,简单
浏览器支持
实现思路如下:
1:用户选中文件或文件夹后,获取文件对象,
2:遍历获取的文件对象 放入实例化的zip对象中
3:使用generateAsync()方法生成文件, 通过formdata提交到服务端
代码如下:
此案例支持拖拽上传多个文件, 支持选择多个文件,选择单个文件夹 此外可以使用 file-saver库的saveAs对zip文件包保存到本地
<template><div class="home"><img alt="Vue logo" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="../assets/logo.png">文件压缩上传案例<label name="myfile" for="myfile" style="display:block;width:200px;height:200px;border:1px solid #ddd":class="{'is-dragover': dragover}"@drop.prevent="onDrop"@dragover.prevent="onDragover"@dragleave.prevent="dragover = false"><input type="file" id="myfile" multiple webkitdirectory @change="selectFile" /></label></div></template><script>// @ is an alias to /srcimport JSZip from 'jszip'import axios from 'axios'import { saveAs } from 'file-saver'export default {name: 'home',components: {},data () {return {dragover: false}},mounted () {},methods: {selectFile (even) {var files = even.target.filesthis.commmon(files)},onDrop (even) {this.dragover = falsevar files = even.dataTransfer.filesthis.commmon(files)},commmon (files) {var zip = new JSZip()for (var i = 0; i < files.length; i++) {var f = files[i]zip.file(f.name, f)}zip.generateAsync({ type: 'blob' }).then(function (content) {saveAs(content, 'example.zip')let formData = new FormData()formData.append('file', content)axios({method: 'post',url: '/framework/file/create',data: formData,withCredentials: true, // 默认的headers: {'Content-Type': 'application/x-www-form-urlencoded'}})})},onDragover () {this.dragover = true}}}</script><style lang="scss">.is-dragover{border: 2px solid red !important}</style>
这里说一下拖拽上传文件, 主要是用到的原生事件是这三个
ondrop ondragover ondragleave
加上prevent 可以防止拖拽过程,浏览器 直接打开文件,阻止事件默认行为.
在ondragover的事件上可以处理文件拖拽到了可放置的元素上,对用户 进行友好提示.
ondrop 事件是文件拖拽到了元素上,松开鼠标时触发, 这个时候可以通过事件拿到拖拽的文件列表 使用even.dataTransfer.files
jszip库的常用api是这两个
file(name, data [,options]) :创建zip文件,可以放入多个文件,支持多种文件格式String/ArrayBuffer/Uint8Array/Buffer/Blob/Promise/Nodejs stream,
name | type | description |
---|---|---|
name | string | the name of the file. You can specify folders in the name : the folder separator is a forward slash (“/”). |
data | String/ArrayBuffer/Uint8Array/Buffer/Blob/Promise/Nodejs stream | the content of the file. |
options | object | the options. |
Content of options
:
name | type | default | description |
---|---|---|---|
base64 | boolean | false |
set to true if the data is base64 encoded. For example image data from a <canvas> element. Plain text and HTML do not need this option. More. |
binary | boolean | false |
set to true if the data should be treated as raw content, false if this is a text. If base64 is used, this defaults to true , if the data is not a string, this will be set to true . More. |
date | date | the current date | the last modification date. More. |
compression | string | null | If set, specifies compression method to use for this specific file. If not, the default file compression will be used, see generateAsync(options). More. |
compressionOptions | object | null |
the options to use when compressing the file, see generateAsync(options). More. |
comment | string | null | The comment for this file. More. |
optimizedBinaryString | boolean | false |
Set to true if (and only if) the input is a “binary string” and has already been prepared with a 0xFF mask. |
createFolders | boolean | true |
Set to true if folders in the file path should be automatically created, otherwise there will only be virtual folders that represent the path to the file. More. |
unixPermissions | 16 bits number | null | The UNIX permissions of the file, if any. More. |
dosPermissions | 6 bits number | null | The DOS permissions of the file, if any. More. |
dir | boolean | false | Set to true if this is a directory and content should be ignored. More. |
generateAsync(options[, onUpdate]): 生成一个完整的zip的文件在当前文件目录 返回一个promise
Arguments
name | type | default | description |
---|---|---|---|
options | object | the options to generate the zip file : | |
options.type | string | The type of zip to return, see below for the other types. Required. More. | |
options.compression | string | STORE (no compression) |
the default file compression method to use. More. |
options.compressionOptions | object | null |
the options to use when compressing the file. More. |
options.comment | string | The comment to use for the zip file. More. | |
options.mimeType | string | application/zip |
mime-type for the generated file. More. |
options.platform | string | DOS |
The platform to use when generating the zip file. More. |
options.encodeFileName | function | encode with UTF-8 | the function to encode the file name / comment. More. |
options.streamFiles | boolean | false | Stream the files and create file descriptors, see below. More. |
onUpdate | function | The optional function called on each internal update with the metadata. More. |
type
option
Possible values for type
:
base64
: the result will be a string, the binary in a base64 form.binarystring
(orstring
, deprecated): the result will be a string in “binary” form, using 1 byte per char (2 bytes).array
: the result will be an Array of bytes (numbers between 0 and 255) containing the zip.uint8array
: the result will be a Uint8Array containing the zip. This requires a compatible browser.arraybuffer
: the result will be a ArrayBuffer containing the zip. This requires a compatible browser.blob
: the result will be a Blob containing the zip. This requires a compatible browser.nodebuffer
: the result will be a nodejs Buffer containing the zip. This requires nodejs.
能不能做,要想看这个库的api具不具备将文件转化为zip文件,通过以上两个api,可以得知这个库是支持的.
另外jszip库也支持读取本地和远程的zip文件返回内部文件目录,文件名.等信息,有兴趣的朋友可以去尝试一下
共同学习,写下你的评论
评论加载中...
作者其他优质文章