当前位置: 首页 > 工具软件 > Any2Excel > 使用案例 >

flask 导出excel

荆城
2023-12-01

Flask 导出Excel 的两种方法 ,第一种使用Flask-Excel

安装:

pip install Flask-Excel
pip install pyexcel-xls
pip install pyexcel-xlsx
pip install pyexcel-ods

除了安装主要的Falsk-Excel,还需要安装一些格式的扩展,需要导出什么格式就安装什么扩展

使用:

#extendsions.py
import flask_excel as excel


#__init__.py
from hifeiji.extendsions import excel
excel.init_excel(app)

#blueprint
#activity.py
import flask_excel as excel


@activity_bp.route("/export", methods=['GET'])
@login_required
def export_records():
    content = [['No','Title','Name','Tel','Start','End','Service Time']]

    activityList = ActivityAtten.query.order_by(ActivityAtten.activity_start.asc()).all()
    if activityList:
        for value in activityList:
            new_content = []
            new_content = [value.activity_no,value.activity_title,value.activity_atten_name,value.activity_atten_tel,value.activity_start,value.activity_end,minutes2hours(value.activity_servicetime)]

            content.append(new_content)

    current_app.logger.info("exportActivity")
    return excel.make_response_from_array(content, "xlsx",
                                          file_name="exportActivity") 

 首先,要初始化Flask-Excel,

excel.init_excel(app)

重点是最后一句

return excel.make_response_from_array(content, "xlsx",file_name="exportActivity") 

#注释是这样的
(function) make_response_from_array: (array, file_type, status=200, file_name=None, **keywords) -> None

第二种是使用 xlsxwriter

首先安装

pip install xlswriter

xlsxwriter 不需要初始化,可以直接调用,代码如下

import xlsxwriter
import io


@activity_bp.route("/exportActivity",methods=['GET'])
@login_required
def exportActivity():

    output = io.BytesIO()
    workbook = xlsxwriter.Workbook(output)
    sheet = workbook.add_worksheet('考勤人员')
    activityList = Activity.query.order_by(Activity.starttime.asc()).all()

    format1 = {
        # 'bold': True,  # 字体加粗
        'align': 'center',  # 水平位置设置:居中
        'valign': 'vcenter',  # 垂直位置设置,居中
        # 'font_size': 14,  # '字体大小设置'
        'border':1
    }
    title_format = workbook.add_format(format1)

    #构建格式并添加入实例
    format2={
        # 'bold':True,#字体加粗
        # 'num_format':'$#,##0',#货币数字显示样式
        'align':'center',#水平位置设置:居中
        'valign':'vcenter',#垂直位置设置,居中
        # 'font_size':16,#'字体大小设置'
        # 'font_name':'Courier New',#字体设置
        # 'italic':True,# 斜体设置
        # 'underline':1,#下划线设置 1.单下划线 2.双下划线 33.单一会计下划线 34双重会计下划线
        # 'font_color':"red",#字体颜色设置
        'border':1,#边框设置样式1
        # 'border_color':'green',#边框颜色
        # 'bg_color':'#c7ffec',#背景颜色设置
    }
    content_format = workbook.add_format(format2)




    row = 0
    number = 1
    if activityList:
        for index in range(len(activityList)):

            activityAttenList = ActivityAtten.query.filter_by(activity_no=activityList[index].no).all()
            if activityAttenList:

                title_date = time.strftime("%Y-%m-%d", time.strptime(str(activityList[index].starttime), "%Y-%m-%d %H:%M:%S")) 
                title = activityList[index].title
                # sheet.merge_range('B'+str(row)+':F'+str(row),str(index+1)+'.'+str(title_date)+' '+title)
                sheet.merge_range(row,1,row,5,str(number)+'.'+str(title_date)+' '+title,title_format)
                row = row+1
                sheet.set_column(row,1, 5) 
                sheet.set_column(row,2, 10)
                sheet.set_column(row,3, 20)
                sheet.set_column(row,4, 20)
                sheet.set_column(row,5, 10)

            
            
                sheet.write(row,1,'序号',title_format)
                sheet.write(row,2,'姓名',title_format)
                sheet.write(row,3,'手机号码',title_format)
                sheet.write(row,4,'服务/培训时长',title_format)
                sheet.write(row,5,'备注',title_format)
                row = row+1


                for key in range(len(activityAttenList)):
                    sheet.write(row,1,str(key+1),title_format)
                    sheet.write(row,2,activityAttenList[key].activity_atten_name,title_format)
                    sheet.write(row,3,activityAttenList[key].activity_atten_tel,title_format)
                    sheet.write(row,4,minutes2hours(activityAttenList[key].activity_servicetime),title_format)
                    sheet.write(row,5,'',title_format)
                    row = row+1

                row = row+2 #每个活动换2行
                number = number+1 #活动序号


    workbook.close()
    response = make_response(output.getvalue())
    response.headers['Content-Type'] = "application/x-xlsx"
    response.headers["Cache-Control"] = "no-cache"
    response.headers["Content-Disposition"] = "attachment; filename=download.xlsx"
    return response

