简体   繁体   中英

Google Apps Script - Docs. Converting table cells with formatting to HTML

I'm creating a Google Script add-on in Docs (not Sheets) which allows people to input content into predefined table cells, which I then later on need to parse and turn into HTML.

I'm almost there, thanks to this answer: https://stackoverflow.com/a/47313357/2586977 and the GoogleDoc2HTML script it mentions. I can get out everything I need, except for the simple formatting that some content will require – bold, italics and links.

The method described in the linked article uses getTextAttributeIndices() to work out where these attribute changes are located, then splices the corresponding HTML tags into the output to replicate the formatting. It's kind of long-winded, but it works!

The problem I have is that getTextAttributeIndices() will only work on [Text][2] elements, and I'm trying to get the indices of content in a [TableCell][3] element.

The console gives me the error message:

TypeError: Cannot find function getTextAttributeIndices in object TableCell.

If do myTableCell.getText() first, I lose all the formatting.

I finally cracked it, so I'm sharing the answer in case anyone else runs into this.

getTextAttributeIndices() only works on Text elements, not TableCell elements.

BUT it turns out that when you create a TableCell element and enter content into it, it implicitly creates a Paragraph element and that contains a Text element.

Therefore this does NOT work:

myTableCell.getTextAttributeIndices()

but this DOES work:

myTableCell.getChild(0).getChild(0).getTextAttributeIndices()

@axemonkey Your solution will work but it's brittle since the documentation does not guarantee that the paragraph element will always be a child element at index 0. Rummaged through the documentation and found this method:

TabelCell::findElement(elementType)

You can use that method to fetch child elements of a given type. It returns a RangeElement which wraps the child element so you have to call the following method:

RangeElement::getElement()


So using the above, a more reliable way to get the paragraph element is this:

var paragraph = tableCell.findElement(DocumentApp.ElementType.PARAGRAPH).getElement();

To get the Text element in the paragraph you can use findElement() on the paragraph instance as well:

var text = paragraph.findElement(DocumentApp.ElementType.TEXT).getElement();

So bringing it all together you'd get:

var paragraph = tableCell.findElement(DocumentApp.ElementType.PARAGRAPH).getElement();
var text = paragraph.findElement(DocumentApp.ElementType.TEXT).getElement();

var indices = text.getAttributeIndices();

There's more code to write, but you'll have more readable code and its less likely break since it does not rely on child indices.


PS: When you invoke the getElement() method on a RangeElement its returns the element, but as far as the Apps Script GUI is concerned you only get auto-completion for properties associated with the Element interface. If you want to get auto-completion for the properties and methods specific to a given element type, then leverage one of the many type casting methods defined in the Element interface. These methods are always prefixed with as . So to get code-completion for the text element you could write code like this:

var text = paragraph.findElement(DocumentApp.ElementType.TEXT).getElement().asText();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM