【问题标题】:Download PDF file using pdfkit and FastAPI使用 pdfkit 和 FastAPI 下载 PDF 文件
【发布时间】:2022-04-21 19:55:09
【问题描述】:

我将创建一个将HTML 页面转换为PDF 文件的API。我使用pdfkitFastAPI 制作了它。但是,它将文件保存到我的本地磁盘。在我在线提供这个 API 之后,用户如何将这个 PDF 文件下载到他们的计算机上?

from typing import Optional
from fastapi import FastAPI
import pdfkit

app = FastAPI()
@app.post("/htmltopdf/{url}")
def convert_url(url:str):
  pdfkit.from_url(url, 'converted.pdf')

【问题讨论】:

  • 您是否尝试返回该对象?也许返回它的路径?
  • this 会回答您的问题吗?正如@PaulH 所说,您应该返回对象
  • @clmno 是的,它对我有用。谢谢你。现在我希望在不保存到服务器路径的情况下做到这一点。我使用了 tempfile.NamedTemporaryFile() 但得到了空的 pdf 页面。正在寻找另一种解决方案...

标签: python pdfkit fastapi


【解决方案1】:

返回 FileResponse 解决了我的问题。感谢@Paul H 和@clmno 下面的代码是返回 pdf 文件以使用 FastApi 下载的工作示例。

from typing import Optional
from fastapi import FastAPI
from starlette.responses import FileResponse
import pdfkit

app = FastAPI()
config = pdfkit.configuration(wkhtmltopdf=r"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe")

@app.get("/")
def read_root():
    pdfkit.from_url("https://nakhal.expo.com.tr/nakhal/preview","file.pdf", configuration=config)
    return FileResponse(
                "file.pdf",
                media_type="application/pdf",
                filename="ticket.pdf")

**2)**这是使用临时文件的另一种方式 - 将 pdf 添加到变量中,只需写入 False 而不是路径 -

from typing import Optional
from fastapi import FastAPI
from starlette.responses import FileResponse
import tempfile
import pdfkit



app = FastAPI()

config = pdfkit.configuration(wkhtmltopdf=r"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe")


@app.get("/")
def read_root():
    pdf = pdfkit.from_url("https://nakhal.expo.com.tr/nakhal/preview",False, configuration=config)

    with tempfile.NamedTemporaryFile(mode="w+b", suffix=".pdf", delete=False) as TPDF:
        TPDF.write(pdf)
        return FileResponse(
                TPDF.name,
                media_type="application/pdf",
                filename="ticket.pdf")

【讨论】:

  • 很好的解决方案?
【解决方案2】:

获得 PDF 文件的 bytes 后,您可以简单地返回自定义 Response,指定 contentheadersmedia_type。因此,无需像另一个答案所建议的那样将文件保存到磁盘或生成临时文件。与this answer 类似,您可以设置Content-Disposition 标头让浏览器知道是否应该查看或下载PDF 文件。示例如下:

from fastapi import Response

@app.get("/")
def read_root():
    pdf = pdfkit.from_url('http://google.com', configuration=config)
    headers = {'Content-Disposition': 'attachment; filename="out.pdf"'}
    return Response(pdf, headers=headers, media_type='application/pdf')

要在浏览器中查看 PDF 文件,请使用:

headers = {'Content-Disposition': 'inline; filename="out.pdf"'}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 2016-11-25
    • 2019-04-27
    • 1970-01-01
    • 2015-06-12
    • 2022-11-30
    相关资源
    最近更新 更多