2015-11-26 50 views
5

我正在使用Google文档添加功能将文本转换为表格。它允许用户:1)选择一些文本或2)将他们的光标,他们希望里面的文字,并在侧边栏的自定义按钮被点击时,该脚本将:在光标位置插入一张表格到Google文档

  1. 将单行,单在光标位置处的单元格表格或所选文本的起始索引,
  2. 在该单元格内放置用户选择的文本或放置光标的元素的完整文本,
  3. 删除原始选定文本/元素,以便只有表格保持

(本质上,这只是在所选文本或元素周围“绘制”一个表格)

documentation的概述显示可以通过var element = cursor.insertText('ಠ‿ಠ');插入文本,但是没有类似的插入其他元素的方法。因此,我一直试图使用不同程度的成功insertTable(childIndex, cells)。关注用户将光标置于元素内部的情况,我可以插入一个正确文本的表格并删除原始文本,但是我找不到将表格插入正确位置的方法。我曾尝试以下,但无济于事:

  1. var newTable = body.insertTable(cursor.getOffset(), [['Test Text']]); - 这将创建表,但在错误的位置,看似基于其中文本光标置于其插入,通常对文档的开头。

  2. var el = cursor.getElement().asBody(); var newTable = el.insertTable(0, [['Test Text']]); - 这确实没什么

  3. var el = cursor.getElement().getParent().asBody(); var newTable = el.insertTable(0, [['Test Text']]); - 这确实没什么

  4. var el = cursor.getElement(); var parent = el.getParent().getChildIndex(el); var newTable = body.insertTable(parent, [['Test Text']]); - 此插入表在文档的最开始。

甲搜索堆栈溢出的产生this very similar question与插入在光标位置一些占位符文本,然后搜索该插入字符串文件,并把表的建议。我有这个方法有两个主要的担忧:

  1. 我需要修改的文本直接周围插入点,并插入额外的文本似乎是它可以使这更困难,而且
  2. 更重要的是,我还有事不知道如何获得表格插入点的正确位置。

如果任何人都可以扩展占位符文本方法或可以提供新的解决方案,这将是非常有用的。谢谢!

回答

3

我用下面的GAS代码在Google Doc中的当前光标位置插入表格。如果光标位于换行符上,它会更好。

var doc = DocumentApp.getActiveDocument(); 
    var body = doc.getBody(); 
    var cursor = doc.getCursor(); 

    var element = cursor.getElement(); 
    var parent = element.getParent(); 
    //here table is an array of cells like 
    // [[r1c1, r1c2], [r2c1, r2c2]] 
    body.insertTable(parent.getChildIndex(element) + 1, table); 

编辑:为了获得在谷歌文档光标位置运作一个更好的了解,我建议你运行下面的光标检查GitHub的项目

https://github.com/google/google-apps-script-samples/tree/master/cursor_inspector

1

TL; DR:使用代码下面的代码段。

看起来Google Docs在选择“插入”>“表格”时会执行的操作是将当前段落分成两段,然后在两段之间插入一个新表格。

困难的部分是将段落分成两部分。我试图通过几种方式来实现这一点。我无法从Google Apps脚本文档找到任何API调用(电子表格API在Range对象上有moveTo()方法,但这不能帮助我们)。我希望能够将段落中给定位置的元素复制到另一段中,并删除原稿。但是,由于Document Service does not allow explicit insertion of several element types只能在原地进行操作,如Equation元素,因此无法一一复制这些元素。

幸运的是,Paragraph有一个copy()方法执行深度复制。因此,我接下来要复制整个段落,从原始段落中的光标位置向前移除所有内容,并删除光标所在段落副本中的所有内容。这样,你就可以在中间分割段落,并且可以在需要的位置插入一个表格。它的作用方式与ListItem相同。

下面是函数splitParagraphAt()的代码,该函数返回新创建的段落(或列表项,它是原始段的下一个兄弟元素)。我在代码中进行了一些额外的检查,以确定它所做的是您认为正在做什么。接下来,我添加了一个简短代码摘录,说明如何在当前光标位置插入一张表。有人可能会使用splitParagraphAt()类似于在光标位置插入任何元素。我没有彻底测试过,所以任何输入都是可以接受的。

