如何使用FastAPI返回并下载Excel文件?

a69*_*673 4 python excel media-type fastapi

如何使用FastAPI返回excel文件(版本:Office365)?该文档看起来非常简单。但是,我不知道media_type该用什么。这是我的代码:

import os
from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel
from typing import Optional

excel_file_path = r"C:\Users\some_path\the_excel_file.xlsx"

app = FastAPI()

class ExcelRequestInfo(BaseModel):
    client_id: str


@app.post("/post_for_excel_file/")
async def serve_excel(item: ExcelRequestInfo):
    # (Generate excel using item.)
    # For now, return a fixed excel.
    return FileResponse(
        path=excel_file_path,

        # Swagger UI says 'cannot render, look at console', but console shows nothing.
        media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

        # Swagger renders funny chars with this argument:
        # 'application/vnd.ms-excel'
    )
Run Code Online (Sandbox Code Playgroud)

假设我做对了,如何下载该文件?我可以使用FastAPI生成的Swagger UI来查看工作表吗?或者,卷曲?理想情况下,我希望能够下载并在 Excel 中查看该文件。

解决方案

这是我的最终(编辑过的)解决方案,可以让您免于点击。在开发过程中,我不得不从 a 切换FileResponseResponsereturns io.BytesIO

import io
import os.path
from fastapi.responses import Response


@router.get("/customer/{customer}/sheet")
async def generate_excel(customer: str):
    excel_file_path: str = None
    buffer: io.BytesIO = None

    # Generate the sheet.
    excel_file_path, buffer = make_excel(customer=customer)

    # Return excel back to client.
    headers = {
        # By adding this, browsers can download this file.
        'Content-Disposition': f'attachment; filename={os.path.basename(excel_file_path)}',
        # Needed by our client readers, for CORS (cross origin resource sharing).
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Headers": "*",
        "Access-Control_Allow-Methods": "POST, GET, OPTIONS",
    }
    media_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

    return Response(
        content=buffer.getvalue(),
        headers=headers,
        media_type=media_type
    )
Run Code Online (Sandbox Code Playgroud)

Chr*_*ris 8

您可以Content-Disposition使用attachment参数设置标头,指示浏览器应下载该文件,如此处和此处答案中所述。Download file一旦您执行请求,Swagger UI 将提供一个链接供您下载该文件。

headers = {'Content-Disposition': 'attachment; filename="Book.xlsx"'}
return FileResponse(excel_file_path, headers=headers)
Run Code Online (Sandbox Code Playgroud)

要在浏览器中查看文件,可以在标头中使用inline, 而不是attachment, 参数Content-Disposition,如前面链接的答案中所述。但是,为了使浏览器能够显示 Excel 文件,应在 中设置正确的值media_typeFileResponse对于 Excel 文件,请参见此处),并且.xlsx(或.xls)必须是浏览器已知的文件扩展名(这通常是通过浏览器扩展/插件)。