Избегайте расчета startIndex и endIndex при создании документа с помощью Google Docs API - PullRequest
1 голос
/ 01 февраля 2020

Я доказал себе, что могу вставить текст в документ Google Docs, используя этот код:

function appendToDocument() {
    let offset = 12;
    let updateObject = {
        documentId: 'xxxxxxx',
        resource: {
            requests: [{
                "insertText": {
                    "text": "John Doe",
                    "location": {
                        "index": offset,
                    },
                },
            }],
        },
    };
    gapi.client.docs.documents.batchUpdate(updateObject).then(function(response) {
        appendPre('response =  ' + JSON.stringify(response));
    }, function(response) {
        appendPre('Error: ' + response.result.error.message);
    });
}

Мой следующий шаг - создать целый сложный документ с использованием API. Я ошеломлен тем, что мне кажется, что мне нужно сохранять места в документах, как это

new Location().setIndex(25)

Я информирую себя об этом мнении, прочитав это https://developers.google.com/docs/api/how-tos/move-text

Документ, который я пытаюсь создать, очень динамичен c и очень сложен, и выполнение задачи кодирования для отслеживания значений индекса для пользователя API, а не дизайнера API, кажется странным.

Есть ли подход, или API более высокого уровня, который позволяет мне создавать документ без такого рода ведения домашнего хозяйства?

1 Ответ

1 голос
/ 04 февраля 2020

К сожалению, короткий ответ - нет, нет API, позволяющего обойти отслеживание индексов, необходимое для базового API Google Docs - по крайней мере, когда речь идет о создании таблиц.

Недавно мне пришлось самому заняться этой проблемой - комбинацией обновления шаблонов и построения документа - и в итоге я написал промежуточный API с вспомогательными функциями для поиска и вставки по индексам символов.

Например, один прием, который я использовал для создания таблицы, заключается в том, чтобы сначала создать таблицу указанного размера по заданному индексу и поместить некоторый текст в первую ячейку. Затем я могу найти в объекте документа элемент tableCells, содержащий этот текст, и вернуться к нему, чтобы получить начальный индекс таблицы.

Еще одна хитрость заключается в том, что если вы знаете, сколько конкретно c видов объектов (например, таблиц) у вас есть в документе, вы можете проанализировать весь объект документа и отследить количество таблиц, а затем остановить, когда вы попадаете к тому, который хотите обновить / удалить (вы можете использовать этот подход и для создания, но подход с использованием целевого текста проще, я нахожу).

Оттуда с некоторыми JSON разбором и методом проб и ошибок вы можете определить начальный индекс каждой ячейки в таблице и написать функции для программного поиска и создания / замены / удаления. Если есть более простой способ сделать все это, я не нашел его. Существует один репозиторий Github с оболочкой API Google Docs специально для таблиц , и он действительно активен, хотя я нашел его после того, как написал все самостоятельно и не использовал его.)

Вот небольшой код для начала работы:

def get_target_table(doc, target_txt):
    """ Given a target string to be matched in the upper left column of a table
        of a Google Docs JSON object, return JSON representing that table. """
    body = doc["body"]["content"]
    for element in body:
        el_type = list(element.keys())[-1]
        if el_type == "table":
            header_txt = get_header_cell_text(element['table']).lower().strip()
            if target_txt.lower() in header_txt:
                return element
    return None

def get_header_cell_text(table):
    """ Given a table element in Google Docs API JSON, find the text of
        the first cell in the first row, which should be a column header. """
    return table['tableRows'][0]\
        ['tableCells'][0]\
        ['content'][0]\
        ['paragraph']['elements'][0]\
        ['textRun']['content']

Предполагается, что вы уже создали таблицу с целевым текстом в ней: теперь начнем с вытягивания объекта document JSON из API, а затем используйте get_target_table(), чтобы найти фрагмент JSON, связанный с таблицей.

doc = build("docs", "v1", credentials=creds).documents().get(documentId=doc_id).execute() 
table = get_target_table(doc, "my target")

Оттуда вы увидите вложенные объекты tableRows и tableCells, а content внутри каждой ячейки имеет startIndex. Создайте матрицу начальных индексов ячеек таблицы, а затем, для их заполнения, работайте в обратном направлении от нижней правой ячейки к верхней левой, чтобы избежать смещения сохраненных вами индексов (как предлагается в документах и ​​в одном из комментариев).

Это определенно немного утомительно. А стилизация ячеек таблицы - это целое «другое чудовище», представляющее собой головокружительный лабиринт вариантов JSON. Интерактивный инструмент конструктора JSON на сайте API Docs полезен для записи синтаксиса.

Надеюсь, это поможет, удачи!

...