将 Google 工作表中的格式化文本转换为 Google 文档

Converting formatted Text from Google sheets to Google docs

我正在尝试使用 google 脚本将格式化文本从 google sheet 复制到 google 文档。我已经成功地将文本从 sheets 转换为文档,但是我无法继承相关的 formatting/markdowns,例如粗体、斜体、颜色、下划线等。有没有人知道我在做什么错误或我可以在 google 脚本库中使用什么功能,它也允许我复制格式?

目前,我有一个现有的 google 文档作为模板。以后创建的所有 google 文档都将遵循类似的模板。我创建了一个名为 'doc Builder' 的 sheet 并使用 ,for 循环和 switch 语句来选择要将 sheet 中的哪个单元格复制到 word doc.

function createDocument() {

  var docbuilder = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('doc Builder');

  //active data range
  var range = docbuilder.getRange(4, 1, docbuilder.getLastRow() - 3, docbuilder.getLastColumn() - 1).getDisplayValues();

  var templateId = 'myworddocIDwhichihaveremoved'; //the word doc

  //Make a copy of the template file
  var documentId = DriveApp.getFileById(templateId).makeCopy().getId();

  //Rename the copied file
  DriveApp.getFileById(documentId).setName('name of new doc');

  //Get the document body as a variable
  var body = DocumentApp.openById(documentId).getBody();

  //copies texts from cell to word doc 
  //i = row, j = column
  for(var i = 0; i < range.length; i++){
    for(var j = 0; j < range[i].length; j++){
      var cells = [];
      switch(j) {
      case 0:
      body.appendParagraph(range[i][j]);
      break;
      case 1: 
      body.appendParagraph(range[i][j]);
      break;
      case 2: 
        if(range[i][j] != ""){
          body.appendParagraph('PARAGRAPH 1:' + range[i][j]);
        }
      break;
      case 3:
        body.appendParagraph('PARAGRAPH 2:' + range[i][j]);
      break;
      }
    }
  }
}

我已经尝试 copyTo() 并且它成功地将格式从 sheet 复制到 sheet 但是我无法对 sheet 做同样的事情到文档。我也知道可以从 documentation 添加到我的 word 文档中的属性,例如 BACKGROUND_COLOR、BOLD 等,但是我处理的数据通常只对单元格的某些部分进行格式化,例如: sallygirl 而不是 sally 是 girl。因此,当单元格数量增加时,很难进行硬编码。

简而言之,我正在尝试将格式从 sheet 转移到文档中,这样我就不必单独处理每个单元格。

我正在处理更多案例,但我已删除它们以简化代码,并且活动数据范围内的每个单元格都已格式化,但是当创建新的 google 文档时,格式会消失。

我希望有人能解决这个问题哈哈:""D

正在将值从表格复制到带有格式的文档

没有可用于将格式化文本从表格复制到文档的本机方法。他们不使用相同的 classes 来处理格式化文本。

Sheets 有 RichTextValue,其中包含一个单元格的所有信息。例如,当您调用:

const range = sheet.getRange("A2")
const richTextValue = range.getRichTextValue()

然后您可以获得有关单元格内文本格式的所有信息。例如,如果您有这样一个单元格:

如果您从此单元格获取富文本值,然后对该值调用 getRuns() 方法,您将获得一系列新的 RichTextValue:

wherein each run is the longest possible substring having a consistent text style.

因此对于示例,您将获得一个新对象:

  • "Hello"
  • "bold"
  • "italic"
  • ...等等

您还可以为单词之间的空格获取单独的对象。

对于其中的每一个对象,您都可以调用一系列方法来获取其格式的各个组成部分:

  • getFontFamily()
  • getFontSize()
  • getForegroundColor()
  • isBold()
  • isItalic()
  • isStrikethrough()
  • isUnderline()

注意:此示例中未使用 getBackgroundColor(),因为 sheet 中的背景颜色无法应用于单个文本运行,而是应用于整个单元格。

DocumentApp 中没有对应的 class。您不能将 RichTextValue 附加到文档中的任何元素。所以这意味着你需要匹配你需要的相应方法。例如,您可以使用具有所有相应方法的 Text class,您只需要一个中间人来 link 建立方法并以正确的方式对它们进行排序。

示例实现

这很可能需要根据您的确切需求进行调整,我不知道 switch 语句的逻辑是什么,而且我没有样本数据来测试它,但是这个应该让你很好地了解它是如何工作的。您也可以在脚本中按原样使用自定义 class。

理想情况下,您可以从主脚本中调用一些简单的方法,如下所示:

function main() {
  // Getting the rich text value
  const sheet = SpreadsheetApp.getActive();.getSheetByName("Sheet1");
  const range = sheet.getRange("A2");
  const value = range.getRichTextValue();

  // Creating an instance of a custom class that will be implemented
  const textToExport = new SheetRichText(value)

  // Setting the target document
  const doc = DocumentApp.openById("[YOUR DOCUMENT ID]")
  const body = doc.getBody()

  // Calling a method of the custom class
  textToExport.appendAsNewParagraph(body)
}

注意:将 [YOUR DOCUMENT ID] 替换为正确的文档 ID。

请记住,在我的例子中,我的 sheet 有这个:

我在示例中实现的自定义 class 是:

class SheetRichText{
  // To initialize it you pass it a RichTextValue object
  constructor(RichTextValue){
    // It gets all the runs and creates an object that contains all the information
    // needed to call the corresponding methods in the document Text class.
    this.runs = RichTextValue.getRuns().map(run => {
      const style = run.getTextStyle()
      return {
        "style" : {
            "fontFamily" : style.getFontFamily(),
            "fontSize" : style.getFontSize(),
            "foregroundColor" : style.getForegroundColor(),
            "bold" : style.isBold(),
            "italic" : style.isItalic(),
            "strikethrough" : style.isStrikethrough(),
            "underline" : style.isUnderline()
          },
        "text" : run.getText(),
        "start" : run.getStartIndex(),
        "end" : run.getEndIndex()
      }
    })
  }

  // This takes as an argument the body of a document and adds the RichTextValue
  // to the document as a new paragraph
  appendAsNewParagraph(body){

    // Initializing the new blank paragraph
    const paragraph = body.appendParagraph("")

    // For each run, copy the text and then set all the formatting
    // making sure that the start and end indices are called.
    this.runs.forEach(run => {
      const textElement = paragraph.asText().appendText(run.text)
      const [start, end] = [run.start, run.end -1]

      textElement.setFontFamily(start, end, run.style.fontFamily)
      textElement.setFontSize(start, end, run.style.fontSize)
      textElement.setForegroundColor(start, end, run.style.foregroundColor)
      textElement.setBold(start, end, run.style.bold)
      textElement.setItalic(start, end, run.style.italic)
      textElement.setStrikethrough(start, end, run.style.strikethrough)
      textElement.setUnderline(start, end, run.style.underline)
    })
  }
}

这导致:

参考资料