Search code examples
javascriptgoogle-apps-scriptgoogle-docs

How to copy and edit text data inside a table cell in Google Documents using Google Apps Script


I'm new to Google Apps Script and have been stuck in this problem for several days. Thanks in advance to those who are looking at this trying to help me.

I'm trying to copy text data from a certain table cell, divide them with line breaks and put them into variables, and use them in another table. With tablecell.getText() you would lose all the format, so I want to use Paragraphs instead, but with table cell you couldn't use getParagraphs()...

tableCellOut.appendParagraph(tableIn.getRow(1).getChild(1).asParagraph());

I have no idea how close I am to my goal. Is there a way you could edit text data without losing the format?

This is the image of the tables before and after


Solution

  • I believe your goal as follows.

    • You want to achieve the conversion of table cells as the image shown in your question using Google Apps Script. (The following image is from your question.)

    For this, how about this answer? I would like to propose the following sample script for achieving your issue. The flow of this script is as follows.

    1. Retrieve table.
    2. Retrieve the cell "B2" of the table.
      • This is from your sample image.
    3. Create an object including the text and text styles.
      • This is used for splitting values to the cells.
    4. The text and text styles are set to the cells.
    5. When the number of rows are smaller than the number of rows of splitted values, the new rows are appended and the text and text styles are set to the cells.

    Sample script:

    Please copy and paste the following script to the container-bound script of the Google Document, and run the function of myFunction at the script editor. In this script, row and column are the row and column numbers, respectively. So in your image, please set row = 2 and column = 2. For example, when you want to split the cell "C3", please set row = 3 and column = 3.

    function myFunction() {
      // 1. Retrieve table.
      const body = DocumentApp.getActiveDocument().getBody();
      const table = body.getTables()[0];
      
      // 2. Retrieve the cell "B2" of the table.
      const row = 2;  // Please set the row number.
      const column = 2;  // Please set the column number.
      const cell = table.getCell(row - 1, column - 1);
      
      // 3. Create an object including the text and text styles. This is used for splitting values to the cells.
      const text = cell.editAsText();
      let temp = [];
      const textRuns = [].reduce.call(text.getText(), (ar, c, i, a) => {
        if (c != "\n") temp.push({text: c, foregroundColor: text.getForegroundColor(i), backgroundColor: text.getBackgroundColor(i), textAlignment: text.getTextAlignment(i), italic: text.isItalic(i)});
        if (c == "\n" || i == a.length - 1) {
          ar.push({text: temp.reduce((s, {text}) => s += text, ""), styles: temp});
          temp = [];
        }
        return ar;
      }, []);
      
      // 4. The text and text styles are set to the cells.
      for (let i = row - 1; i < table.getNumRows(); i++) {
        const t = table.getCell(i, column - 1).editAsText();
        const run = textRuns.shift();
        t.setText(run.text);
        run.styles.forEach((r, j) => {
          t.setBackgroundColor(j, j, r.backgroundColor);
          t.setForegroundColor(j, j, r.foregroundColor);
          t.setItalic(j, j, r.italic);
          if (r.textAlignment) t.setTextAlignment(j, j, r.textAlignment);
        });
      }
      
      // 5. When the number of rows are smaller than the number of rows of splitted values, the new rows are appended and the text and text styles are set to the cells.
      while (textRuns.length > 0) {
        const appendedRow = table.appendTableRow();
        for (let i = 0; i < table.getRow(row - 1).getNumCells(); i++) {
          appendedRow.appendTableCell("");
        }
        const t = appendedRow.getCell(column - 1).editAsText();
        const run = textRuns.shift();
        t.setText(run.text);
        run.styles.forEach((r, j) => {
          t.setBackgroundColor(j, j, r.backgroundColor);
          t.setForegroundColor(j, j, r.foregroundColor);
          t.setItalic(j, j, r.italic);
          if (r.textAlignment) t.setTextAlignment(j, j, r.textAlignment);
        });
      }
    }
    

    Result:

    When above script is run for your initial table, the following result can be obtained. In this demonstration, at first, the values of cell "B2" are expanded, and then, the values of cell "C3" are expanded.

    enter image description here

    Note:

    • This sample script is prepared for above situation. If your specification of above image is changed, the script might not be able to be used. So please be careful this.
    • In this sample script, BackgroundColor and ForegroundColor are used as the text styles. When you want to use other text styles, please modify above script.

    References: