【问题标题】:How to Convert XLSX to Sheets in Google Drive API v3如何在 Google Drive API v3 中将 XLSX 转换为表格
【发布时间】:2016-04-29 23:15:18
【问题描述】:

当我将 xlsx 文件与我的代码一起上传到 Google 云端硬盘时,我想将它们自动转换为 Google 电子表格。但是,虽然转换对 csv 文件有效,但我得到:

<HttpError 400 when requesting https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&alt=json returned "Bad Request">

尝试上传 xlsx 时。

这是我的代码:

def upload_service(filepath, name="", description="", fileID="", parentID=""):
    """ Uses a Resource (service) object to upload a file to drive. """

    if service == "": authenticate_service()

    if name == "":
        name = str(os.path.basename(filepath).split(os.extsep)[0])   # Get from filepath

    extension = str(os.path.basename(filepath).split(os.extsep)[1]).lower()

    if extension == "csv":                  # CSV
        mime_type = "text/csv"
    elif extension in ["xls", "xlsx"]:      # EXCEL
        mime_type = "application/ms-excel"
    else:
        return

    media_body = MediaFileUpload(filepath, mimetype=mime_type, resumable=True)

    if parentID == "":
        meta = dict(name=name, mimeType="application/vnd.google-apps.spreadsheet", description=description)
    else:
        meta = dict(name=name, mimeType="application/vnd.google-apps.spreadsheet", description=description, parents=[parentID])

    if fileID == "":   # CREATE 
        upload = service.files().create(
                                    body=meta,
                                    media_body=media_body).execute()
    else:   # REPLACE
        upload = service.files().update(
                                body=meta,
                                media_body=media_body,
                                fileId=fileID).execute()

    print ("\nFINISHED UPLOADING")

如何在 v3 中做到这一点?在 v2 中如何做到这一点非常清楚,但在更新的 API 中却没有。

【问题讨论】:

    标签: python excel google-api google-drive-api google-api-python-client


    【解决方案1】:

    在 APIv3 中,您需要指定一个非常具体的 MIME 类型才能进行转换。

    https://developers.google.com/drive/v3/web/manage-uploads#importing_to_google_docs_types_wzxhzdk8wzxhzdk9,您会注意到“支持的转换在 About 资源的 importFormats 数组中动态可用”的语句。使用任一方法获取importFormats 列表

    GET https://www.googleapis.com/drive/v3/about?fields=importFormats&amp;key={YOUR_API_KEY}

    或转至https://developers.google.com/drive/v3/reference/about/get#try-it 并输入importFormats

    您会在回复中注意到:

    "application/vnd.ms-excel": [
       "application/vnd.google-apps.spreadsheet"
    ]
    

    在您的代码中,使用:

    elif extension in ["xls", "xlsx"]:      # EXCEL
        mime_type = "application/vnd.ms-excel"
    

    (注意额外的vnd.)它应该可以正常工作!

    【讨论】:

      【解决方案2】:

      根据Official Google Documentation,您收到400: Bad Request,表示未提供必填字段或参数,提供的值无效或提供的字段组合无效。尝试添加将在目录图中创建循环的父级时,可能会引发此错误。

      遇到此错误时,建议的操作是使用exponential backoff。它是网络应用程序的标准错误处理策略,其中客户端在越来越长的时间内定期重试失败的请求。

      您可以参考谷歌官方Docs,有一个参数convertconvert=true,可以将文件转换成对应的谷歌文档格式(默认:false)。

      您还需要使用Python client library,您可以使用该库来支持上传文件。

      找到这张 Stack Overflow 票,查看社区提供的解决方案:python + google drive: upload xlsx, convert to google sheet, get sharable link

      【讨论】:

      • 您引用的参数是 Google v2 选项,而这个问题是指 v3。 Google v3 不提供该参数,docs 建议的方法不起作用。
      【解决方案3】:
      def uploadExcel(excelFileName):
         file_metadata = {'name': excelFileName, 'parents': [folderId], 'mimeType': 'application/vnd.google-apps.spreadsheet'}
         media = MediaFileUpload(excelFileName, mimetype='application/vnd.ms-excel', resumable=True)
         file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
      

      【讨论】:

        【解决方案4】:

        要具备的逻辑是:我们想从 excel 格式创建一个电子表格

        所以我们完全按照这个逻辑进行编码(C# 的示例):

        Google.Apis.Drive.v3.Data.File fileMetadata = new Google.Apis.Drive.v3.Data.File();
                    fileMetadata.Name = System.IO.Path.GetFileName(file_being_uploaded);
                    fileMetadata.Description = "File created via Google Drive API C#";
                    fileMetadata.MimeType = "application/vnd.google-apps.spreadsheet";
                    fileMetadata.Parents = new List<string> { _parent };    // if you want to organize in some folder       
        
                    // File content.
                    byte[] byteArray = System.IO.File.ReadAllBytes(file_being_uploaded);
                    System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
                    try
                    {
                        FilesResource.CreateMediaUpload request = _service.Item1.Files.Create(fileMetadata, stream, GetMimeType(file_being_uploaded));
        (...)
        
            // gets us the Excel Mime
            private static string GetMimeType(string fileName)
            {
                string mimeType = "application/unknown";
                string ext = System.IO.Path.GetExtension(fileName).ToLower();
                Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
                if (regKey != null && regKey.GetValue("Content Type") != null)
                    mimeType = regKey.GetValue("Content Type").ToString();
                return mimeType;
            }
        

        【讨论】:

          猜你喜欢
          • 2019-07-04
          • 2017-10-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-13
          • 1970-01-01
          相关资源
          最近更新 更多