django 实现指定文件合并成压缩文件下载

需求是在一列学生列表中选择指定的学生,然后下载他们上传的报告文档。

用Js构造一个表单将选中的学生学号传递到后台

$('#output_student').click(function () {
            var arr = new Array();
                var sign = 0;
                var inputs = document.getElementsByTagName('input');//获取所有的input标签对象。
                for (var i = 0; i < inputs.length; i++) {
                    var obj = inputs[i];
                    if (obj.type == 'checkbox') {
                        if (obj.checked == true) {
                            sign = 1;
                            var length = arr.push(obj.value);
                        }
                    }
                }
                if (sign == 0)//没有被选择项
                {
                    alert("请勾选要下载的数据!");
                    return;
                }
                if (!confirm("确定下载选中的条目吗?")) return;
                var form = $("<form>");
                form.attr('style', 'display:none');
                form.attr('target', '');
                form.attr('method', 'post');
                form.attr('action', '{% url "teacher:downloadDoc" %}');
                var input1 = $('<input>');
                input1.attr('type', 'hidden');
                input1.attr('name', 'number');
                input1.attr('value', arr.join("&"));
                $('body').append(form);
                form.append(input1);
                form.submit();
                form.remove();
                });

后台接收数据

class DownloadDoc(LoginRequiredMixin, View):
    login_url = "/"

    @staticmethod
    def post(request):
        try:
            numbers = request.POST['number']
            list_number = numbers.split('&')
            if "on" in list_number:
                list_number = list_number[1:]
            temp = tempfile.TemporaryFile()
            archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED)
            for number in list_number:
                student = Student.objects.get(number=number)
                if Document.objects.filter(student=student, period='01'):
                    document = Document.objects.get(student=student, period='01')
                    base_dir = os.path.dirname(os.path.dirname(__file__))
                    target_file = os.path.join(base_dir, 'static', 'media', str(document.file)).replace('\\', '/')
                    file_name = str(document.file).split('/')[4]
                    archive.write(target_file, student.real_name+"--"+file_name)
            archive.close()
            wrapper = FileWrapper(temp)
            response = HttpResponse(wrapper, content_type='application/zip')
            response['Content-Disposition'] = 'attachment; filename='+time.strftime('%m-%d')+'.zip'
            response['Content-Length'] = temp.tell()
            temp.seek(0)
            return response
        except Document.DoesNotExist:
            return

注解:

temp = tempfile.TemporaryFile()

tempfile.TemporaryFile([mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None]]]]])

    该函数返回一个 类文件 对象(file-like)用于临时数据保存(实际上对应磁盘上的一个临时文件)。当文件对象被close或者被del的时候,临时文件将从磁盘上删除。 mode、bufsize参数的单方与open()函数一样;suffix和prefix指定了临时文件名的后缀和前缀;dir用于设置临时文件默认的保 存路径。返回的类文件对象有一个file属性,它指向真正操作的底层的file对象。


 

注解:

archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED)

zipfile.ZipFile(fileName[, mode[, compression[, allowZip64]]])
fileName是没有什么疑问的了。
mode和一般的文件操作一样,'r'表示打开一个存在的只读ZIP文件;'w'表示清空并打开一个只写的ZIP文件,或创建一个只写的ZIP文件;'a'表示打开一个ZIP文件,并添加内容。
compression表示压缩格式,可选的压缩格式只有2个:ZIP_STORE;ZIP_DEFLATED。ZIP_STORE是默认的,表示不压缩;ZIP_DEFLATED表示压缩,如果你不知道什么是Deflated,那么建议你去补补课。
allowZip64为True时,表示支持64位的压缩,一般而言,在所压缩的文件大于2G时,会用到这个选项;默认情况下,该值为False,因为Unix系统不支持。
1.2 zipfile.close()
说真的,这个没什么可说的,如果有的话,那就是你写入的任何文件在关闭之前不会真正写入磁盘。
1.3 zipfile.write(filename[, arcname[, compress_type]])
acrname是压缩文件中该文件的名字,默认情况下和filename一样
compress_type的存在是因为zip文件允许被压缩的文件可以有不同的压缩类型。
1.4 zipfile.extractall([path[, member[, password]]])
path解压缩目录,没什么可说的
member需要解压缩的文件名儿列表
password当zip文件有密码时需要该选项
对于简单的应用,这么多就够了。

FileWrapper
简单说就是用FileWrapper类来迭代器化一下文件对象,实例化出一个经过更适合大文件下载场景的文件对象,实现原理相当与把内容一点点从文件中读取,放到内存,下载下来,直到完成整个下载过程。这样内存就不会担心你一下子占用它那么多空间了。

posted on 2015-04-08 15:50  颓废的悠然  阅读(2372)  评论(0编辑  收藏  举报

导航