使用pdf2docx转换PDF至DOCX失败,求助无本地存储解决方案
问题解决:pdf2docx转换时的"bad filename"错误
错误原因
你遇到的TypeError: bad filename是因为pdf2docx.Converter(底层依赖PyMuPDF的fitz.Document)无法直接处理原始字节串。代码中cv = Converter(pdf_stream.read())传入的是pdf_stream.read()返回的字节内容,而它需要的是文件路径、已打开的文件对象或BytesIO流对象。
修复步骤
1. 修正Converter的参数
直接传入BytesIO对象而非字节串,无需调用read():
# 原错误代码 cv = Converter(pdf_stream.read()) # 修改后代码 cv = Converter(pdf_stream)
注意:刚创建的BytesIO(response.content)默认文件指针在起始位置,无需额外调整。
2. 可选优化建议
- 改用异步HTTP客户端:在FastAPI异步函数中使用同步
requests.get会阻塞事件循环,换成aiohttp提升性能:import aiohttp # 替换原requests.get逻辑 async with aiohttp.ClientSession() as session: async with session.get(urls) as response: pdf_content = await response.read() pdf_stream = BytesIO(pdf_content) - 提前初始化Firebase:不要在每次请求中重复初始化Firebase应用,将初始化代码放在函数外部:
# 文件顶部、函数外执行 firebase = pyrebase.initialize_app(firebase_config) storage = firebase.storage() - 无需手动关闭BytesIO:内存中的
BytesIO对象无需手动调用close(),Python会自动回收资源。
修改后的完整代码
from fastapi import Request from pydantic import BaseModel from typing import Union, List, Dict import os from io import BytesIO import aiohttp import pyrebase from pdf2docx import Converter # 提前初始化Firebase应用 firebase_config = {} # 填入你的Firebase配置 firebase = pyrebase.initialize_app(firebase_config) storage = firebase.storage() class PDFManipulationRequest(BaseModel): urls: Union[str, List[str]] user: Dict = {} rename_file: str = "" pages: List[int] = [] rotation: Dict = {} password: str = "" metadata: Dict async def pdf_to_word(request: Request, data: PDFManipulationRequest): urls = data.urls metadata = data.metadata filename = metadata["name"] filename_without_extension = os.path.splitext(filename)[0] # 异步下载PDF文件 async with aiohttp.ClientSession() as session: async with session.get(urls) as response: pdf_content = await response.read() pdf_stream = BytesIO(pdf_content) # 初始化转换器,传入BytesIO流对象 cv = Converter(pdf_stream) output_doc_stream = BytesIO() cv.convert(output_doc_stream, start=0, end=None) cv.close() # 设置Firebase存储路径 folder_name = "pdf-to-word/modified" destination_path = f"{folder_name}/{filename_without_extension}.docx" # 上传转换后的DOCX文件 storage.child(destination_path).put(output_doc_stream.getvalue()) # 获取文件下载URL docx_url = storage.child(destination_path).get_url(None) return docx_url
内容的提问来源于stack exchange,提问作者Rayyan Alam
相关产品推荐
相关产品推荐

