使用Google Drive API导出/下载PDF时触发FileNotExportable等错误
问题描述
在使用Google Drive API导出/下载PDF文件时,调用export_media()会报错提示“仅支持Docs编辑器文件”,调用get_media()又提示“仅二进制内容文件可下载,请对Docs编辑器文件使用Export”,两种方法均在next_chunk()调用后触发错误。已确认凭证有效,文件名含空格排除为问题原因,询问遗漏的配置或操作。
错误原因分析
这两个错误的核心是未根据文件的实际类型选择正确的方法:
export_media()仅适用于Google Docs原生编辑器文件(如Google Docs/Sheets/Slides,对应MIME类型为application/vnd.google-apps.document/spreadsheet/presentation等),用于将这类原生文件导出为PDF等格式。get_media()仅适用于二进制文件(如已上传的PDF、图片等,对应MIME类型为application/pdf等),用于直接下载文件原始内容。
你的情况说明:你主观认为操作的是PDF文件,但该文件的实际MIME类型可能是Google Docs原生类型(比如通过Google编辑器创建后转存为PDF,但实际仍保留原生文档属性),导致两种方法都不匹配。
解决方案:先判断文件实际类型,再选择对应方法
解决思路是先调用Drive API获取文件的实际MIME类型,再根据类型自动选择export_media()或get_media()。
修改后的完整代码
import io from googleapiclient.discovery import build from googleapiclient.errors import HttpError def get_file_mime_type(creds, file_id): """获取文件的实际MIME类型""" service = build("drive", "v3", credentials=creds) file = service.files().get(fileId=file_id, fields="mimeType").execute() return file["mimeType"] def handle_pdf_download(creds, file_id, destination): """根据文件类型自动选择导出或下载方法""" try: mime_type = get_file_mime_type(creds, file_id) service = build("drive", "v3", credentials=creds) file_buffer = io.BytesIO() # 判断文件类型:如果是Google原生编辑器文件,用export;否则用get_media if mime_type.startswith("application/vnd.google-apps."): # 导出为PDF request = service.files().export_media(fileId=file_id, mimeType="application/pdf") downloader = io.MediaIoBaseDownload(file_buffer, request) else: # 直接下载二进制文件 request = service.files().get_media(fileId=file_id) downloader = io.MediaIoBaseDownload(file_buffer, request) done = False while not done: status, done = downloader.next_chunk() # 写入本地文件 with open(destination, 'wb') as f: f.write(file_buffer.getbuffer()) except HttpError as error: print(f"操作失败: {error}")
调用示例
dst = "Colab Notebooks/My File 04-24-24.pdf" file_id = "你的文件ID" creds = "你的凭证对象" handle_pdf_download(creds=creds, file_id=file_id, destination=dst)
关键说明
- 通过
files().get()获取mimeType字段,能准确判断文件的实际类型,避免主观判断错误。 - Google原生编辑器文件的MIME类型均以
application/vnd.google-apps.开头,统一用export_media()导出为PDF;其他类型直接用get_media()下载。
内容的提问来源于stack exchange,提问作者Binx
相关产品推荐
相关产品推荐

