使用 pdfkit 和 FastAPI 下载 PDF 文件
Download PDF file using pdfkit and FastAPI
我将创建一个 API 将 HTML
页面转换为 PDF 文件。我使用 pdfkit
和 FastAPI
制作了它。但是,它将文件保存到我的本地磁盘。在我在线提供此 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')
返回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")
一旦你得到PDF文件的bytes
,你可以简单地return自定义Response
, specifying the content
, headers
and media_type
. Thus, no need for saving the file to the disk or generating temporary files, as suggested by another answer. Similar to this answer,你可以设置Content-Disposition
header到让浏览器知道是否应该查看或下载 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"'}
我将创建一个 API 将 HTML
页面转换为 PDF 文件。我使用 pdfkit
和 FastAPI
制作了它。但是,它将文件保存到我的本地磁盘。在我在线提供此 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')
返回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")
一旦你得到PDF文件的bytes
,你可以简单地return自定义Response
, specifying the content
, headers
and media_type
. Thus, no need for saving the file to the disk or generating temporary files, as suggested by another answer. Similar to this answer,你可以设置Content-Disposition
header到让浏览器知道是否应该查看或下载 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"'}