在单个Google表格单元格中为文本应用多种字体颜色

时间:2018-03-14 20:28:28

标签: google-apps-script google-sheets text-formatting

我正在尝试使用Google Apps脚本中的函数将单元格格式化为多种字体颜色。我无法找到任何文件。此外,使用getFontColor()不会返回任何有用的内容。

有没有办法以编程方式重现此功能

enter image description here

用户可以通过Google表格网页界面获取

吗?

3 个答案:

答案 0 :(得分:2)

Sheets API开始使用有点令人生畏,但允许对电子表格进行非常细粒度的控制。您必须enable it,因为它是“高级服务”。我强烈建议您查看Sample Codelab

使用Sheets API,可以逐个单元地操作TextFormatRun属性。注意:

  

应用于单元格子部分的富文本运行。运行仅对用户输入的字符串有效,而不是公式,bool或数字。运行从文本中的特定索引开始,一直持续到下一次运行。除非在后续运行中明确更改,否则运行的属性将继续(并且第一次运行的属性将继续该单元的属性,除非明确更改)。

     

写入时,新运行将覆盖任何先前的运行。在编写新的userEnteredValue时,先前的运行将被删除。

此示例使用它来调整文本的绿色值,在活动单元格中字符串的长度上从0增加到100%。根据您的需求进行调整。

function textFormatter() {
  // Get the current cell's text.
  var wb = SpreadsheetApp.getActive(), sheet = wb.getActiveSheet();
  var cell = sheet.getActiveCell(), value = cell.getValue();
  var len = value.toString().length;
  if(len == 0) return;

  // Change the color every 2 characters.
  var newCellData = Sheets.newCellData();
  newCellData.textFormatRuns = [];
  var step = 1 / len;
  for(var c = 0; c < len; c += 2) {
    var newFmt = Sheets.newTextFormatRun();
    newFmt.startIndex = c;
    newFmt.format = Sheets.newTextFormat();
    newFmt.format.foregroundColor = Sheets.newColor();
    newFmt.format.foregroundColor.green = (c + 2) * step;
    newCellData.textFormatRuns.push(newFmt);
  }

  // Create the request object.
  var batchUpdateRQ = Sheets.newBatchUpdateSpreadsheetRequest();
  batchUpdateRQ.requests = [];
  batchUpdateRQ.requests.push(
    {
       "updateCells": {
        "rows": [ { "values": newCellData } ],
        "fields": "textFormatRuns",
        "start": {
          "sheetId": sheet.getSheetId(),
          "rowIndex": cell.getRow() - 1,
          "columnIndex": cell.getColumn() - 1
        }
      }
    }
  );
  Sheets.Spreadsheets.batchUpdate(batchUpdateRQ, wb.getId());
}

编辑:根据如何设置要格式化的单元格的值,可能还需要包括同一请求中的单元格的值。 See this example on the issue tracker

答案 1 :(得分:2)

从2018年7月开始,Apps-Script支持更改单个文本颜色和其他与字体相关的样式。 SpreadsheetApp中添加了两种方法。 newTextStyle()newRichTextValue()。以下应用程序脚本更改了A1中的此类字体样式。为了获得最佳效果,请使用较长的字符串(30个字符或更多)。

function rainbow(){
  var rng = SpreadsheetApp.getActiveSheet().getRange("A1");
  var val = rng.getValue().toString();
  var len = val.length; // length of string in A1
  var rich = SpreadsheetApp.newRichTextValue(); //new RichText
  rich.setText(val); //Set Text value in A1 to RichText as base 
  for (var i=0;i<len;i++){ //Loop through each character
    var style = SpreadsheetApp.newTextStyle(); // Create a new text style for each character
    var red= ("0"+Math.round((1/len)*(i)*255).toString(16)).substr(-2,2); //
    var green= ("0"+Math.round((1/len)*Math.min(i*2,len-Math.abs(i*2-len))*255).toString(16)).substr(-2,2); //
    var blue= ("0"+Math.round((1/len)*(len-i)*255).toString(16)).substr(-2,2);//
    style.setForegroundColor("#"+red+green+blue); // hexcode
    style.setFontSize(Math.max(Math.abs(len/2-i),8)); //Use a lengthy string
    var buildStyle = style.build(); 
    rich.setTextStyle(i,i+1,buildStyle); // set this text style to the current character and save it to Rich text     
  }
  var format = rich.build()
  rng.setRichTextValue(format); //Set the final RichTextValue to A1
}

文档尚未发布。方法可能会更改

参考文献:

答案 2 :(得分:0)

    function submit(event) {
      const radio_htm = document.querySelectorAll('input[type=radio]');
      const radios_array = Array.prototype.slice.call(radio_htm);

      // Reduce to get an array of radio button sets
    const questions = Object.values(radios_array.reduce((result, el) => {
      return Object.assign(result, {[el.name]: (result[el.name] || []).concat(el)});
    }, {}));

    // Loop through each question, looking for any that aren't answered.
    const hasUnanswered = questions.some(question => {
      !question.some(el => {
        return el.checked;
      })
     });

    if (hasUnanswered) {
        radio_not_pass = false;
        // Retrieve DOM element from sliced array - radios_array and modify dom.
        // Suggestion works here.  
        // What about accessing only radios that = hasUnanswered
        radios.forEach(radio=>radio.parentNode.classList.add('error'))

    } else {
      radio_not_pass = true;

    }

    if (!radio_not_pass) {
     event.preventDefault();
    }