2015-11-26 74 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

相關問題