zoukankan      html  css  js  c++  java
  • day19-python生成文件并提供下载踩的坑

    现在有一个生成文件并提供下载的需求,原代码为(csdn一个博客的):

    
    # app.py
    from flask import send_file
    import xlsxwriter
    
    
    @app.route("/students/v1.0/excel", methods=["GET"])
    def students_excel():
      """1. 生成表头   2. 生成数据  3. 个性化合并单元格,修改字体属性、修改列宽  3. 返回给前端"""
      fp = io.BytesIO()  # 生成一个BytesIO对象
      book = xlsxwriter.Workbook(fp)  # 可以认为创建了一个Excel文件
      worksheet = book.add_worksheet('students_message') # 增加一个sheet
      # 1. 生成表头
      header_list = ["姓名", "年龄", "年级"]
      for col, header in enumerate(header_list):
          worksheet.write(0, col, header)  # 行(从0开始), 列(从0开始), 内容
      
      # 2. 生成数据
      students_data = [("小王", 12, "7年级"), ("小明", 11, "6年级")]
      for row_number, row_tuple in enumerate(students_data):
        for col, per_student_info in enumerate(row_tuple):
            worksheet.write(col+1, col, per_student_infor)  # 遍历导入每个学生的每个信息
      
      # 3. 个性化合并单元格,修改字体属性、修改列宽
      # 定义格式实例, 16号字体,加粗,水平居中,垂直居中,红色字体
      my_format = book.add_format({'font_size': 16, 'bold': True, 'align': 'center', 'valign': 'vcenter', "font_color": "red"})
      worksheet.merge(len(students_data+1, students_data+2, 1, 5, "合并单元格内容", my_format))
      book.close()
      fp.seek(0)
      return send_file(fp, attachment_filename= '学生信息.xlsx', as_attachment=True)
    
    

    但是实际使用时,会发现第二次下载的文件与第一次下载的文件内容相同。
    粗略排查了一下代码,认为问题是写在内存当中每次的内容都一样
    但是fp.seek(0)这一操作按理应该把指针指向了最开始的位置,不应该出现这样的问题
    后来我觉得是send_file(fp, attachment_filename= '学生信息.xlsx', as_attachment=True)中使用了fp,将指针又指向了文件的尾部(还是觉得不合理,按理说这样会内容变多,而不是与之前一样)
    于是又百度去找别的方法,但是大多数都是采用这种写法,终于又发现了新的写法,代码如下

    
    @download_api.route("/downfile",methods=["GET"])
    def down_file():
        """1. 生成表头   2. 生成数据  3. 个性化合并单元格,修改字体属性、修改列宽  3. 返回给前端"""
        fp = io.BytesIO()  # 生成一个BytesIO对象
        book = xlsxwriter.Workbook(fp,{'in_memory':True})  # 可以认为创建了一个Excel文件
        worksheet = book.add_worksheet('students_message')  # 增加一个sheet
        # 1. 生成表头
        header_list = ["姓名", "年龄", "年级"]
        for col, header in enumerate(header_list):
            worksheet.write(0, col, header)  # 行(从0开始), 列(从0开始), 内容
    
        # 2. 生成数据
        students_data = [("小刚", 12, "7年级")]
        for row_number, row_tuple in enumerate(students_data):
            for col, per_student_info in enumerate(row_tuple):
                worksheet.write(row_number + 1, col, per_student_info)  # 遍历导入每个学生的每个信息
        book.close()
        response = make_response(fp.getvalue())
        fp.close()
        response.headers['Content-Type'] = "utf-8"
        response.headers["Cache-Control"] = "no-cache"
        response.headers["Content-Disposition"] = "attachment; filename=download.xlsx"
        return response
    
    

    在这段代码尾部可以看到,获取内存中的值生成了一个响应,然后关闭了内存,这样就不存在因为内存而重复文件的问题了

  • 相关阅读:
    第七次作业-正规式到正规文法与自动机
    第六次作业——正规文法与正规式
    作业5 词法分析程序的设计与实现
    作业4—文法和语言总结与梳理
    第三次作业
    第二次作业-语言和文法
    编译原理第一次作业
    记录在腾讯云上搭建Ubuntu服务器
    第八章总结--排序 数据结构课程终章
    第七章-查找
  • 原文地址:https://www.cnblogs.com/wuren-best/p/14379395.html
Copyright © 2011-2022 走看看