使用Google Drive API下载电子表格所有标签页内容的方法
问题根源
你现有代码仅能导出第一个标签页,是因为text/csv属于单表存储格式,Google Drive的export_media接口导出CSV时默认只返回电子表格的第一个工作表,本身不支持一次性导出多sheet内容到单个CSV文件。
根据你的输出需求,可以选择以下两种方案修改:
方案1:导出为XLSX格式(推荐,完整保留全表内容)
如果不需要强制使用CSV格式,直接导出为XLSX是改动最小的方案,XLSX原生支持多工作表,一次请求即可拿到所有标签页的完整内容、结构。
修改后的代码如下:
import io from googleapiclient.http import MediaIoBaseDownload from googleapiclient.errors import HttpError def download_full_spreadsheet(real_file_id, service, output_path='full_spreadsheet.xlsx'): try: # mimeType改为XLSX对应类型,支持全表导出 request = service.files().export_media( fileId=real_file_id, mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) file = io.BytesIO() downloader = MediaIoBaseDownload(file, request) done = False while not done: status, done = downloader.next_chunk() print(f'下载进度 {int(status.progress() * 100)}%') # 二进制写入本地文件,替换原有的追加模式避免重复写入 with open(output_path, 'wb') as f: f.write(file.getvalue()) return file.getvalue() except HttpError as error: print(f'导出发生错误: {error}') return None # 调用示例 # download_full_spreadsheet(real_file_id='XXXXXXXXXXXXXXXXXXXXX', service=service)
方案2:必须输出CSV格式时,逐工作表导出
如果业务要求必须输出CSV格式,需要先拉取电子表格下所有工作表的ID,逐个指定sheet导出,每个sheet单独存储为CSV文件。
注意:使用该方案需要提前在Google Cloud控制台启用Google Sheets API,初始化service时添加Sheets只读权限scope:https://www.googleapis.com/auth/spreadsheets.readonly
代码如下:
import io from googleapiclient.http import MediaIoBaseDownload from googleapiclient.errors import HttpError def download_all_sheets_csv(real_file_id, service): try: # 拉取电子表格的所有工作表元信息 spreadsheet_info = service.spreadsheets().get(spreadsheetId=real_file_id).execute() sheet_list = spreadsheet_info.get('sheets', []) for sheet in sheet_list: sheet_prop = sheet['properties'] sheet_name = sheet_prop['title'] sheet_gid = sheet_prop['sheetId'] print(f'正在导出工作表: {sheet_name}') # 传gid参数指定要导出的工作表 request = service.files().export_media( fileId=real_file_id, mimeType='text/csv', params={'gid': sheet_gid} ) file = io.BytesIO() downloader = MediaIoBaseDownload(file, request) done = False while not done: status, done = downloader.next_chunk() print(f'{sheet_name} 下载进度 {int(status.progress() * 100)}%') # 按sheet名命名文件,避免覆盖 with open(f'test_{sheet_name}.csv', 'w', encoding='utf-8') as f: f.write(file.getvalue().decode('utf-8')) print("所有工作表导出完成") except HttpError as error: print(f'导出发生错误: {error}') # 调用示例 # download_all_sheets_csv(real_file_id='XXXXXXXXXXXXXXXXXXXXX', service=service)
原有代码问题修正
- 原代码写文件用
a追加模式,多次运行会重复往同一个文件追加内容,改为w写入模式更合理 - 原代码没有处理接口报错时
file为None的场景,直接调用file.getvalue()会触发空指针异常,修改后的代码增加了异常分支判断,避免运行报错。
内容的提问来源于stack exchange,提问作者pterodactella
相关产品推荐
相关产品推荐

