【问题标题】:Avoid calculating startIndex and endIndex when creating a document using Google Docs API使用 Google Docs API 创建文档时避免计算 startIndex 和 endIndex
【发布时间】:2020-02-01 15:45:31
【问题描述】:

我已经向自己证明,我可以使用以下代码将文本插入到 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 来告知自己这一观点

我尝试创建的文档非常动态且非常复杂,将编码挑战交给 api 用户而不是 api 设计者来跟踪索引值似乎很奇怪。

有没有一种方法或更高级别的 api,可以让我在没有这种内务管理的情况下构建文档?

【问题讨论】:

  • 我必须为我糟糕的英语水平道歉。关于Is there an approach, or a higher level api, that allows me construct a document without this kind of house keeping?,我无法理解。我能问一下你的目标吗?我认为,当我能够正确地看到您的目标愿景时,考虑解决方案和解决方法可能会有所帮助。
  • 当然@Tanaike。我想编写一个软件来创建一个新的谷歌文档,插入一个包含许多行和单元格的复杂表格,其中可能包含一些图像、一些文本等。我​​不喜欢我需要跟踪的事实当我插入表格、表格行、表格单元格、图像、文本、文本、文本、表格行、表格单元格等时,所有位置的索引。我想找到一个可以为我做这些的 api。
  • 感谢您的回复。从您的回复中,您希望创建一个表格,其中包含 Google Document with Docs API 的值。你想在不使用每个元素的索引的情况下实现这一点。我可以这样理解。如果我的理解是正确的,不幸的是,在当前阶段,我认为在 Docs API 中没有直接实现您的目标的方法。因此,作为一种解决方法,如何将 append 方法与 Google Apps 脚本一起使用?在这种情况下,使用Web Apps,并且可以通过请求运行脚本。如果这不是您想要的方向,我很抱歉。
  • 不用担心@Tanaike。我最初的实验是使用 Google App Script api,我发现它可以工作。但我需要在服务器上创建我的文档,无需人工参与。所以我转向了 Google Docs api。男孩让我失望了。我正在构建一个为我管理索引值的谷歌文档模型,但提供了一个附加样式 api。不得不这样做只是一种痛苦。
  • this 对您有帮助吗? “通过向后写来简化问题。 为了避免必须预先计算这些偏移更改,请将插入排序为“向后写”:首先在编号最高的索引处进行插入,每次插入都从头开始。这种排序确保每次写入的偏移量都不受前面的影响。”顺便说一句,您可以在 Apps 脚本中设置一个服务帐户,这样您就可以在没有人工干预的情况下使用它。

标签: google-docs-api


【解决方案1】:

遗憾的是,简短的回答是否定的,没有 API 可以让您绕过基本 Google Docs API 所需的索引跟踪 - 至少在构建表格时是这样。

我最近不得不自己解决这个问题 - 模板更新和文档构建的组合 - 我基本上最终编写了一个带有辅助函数的中间 API 来搜索和插入字符索引。

例如,我一直在创建表格时使用的一个技巧是首先在给定索引处创建一个指定大小的表格,然后在第一个单元格中放置一些文本。然后我可以在文档对象中搜索包含该文本的tableCells 元素,然后从那里返回以获取表开始索引。

另一个技巧是,如果您知道文档中有多少种特定类型的对象(例如表格),您可以解析整个文档对象并跟踪表格数量,并在到达您想要的对象时停止想要更新/删除(您也可以使用这种方法进行创建,但我发现目标文本方法更容易)。

通过一些 JSON 解析和反复试验,您可以找出表格中每个单元格的起始索引,并编写函数以编程方式查找和创建/替换/删除。如果有更简单的方法来完成这一切,我还没有找到。有one Github repo with a Google Docs API wrapper specifically for tables,它看起来确实很活跃,虽然我是在我自己写完所有东西之后发现的,我没有使用它。)

这里有一些代码可以帮助您入门:

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']

假设您已经创建了一个包含目标文本的表格:现在,首先从 API 中提取文档 JSON 对象,然后使用get_target_table() 查找与表格相关的 JSON 块。

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

从那里您将看到嵌套的tableRowstableCells 对象,每个单元格内的content 都有一个startIndex。构造一个表格单元格起始索引的矩阵,然后,为了填充它们,从右下角的单元格向后工作到左上角,以避免替换您存储的索引(如文档和其中一个 cmets 中所建议的那样)。

这绝对是一个艰难的过程。并且样式表单元格是一个完整的“另一种野兽”,这是一个令人眼花缭乱的 JSON 选项迷宫。 Docs API 站点上的交互式 JSON 构造器工具对于获取语法编写很有用。

希望这会有所帮助,祝你好运!

【讨论】:

  • 嘿@andrew_reece 我在运行代码时遇到 KeyError: 'textRun'。
  • 您可能有一个没有这种段落元素的文档 - 没有详细信息很难调试,但这里是 TextRun API 规范:developers.google.com/docs/api/reference/rest/v1/…
  • 毕竟我使用了 github 包装器,它的工作完美无缺。
【解决方案2】:

我得到的答案:您可以在不使用 JSON 架构的情况下创建 Docs。

https://developers.google.com/drive/api/v3/manage-uploads#node.js_1

因此,以您选择的格式(HTML、DocX、MD(您将使用 pandoc 将 MD 转换为另一种格式))创建文档,然后上传。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多