如何在FastAPI中上传Word/Excel文件并转换返回PDF文件?
解决FastAPI中Word/Excel转PDF的问题
问题原因
你遇到的错误是因为comtypes调用Word的Documents.Open()方法时,传入的是FastAPI的UploadFile对象,但这个方法需要的是本地文件的绝对路径,而非内存中的文件流对象,所以无法将UploadFile转换为COM所需的VARIANT类型。
解决方案
核心思路是先把上传的文件保存到本地临时路径,再用Word/Excel的COM组件打开本地文件完成转换,最后可根据需求返回转换后的PDF文件或清理临时文件。
步骤说明
- 将
UploadFile的内容写入本地临时文件 - 调用Office COM组件打开本地文件并转存为PDF
- 处理完成后强制退出Office进程(避免后台残留进程)
- 可选:清理临时文件,或把PDF文件返回给前端
修正后的代码(支持Word和Excel)
import os import tempfile from fastapi import FastAPI, File, UploadFile import comtypes.client from comtypes import COMError app = FastAPI() # 定义格式常量 WD_FORMAT_PDF = 17 XL_TYPE_PDF = 0x00000025 def convert_to_pdf(input_path: str, output_path: str, is_excel: bool = False): try: if is_excel: # 初始化Excel应用 excel = comtypes.client.CreateObject("Excel.Application") excel.Visible = False workbook = excel.Workbooks.Open(input_path) workbook.ExportAsFixedFormat(0, output_path) # 0对应xlTypePDF workbook.Close() excel.Quit() else: # 初始化Word应用 word = comtypes.client.CreateObject("Word.Application") word.Visible = False doc = word.Documents.Open(input_path) doc.SaveAs(output_path, FileFormat=WD_FORMAT_PDF) doc.Close() word.Quit() return True except COMError as e: print(f"Office转换错误: {e}") # 确保进程退出,避免残留 if 'excel' in locals(): excel.Quit() if 'word' in locals(): word.Quit() return False @app.post("/convert-to-pdf") async def convert_file(file: UploadFile = File(...)): # 创建临时目录保存上传文件和转换后的PDF with tempfile.TemporaryDirectory() as temp_dir: # 保存上传的文件到临时路径 input_file_path = os.path.join(temp_dir, file.filename) with open(input_file_path, "wb") as f: f.write(await file.read()) # 生成PDF文件名 pdf_filename = os.path.splitext(file.filename)[0] + ".pdf" output_file_path = os.path.join(temp_dir, pdf_filename) # 通过后缀判断文件类型(可优化为文件头判断提升准确性) is_excel = file.filename.lower().endswith((".xlsx", ".xls")) success = convert_to_pdf(input_file_path, output_file_path, is_excel) if not success: return {"error": "文件转换失败,请确保是有效的Word/Excel文件"} # 如需返回PDF文件给前端,可替换为以下代码: # from fastapi.responses import FileResponse # return FileResponse(output_file_path, filename=pdf_filename) return {"original_file": file.filename, "pdf_file": pdf_filename, "status": "success"}
注意事项
- 服务器必须安装Microsoft Office(Word/Excel),
comtypes依赖Office的COM组件才能运行 - 部署时需配置合适的用户权限,Office COM组件对权限要求较高
- 务必保留异常处理逻辑,防止Office进程在后台残留占用系统资源
内容的提问来源于stack exchange,提问作者Zesshi
相关产品推荐
相关产品推荐