有几个点需要注意,如果想设置单元格的样式,可以这样:

    format1 = {
        # 'bold': True,  # 字体加粗
        'align': 'center',  # 水平位置设置:居中
        'valign': 'vcenter',  # 垂直位置设置,居中
        # 'font_size': 14,  # '字体大小设置'
        'border':1
    }
    title_format = workbook.add_format(format1)


    #.......


    sheet.write(row,1,'序号',title_format)
    

write() 的方法是这样的

 #跟踪 write()方法,是这样的

    def write(self, row, col, *args):
        """
        Write data to a worksheet cell by calling the appropriate write_*()
        method based on the type of data being passed.

        Args:
            row:   The cell row (zero indexed).
            col:   The cell column (zero indexed).
            *args: Args to pass to sub functions.

        Returns:
             0:    Success.
            -1:    Row or column is out of worksheet bounds.
            other: Return value of called method.

        """
        return self._write(row, col, *args)  

行和列都从0 开始,比如A1,其实就是0,0

make_response() 方法使用时,要注意,是使用flask 中的make_response()方法,而不是pyexcel 中的 make_response(),当初我就是在这里卡住了!两个方法是不一样的。

跟住make_response()方法

def make_response(*args: t.Any) -> "Response":
    """Sometimes it is necessary to set additional headers in a view.  Because
    views do not have to return response objects but can return a value that
    is converted into a response object by Flask itself, it becomes tricky to
    add headers to it.  This function can be called instead of using a return
    and you will get a response object which you can use to attach headers.

    If view looked like this and you want to add a new header::

        def index():
            return render_template('index.html', foo=42)

    You can now do something like this::

        def index():
            response = make_response(render_template('index.html', foo=42))
            response.headers['X-Parachutes'] = 'parachutes are cool'
            return response

    This function accepts the very same arguments you can return from a
    view function.  This for example creates a response with a 404 error
    code::

        response = make_response(render_template('not_found.html'), 404)

    The other use case of this function is to force the return value of a
    view function into a response which is helpful with view
    decorators::

        response = make_response(view_function())
        response.headers['X-Parachutes'] = 'parachutes are cool'

    Internally this function does the following things:

    -   if no arguments are passed, it creates a new response argument
    -   if one argument is passed, :meth:`flask.Flask.make_response`
        is invoked with it.
    -   if more than one argument is passed, the arguments are passed
        to the :meth:`flask.Flask.make_response` function as tuple.

    .. versionadded:: 0.6
    """
    if not args:
        return current_app.response_class()
    if len(args) == 1:
        args = args[0]
    return current_app.make_response(args)

从注释可以知道,response = make_response(render_template('index.html', foo=42))可以使用html 转存生成其他文件

以上是两种导出excel 的方法,

如果只是单纯导出报表,无需其他样式的,可以使用flask-excel,因为比较简单方便。

如果是需要有一定样式的,比如合拼单元格之类的,xlsxwriter 好用

 类似资料: