【问题标题】:Formatting numbers read from spreadsheet格式化从电子表格读取的数字
【发布时间】:2012-01-26 19:48:23
【问题描述】:

我正在编写一个脚本,用于创建 Google Apps 电子表格内容的固定宽度文本输出。我使用range.getValues() 方法检索当前范围的所有值,然后循环遍历所有内容几次并生成一个文本块,当粘贴到固定宽度字体的电子邮件中时,该文本块看起来像一个格式良好的表格。

我遇到的唯一问题是我无法复制数字格式。我可以使用range.getNumberFormats() 获取数字格式字符串,但我找不到在代码中应用该格式字符串的方法。我尝试使用 TEXT(值、格式)电子表格函数,但显然 Google Apps 脚本还不支持从 JavaScript 代码本身调用电子表格函数(请参阅this issue 以获取证据)。

【问题讨论】:

    标签: javascript google-apps-script google-sheets number-formatting


    【解决方案1】:

    December 2015 开始,可以放弃笨拙的解决方法。 Google 提供了两种方法来从单元格中检索文字字符串显示值。他们还没有提供文档,所以这里是一个摘要:

    Range.getDisplayValue()
    以字符串形式返回区域中左上角单元格的显示值,其中包含表格 UI 上显示的文本值。空单元格将返回一个空字符串。

    Range.getDisplayValues()
    返回此范围的显示值的矩形网格。返回字符串的二维数组,先按行索引,然后按列。空单元格将由数组中的空字符串表示。请记住,虽然范围索引从 1、1 开始,但 JavaScript 数组将从 [0][0] 开始索引。

    示例:

    假设我们在电子表格中有一个感兴趣的范围,如下所示:

    这四个单元格包括两种最难解决的格式;日期/时间和科学记数法。但是有了新方法,就没有什么了。

    function demoDisplayValue() {
      var range = SpreadsheetApp.getActiveSheet().getRange("A1:B2");
    
      Logger.log( range.getDisplayValue() );
      Logger.log( range.getDisplayValues() );
    }
    

    日志:

    [16-01-14 13:04:15:864 EST] 1/14/2016 0:00:00
    [16-01-14 13:04:15:865 EST] [[1/14/2016 0:00:00, 5.13123E+35], [$3.53, 1,123 lb]]
    

    【讨论】:

      【解决方案2】:

      我找到了一个 JavaScript 方法,用于设置小数点后的位数,称为 toFixed()。

      这是文档: http://www.w3schools.com/jsref/jsref_tofixed.asp

      num.toFixed(x) //where x = the number of digits after the decimal point.
      

      我的 Google Apps 脚本需要返回一条消息,其中包含从我的电子表格中提取的美元值。小数点后有 10 位数字看起来很糟糕。应用于我的变量的这种方法解决了这个问题。我只是在标签的文本部分添加了一个 $。

      希望这会有所帮助!

      【讨论】:

        【解决方案3】:

        预先提供的格式列表是here。对于某些格式,等效的 javascript 是相对简单的。对于其他人来说,这是非常困难的。并处理用户定义的自定义格式 - 祝你好运。

        这是一个屏幕截图,显示已复制为 html 的单元格内容 - 没有像您所做的那样修复,而是使用电子表格中的格式。

        有一些 Google Apps 脚本帮助函数,Utilities.formatString()Utilities.formatDate()

        对于日期和时间,例如 "h:mm:ss am/pm",电子表格格式几乎是该实用程序所需的 - 我发现您只需要调整某些格式的 am/pm 名称:

          var format = cell.getNumberFormat();
          var jsFormat = format.replace('am/pm','a');
          var jsDate = Utilities.formatDate(
                  date,
                  this.tzone,
                  jsFormat);
        

        对于美元,例如"\"$\"#,##0.00":

          var dollars = Utilities.formatString("$%.2f", num);
        

        对于百分比格式的数字,例如"0.00%":

          var matches = format.match(/\.(0*?)%/);
          var fract = matches ? matches[1].length : 0;     // Fractional part
          var percent = Utilities.formatString("%.Xf%".replace('X',String(fract)), 100*num);
        

        对于像"0.000E+00" 这样的指数,利用javascript 内置toExponential(),并调整输出使其看起来更像电子表格:

        if (format.indexOf('E') !== -1) {
          var fract = format.match(/\.(0*?)E/)[1].length;  // Fractional part
          return num.toExponential(fract).replace('e','E');
        }
        

        您只需与存储的电子表格格式进行字符串比较即可选择正确的转换器。

        我所说的极其困难是什么意思?尝试获得一个格式化程序,它提供与表格为# ?/?# ??/?? 所做的完全相同的分子和分母选择!在电子表格中,这是一个格式问题 - 在脚本中,它更多...

        【讨论】:

          【解决方案4】:

          试试下面的谷歌应用脚​​本

          function NumberFormat()
          {var ss = SpreadsheetApp.getActiveSpreadsheet();
           var sheet = ss.getSheets()[0];
          
           var cell = sheet.getRange("A1:B10");
           // Always show 2 decimal points
           cell.setNumberFormat("0,00,000.00");
          }
          

          【讨论】:

            【解决方案5】:

            确实,您不能直接调用电子表格函数。但是您可以正常使用setNumberFormats 设置格式。查看文档here

            【讨论】:

            • 从我上面的问题中可以看出,我最终试图将格式化的文本值超出范围并转换为字符串。据我所知,Range.setNumberFormats 方法没有提供将格式化的日期或货币字符从 Range 对象中取出并转换为可用于其他目的的字符串的方法。
            • 对不起,即使重新阅读您的问题,我也无法理解您在评论中所说的这一点。无论如何,电子表格中值的格式不会传递给脚本。不过有一些解决方法,也许我应该重新表述我的答案。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-05-16
            • 1970-01-01
            • 1970-01-01
            • 2011-02-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多