You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 23:03:23