/** 
* Splits the contents of the paragraph (or list item) at the given position, 
* producing two adjacent paragraphs (or list items). This function may be used 
* to insert any kind of element at an arbitrary document position, but placing 
* it immediately before the second paragraph (or list item). 
* 
* @param {Position} pos The position where the paragraph (or list item) should 
*  be split. `pos.getElement()` should be either a Text, Paragraph or 
*  ListItem object. 
* 
* @returns {ContainerElement} The second (newly created) Paragraph or ListItem 
*  object. 
* 
*/ 
function splitParagraphAt(pos) { 
    var el = pos.getElement(), offset = pos.getOffset(); 

    var inParagraph = (el.getType() == DocumentApp.ElementType.PARAGRAPH || el.getType() == DocumentApp.ElementType.LIST_ITEM); 

    if (!inParagraph && (el.getType() != DocumentApp.ElementType.TEXT)) { 
    throw new Error("Position must be inside text or paragraph."); 
    } 

    var par; 
    if (inParagraph) { 
    // in this case, `offset` is the number of child elements before this 
    // Position within the same container element 
    par = el; 
    if (offset == par.getNumChildren()) { 
     // we're at the end of the paragraph 
     return par.getParent().insertParagraph(
     par.getParent().getChildIndex(par) + 1, ""); 
    } 
    el = par.getChild(offset); 
    } 
    else { 
    par = el.getParent(); 

    if (par == null || (par.getType() != DocumentApp.ElementType.PARAGRAPH && par.getType() != DocumentApp.ElementType.LIST_ITEM)) { 
     throw new Error("Parent of text is not a paragraph or a list item."); 
    } 
    } 

    var parContainer = par.getParent(); 

    if (!("insertParagraph" in parContainer)) { 
    throw new Error("Cannot insert another paragraph in this container."); 
    } 

    // This assumes the given position is in the current document. 
    // alternatively, one may traverse through parents of par until document 
    // root is reached. 
    var doc = DocumentApp.getActiveDocument(); 

    var elIndex = par.getChildIndex(el); 
    var newPar = par.copy(); 

    var newEl = newPar.getChild(elIndex); 

    // remove everything up to position from the new element 
    if (!inParagraph && (offset != 0)) { 
    newEl.deleteText(0, offset-1); 
    } 
    newEl = newEl.getPreviousSibling(); 
    while (newEl != null) { 
    // get the previous sibling before we remove the element. 
    var prevEl = newEl.getPreviousSibling(); 
    newEl.removeFromParent(); 
    newEl = prevEl; 
    } 

    // since we might remove el itself, we get the next sibling here already 
    var nextEl = el.getNextSibling(); 

    // remove everything from position onwards in the original element 
    if (!inParagraph && (offset != 0)) { 
    el.deleteText(offset, el.getText().length-1); 
    } 
    else { 
    // we're at the beginning of the text (or just before a paragraph 
    // subelement) and need to remove the entire text/subelement. 
    el.removeFromParent(); 
    } 

    el = nextEl; 
    while (el != null) { 
    // get the next sibling before we remove the element. 
    nextEl = el.getNextSibling(); 
    el.removeFromParent(); 
    el = nextEl; 
    } 

    // actually insert the newly created paragraph into the document tree. 
    switch (par.getType()) { 
    case DocumentApp.ElementType.PARAGRAPH: 
     parContainer.insertParagraph(parContainer.getChildIndex(par)+1, newPar); 
     break; 
    case DocumentApp.ElementType.LIST_ITEM: 
     parContainer.insertListItem(parContainer.getChildIndex(par)+1, newPar); 
     break; 
    } 


    return newPar; 
} 

下面是在光标位置插入一个表格并设置在表中的第一个单元格中的光标位置的代码摘录:

var doc = DocumentApp.getActiveDocument(); 
var cursor = doc.getCursor(); 
var el = (cursor.getOffset() == 0? cursor.getElement() : splitParagraphAt(cursor)); 
var parentEl = el.getParent(); 
var table = parentEl.insertTable(parentEl.getChildIndex(el), [['ಠ‿ಠ']]); 
doc.setCursor(doc.newPosition(table.getCell(0, 0), 0)); 

注意,这里仍然需要一些额外的检查看看有没有选择,等等。具体来说,这个假设cursor不会是null

相关问题