在使用 python 中的 google 文档 API 使用 gdoctableapp 模块创建 table 时出现无效 table 起始位置错误

Invalid table start location error while using gdoctableapp module to create table using google docs API in python

我正在尝试使用 google 文档 API 创建通用文档。我正在插入边框不可见的图像和动态 table。Tanaike's solution 但在这里我将所有请求附加到一个请求中,然后插入到文档中,但是在执行以下代码后出现错误:

import io
from gdoctableapppy import gdoctableapp

SERVICE_FILENAME = 'C:/Users/XYZ/service_account.json'  # set path to service account filename

from googleapiclient.discovery import build
from google.oauth2 import service_account
from googleapiclient.http import MediaIoBaseDownload, MediaFileUpload

credentials = service_account.Credentials.from_service_account_file(SERVICE_FILENAME,
                                                                    scopes=['https://www.googleapis.com/auth/drive',
                                                                            'https://www.googleapis.com/auth/documents']
                                                                    )
docs = build('docs', 'v1', credentials=credentials)
drive = build('drive', 'v3', credentials=credentials)


def create_file(file_name):
    file_metadata = {
        "title": file_name,
        "body": {}
    }

    file = docs.documents().create(body=file_metadata).execute()
    print('File ID: %s' % file.get('documentId'))
    file_id = file.get('documentId')
    try:
        permission = {
            "role": "writer",
            "type": "user",
            'emailAddress': 'xyz@gmail.com'
        }
        result = drive.permissions().create(fileId=file_id, body=permission).execute()
        print(result)
        return file_id
    except Exception as e:
        print('An error occurred:', e)
    return None


def insert_data(file_id):
    requests = []
    requests.append(insert_image())
    requests.append(insert_text(2, '\n'))
    requests.append(insert_text(3, 'text'))
    values = [['Name of the Client/Organization', 'XYZ'], ['Industry', 'Software']]
    requests.append(insert_table_data(file_id, values))

    result = docs.documents().batchUpdate(documentId=file_id, body={'requests': requests}).execute()


def insert_image():
    image_data = {
        'insertInlineImage': {
            'location': {
                'index': 1
            },
            'uri':
                'https://www.oberlo.com/media/1603970279-pexels-photo-3.jpg?fit=max&fm=jpg&w=1824',
            'objectSize': {
                'height': {
                    'magnitude': 350,
                    'unit': 'PT'
                },
                'width': {
                    'magnitude': 350,
                    'unit': 'PT'
                }
            }

        }
    }
    return image_data


def insert_text(index, text):
    text_data = {
        "insertText":
            {
                "text": text,
                "location":
                    {
                        "index": index
                    }
            }
    }

    return text_data


def insert_table_data(file_id, values):
    documentId = file_id
    resource = {
        "oauth2": credentials,
        "documentId": documentId,
        "rows": len(values),
        "columns": len(values[0]),
        "append": True,
        "values": values,
    }
    gdoctableapp.CreateTable(resource)
    resource = {
        "oauth2": credentials,
        "documentId": documentId,
    }
    res = gdoctableapp.GetTables(resource)
    obj = {"color": {"color": {}}, "dashStyle": "SOLID", "width": {"magnitude": 0, "unit": "PT"}}
    data = {
        "updateTableCellStyle": {
            "tableCellStyle": {
                "borderBottom": obj,
                "borderTop": obj,
                "borderLeft": obj,
                "borderRight": obj,
            },
            "tableStartLocation": {
                "index": res['tables'][-1]['tablePosition']['startIndex']
            },
            "fields": "borderBottom,borderTop,borderLeft,borderRight"
        }
    }
    # docs.documents().batchUpdate(documentId=documentId, body={'requests': requests}).execute()
    return data


def download_as_docx(file_id):
    results = drive.files().get(fileId=file_id, fields="id, name, mimeType, createdTime").execute()
    docMimeType = results['mimeType']
    mimeTypeMatchup = {
        "application/vnd.google-apps.document": {
            "exportType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docExt": "docx"
        }
    }
    exportMimeType = mimeTypeMatchup[docMimeType]['exportType']
    # docExt = mimeTypeMatchup[docMimeType]['docExt']
    docName = results['name']
    request = drive.files().export_media(fileId=file_id,
                                         mimeType=exportMimeType)  # Export formats : https://developers.google.com/drive/api/v3/ref-export-formats
    # fh = io.FileIO(docName + "." + docExt, mode='w')
    fh = io.FileIO(docName, mode='w')
    downloader = MediaIoBaseDownload(fh, request)
    done = False
    while done is False:
        status, done = downloader.next_chunk()
        print("Download %d%%." % int(status.progress() * 100))


def download_as_pdf(file_id, file_name):
    request = drive.files().export_media(fileId=file_id,
                                         mimeType='application/pdf')
    fh = io.BytesIO()
    downloader = MediaIoBaseDownload(fh, request)
    done = False
    while done is False:
        status, done = downloader.next_chunk()
        print("Download %d%%." % int(status.progress() * 100))
    fh.seek(0)
    filename = file_name.split('.docx')[0] + '.pdf'
    with open(filename, 'wb') as fx:
        fx.write(fh.getvalue())


def delete_gdrive_file(file_id):
    """Deleted file on Google Drive
    :param file_id: ID of Google Drive file
    """
    response = drive.files().delete(fileId=file_id).execute()
    print(response)


if __name__ == '__main__':
    file_name = 'Data.docx'
    file_id = create_file(file_name)
    insert_data(file_id)
    download_as_docx(file_id)
    download_as_pdf(file_id, file_name)
    delete_gdrive_file(file_id)

错误:

googleapiclient.errors.HttpError: <请求时出现 HttpError 400 https://docs.googleapis.com/v1/documents/1Qsf3CRKiIS9Ayjws1GEhg5oGiZbrTBAObMsifxdfre:b atchUpdate?alt=json 返回“无效请求 [3].updateTableCellStyle:提供的 table 起始位置无效。”。详细信息:“无效请求[3].up dateTableCellStyle: 提供的 table 起始位置无效。">

当我看到你的脚本在table被gdoctableapp追加后,文本和图片是从文档顶部插入的,删除边框的请求是运行。这样,附加的 table 的索引就不同了。所以会出现这样的错误。我认为这就是您遇到问题的原因。为了消除这个问题,下面的修改怎么样?

发件人:

def insert_data(file_id):
    requests = []
    requests.append(insert_image())
    requests.append(insert_text(2, '\n'))
    requests.append(insert_text(3, 'text'))
    values = [['Name of the Client/Organization', 'XYZ'], ['Industry', 'Software']]
    requests.append(insert_table_data(file_id, values))

    result = docs.documents().batchUpdate(documentId=file_id, body={'requests': requests}).execute()

收件人:

def insert_data(file_id):
    requests = []
    values = [['Name of the Client/Organization', 'XYZ'], ['Industry', 'Software']]
    requests.append(insert_table_data(file_id, values))
    requests.append(insert_image())
    requests.append(insert_text(2, '\n'))
    requests.append(insert_text(3, 'text'))

    result = docs.documents().batchUpdate(documentId=file_id, body={'requests': requests}).execute()