开发者问题收集

请再看一遍:Google Advanced Slides API 在现有表格中插入文本

2021-07-19
1528

问题:如何在 Google Slide 中现有表格的单元格中插入文本?

我有一个现有演示文稿,其中包含一个模型表格,其所有尺寸和颜色均符合要求。它不包含任何文本。这是我运行的代码,尝试填充表格。

  let templatePres = SlidesApp.openById(templatePresId);
  let slidesArr = templatePres.getSlides();
  let templateSlideId = slidesArr[0].getObjectId();
  let tblArr = slidesArr[0].getTables();
  let theTblId = tblArr[0].getObjectId();  // table page element
  
  let requests =[]
    ,numRows = 8, numCols = 8
    ,r, c, nextReq, nextVal
    ,theTableCellObj ,theTableRowObj ,theTableObj ,thePageElement
  
  for ( c = 0 ; c < numCols ; c++ ) {
    for ( r = 0 ; r < numRows ; r++ ) {
      theTableCellObj = 
      {
        "location": {
            "rowIndex": r
           ,"columnIndex": c
        },
        "text": { nextVal }
      };
    
      theTableRowObj =
      {
        "tableCells": [ theTableCellObj ]
      }

      theTableObj =
      {
        "rows": numRows,
        "columns": numCols,
        "tableRows": [ theTableRowObj ]
      }

      thePageElement = 
      {
        "objectId": theTblId,
        "table": theTableObj
      };
  
      nextVal = inArr[r][c].toString();
      console.log('r: ', r, ' c: ', c, ' val: ', nextVal );
      nextReq = 
      {
        "objectId": templateSlideId,
        "pageType":  'SLIDE',
        "pageElements": [thePageElement]
      }  
      requests.push(nextReq);
      console.log(JSON.stringify(nextReq) );
    }
  } 

batchUpdate 中每个请求的错误如下所示:

GoogleJsonResponseException: API call to slides.presentations.batchUpdate failed with error: Invalid JSON payload received. Unknown name "pageElements" at 'requests[0]': Cannot find field.
Invalid JSON payload received. Unknown name "pageType" at 'requests[0]': Cannot find field.
Invalid JSON payload received. Unknown name "objectId" at 'requests[0]': Cannot find field.
Invalid JSON payload received. Unknown name "pageElements" at 'requests[1]': Cannot find field.
Invalid JSON payload received. Unknown name "pageType" at 'requests[1]': Cannot find field.
...

这是 console.log 显示的典型请求:

{
    "objectId": "SLIDES_API142383606_0"
  , "pageType": "SLIDE"
  , "pageElements":
  [
    {
      "objectId": "SLIDES_API142383606_1"
      , "table": 
      {
          "rows": 8
        , "columns": 8
        , "tableRows": [
          {
            "tableCells": [
              {
                "location": { "rowIndex": 3, "columnIndex": 2 }
               ,"text": { "nextVal": "silf" }
              }
            ]
          }
        ]
      }
    }
  ]
}

我使用了文档,但发现它非常困难。任何帮助表示感谢。

我添加了一些日志来证明获取 ID 不是问题。

  try    {
    templatePres = SlidesApp.openById(templatePresId);
  }  catch ( err)    {
    ui.alert('You do not have a presentation. Ending.');
    return;
  }
  
  try    {
    slidesArr = templatePres.getSlides();
  }  catch ( err)    {
    ui.alert('Could not get slides from presentation. Ending.');
    return;
  }
  let templateSlideId = slidesArr[0].getObjectId();
  console.log('templateSlideId: ', templateSlideId );
  
  try    {
    tblArr = slidesArr[0].getTables();
  }  catch ( err)    {
    ui.alert('Could not get slides from presentation. Ending.');
    return;
  }
  let theTblId = tblArr[0].getObjectId();  // table page element
  console.log('ttheTblId: ', theTblId );

这是日志显示:

templateSlideId:  SLIDES_API1369298387_0
ttheTblId:  SLIDES_API1369298387_1    // typo did not affect result

除非您好奇,否则不要费心查看下面的愚蠢想法

下面的先前尝试没有奏效,因为我找不到输入幻灯片 ID 的方法。

第一步:我在现有演示文稿中制作副本,以便我可以添加文本而不会弄乱原始内容。

  //  https://www.debugcn.com/en/article/18027667.html
  let slide0 = templatePres.getSlideById(templateSlideId)
//  templatePres.insertSlide(insertionIndex, slide)
  templatePres.insertSlide(0, slide0);

此临时幻灯片将填充文本,下载为 png 并作为背景插入到最终演示文稿中。

第二步:在临时幻灯片上填充文本而不进行批量更新:

  for ( let r = 0 ; r < 9 ; r++ ) {
    for ( let c = 0 ; c < 9 ; r++ ) {
      theTbl.getCell(r, c). ??? there are no sets or inserts
    }
  }

以上方法不起作用,因为没有设置或插入文本。

第二步:使用批量更新填充临时幻灯片上的文本:

构建 batchUpdate 请求:

  for ( let c = 0 ; c < 8 ; c++ ) {
    for ( let r = 0 ; r < 8 ; r++ ) {
      requests.push(
        {"insertText":
          {"objectId": theTblId
          ,"cellLocation": {
             "rowIndex": r
            ,"columnIndex": c
           }
          ,"text": inArr[r][c].toString()
//          ,"text": inArr[r][c]
          }
        }
      );
    }
  }

  if (requests.length > 0)   {
    response = Slides.Presentations.batchUpdate(
      { 'requests': requests }, templatePresId );
  }

出现错误: GoogleJsonResponseException:对 slides.presentations.batchUpdate 的 API 调用失败,错误为:无效的请求[0].insertText:找不到对象(SLIDES_API1834905201_1)。

SLIDES_API1834905201_1 是带有模型表的现有幻灯片的 id。上述请求包含演示文稿 id 和页面元素/表格 id,但没有地方输入幻灯片 id???

我尝试在 insertText 请求之前将每个请求分别添加到请求数组中,以此来识别幻灯片,但显然我不明白文档中的语法。错误已列出。

测试 1 错误: 'requests[0]' 处的未知名称“Page”:找不到字段。

  requests.push(
    {'Page': {
      "objectId": templateSlideId,
      "pageType": 'SLIDE'
    }}
  );
  

测试 2:错误: 'requests[0]' 处的未知名称“pageType”:找不到字段。 收到无效的 JSON 负载。 'requests[0]' 处的未知名称“objectId”:找不到字段。

  requests.push(
    {
      "objectId": templateSlideId,
      "pageType": 'SLIDE'
    }
  );
   

测试 3:错误: 'requests[0]' 处的未知名称“SlideProperties”:找不到字段。

  requests.push(
    {'SlideProperties': {
      "layoutObjectId": templateSlideId
    }}
  );

问题: 是否可以将文本插入现有幻灯片中的现有表格中?

我真的不想使用批量更新来更改模板/模型表中的所有尺寸和颜色。

@Aerials 发布了是否有办法(或解决方法)使用应用程序脚本将 Google 表格中的表格添加到 Google 幻灯片演示文稿中? 有没有办法(或解决方法)使用应用程序脚本将表格从 Google 表格添加到 Google 幻灯片演示文稿中? 他 1) 创建了幻灯片,2) 添加了表格,3) 填充了表格。

我看过的另一个想法 https://developers.google.com/slides/api/guides/styling#inserting_deleting_or_replacing_text 描述了在插入之前删除文本,但如果没有要删除的文本?

我确实运行了代码来创建带有表格的幻灯片,然后使用 for 循环来填充文本运行并创建带有填充表格的幻灯片。它运行了,创建了带有表格的幻灯片,但出现了错误,并且生成的幻灯片不令人满意。

  let newSlideId = Utilities.getUuid();
  requests.push(
    {"createSlide": {
        "objectId": newSlideId,
        "insertionIndex": 0,
        "slideLayoutReference": {
          "predefinedLayout": "BLANK"
        }
      }
    },
    { "createTable": {
        "objectId": theTblId,   // this id is in use on template slide but will be unique on this new slide
        "elementProperties": {
          "pageObjectId": newSlideId
        },
        "rows": 9,
        "columns": 9
      }
    }
  );
  

  console.log('number of updates: ', requests.length);
  if (requests.length > 0)   {
    response = Slides.Presentations.batchUpdate(
      { 'requests': requests }, templatePresId );
  }

  console.log('table created in new slide');
  requests =[];

表格周围有很多空白。列和行的大小不对,我必须添加背景颜色。批量更新将最小行和列/宽度和高度限制为 32 像素,这太大了。我正在教学,希望表格能够填满幻灯片,以便可以看到。这就是我想使用现有模型表的原因。

但是,错误: 服务不可用:幻灯片 上面显示的代码之后没有其他代码运行,所以不知道这是从哪里来的。因为我不喜欢这个结果 - 我不在乎。

====================================== 开始回应 Kos 的建议

代码:

function insertText(inArr)   {
  console.log('Begin insertText' );
  console.log(inArr );
  const ui = SpreadsheetApp.getUi();
  let templatePres = SlidesApp.openById(templatePresId);
  let slidesArr = templatePres.getSlides();
  let templateSlideId = slidesArr[0].getObjectId();
  console.log('templateSlideId: ', templateSlideId );
  let tblArr = slidesArr[0].getTables();
  let theTblId = tblArr[0].getObjectId();  // table page element
  console.log('theTblId: ', theTblId );
  
  let requests =[]
    ,numRows = 8, numCols = 8
    ,r, c, nextReq, nextVal
    ,theTableCellObj ,theTableRowObj ,theTableObj ,thePageElement
  
  for ( let c = 0 ; c < 8 ; c++ ) {
    for ( let r = 0 ; r < 8 ; r++ ) {
      requests.push(
        {"insertText":
          {"objectId": theTblId
          ,"cellLocation": {
             "rowIndex": r
            ,"columnIndex": c
           }
          ,"text": inArr[r][c].toString()
//          ,"text": inArr[r][c]
          }
        }
      );
    }
  }

  console.log('number of updates: ', requests.length);
  if (requests.length > 0)   {
    response = Slides.Presentations.batchUpdate(
      { 'requests': requests }, templatePresId );
  }

  console.log('End insertText' );
}

日志:

Aug 4, 2021, 1:39:22 PM Debug   ?slide=id.ge1649b52bc_0_0 slide[0] id:  SLIDES_API2065850924_0
Aug 4, 2021, 1:39:23 PM Debug   Begin insertText
Aug 4, 2021, 1:39:23 PM Debug   [ [ ' ', ' ', 'A', 'B', 'C', 'D', 'E', 'F', ' ' ],
  [ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
  [ '1', ' ', 'zub', 'jip', 'kep', 'belm', 'frel', 'ras', ' ' ],
  [ '2', ' ', 'drelf', 'bilp', 'bel', 'crift', 'posk', 'qualt', ' ' ],
  [ '3', ' ', 'frusp', 'julm', 'hes', 'trin', 'taft', 'rop', ' ' ],
  [ '4', ' ', 'sit', 'lit', 'trus', 'gub', 'buct', 'bloct', ' ' ],
  [ '5', ' ', 'mef', 'dolp', 'hush', 'glap', 'crit', 'clack', ' ' ],
  [ '6', ' ', 'crulp', 'gelt', 'quelm', 'dap', 'memp', 'rift', ' ' ],
  [ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ] ]
Aug 4, 2021, 1:39:23 PM Debug   templateSlideId:  SLIDES_API1629452804_0
Aug 4, 2021, 1:39:23 PM Debug   theTblId:  SLIDES_API1629452804_1
Aug 4, 2021, 1:39:23 PM Debug   number of updates:  64
Aug 4, 2021, 1:39:24 PM Error   GoogleJsonResponseException: API call to slides.presentations.batchUpdate failed with error: Invalid requests[0].insertText: The object (SLIDES_API1629452804_1) could not be found.
    at insertText(Code:243:37)
    at makeMockup(Code:78:3)

下午 1:39:23 调试 theTblId: SLIDES_API1629452804_1 表格已定位并记录

下午 1:39:24 错误 GoogleJsonResponseException:对 slides.presentations.batchUpdate 的 API 调用失败,错误为:无效请求[0].insertText:无法插入对象 ( SLIDES_API1629452804_1 )找到。

我在 insertText 命令中使用了表格 ID,但找不到。我猜是因为没有输入幻灯片 ID,因此尝试了更复杂的 batchUpdate,但同样不起作用。

结束对 Kos 的回复


历史记录 - 我想从电子表格中的列表创建一个表格,该表格将填充 Google 幻灯片或 Jamboard 的背景。

方法 1. 在与列表相同的电子表格中创建一个表格并用于教学。问题:电子表格的所有工具栏都占用了小型学生设备上的空间。

方法 2. 不支持:将表格(电子表格中的单元格范围)提取为图像并加载到幻灯片背景。我在 Google 电子表格中找不到任何功能来执行此操作。在 Excel 中可能实现吗?

方法 3。在与列表相同的电子表格中创建一个表格,阅读电子表格中表格的“一些”特征。创建幻灯片,插入表格并使用电子表格中表格特征中可用的有限数据(包括文本)对其进行格式化。从幻灯片中下载表格作为图像并将其上传为背景图像。生成的表格(9x9)比幻灯片大。当将图像加载到幻灯片中时,表格周围是无用的空白,并且大部分未格式化。 “https://stackoverflow.com/questions/58327686/get-range-of-google-spreadsheet-into-an-image-using-google-script/58336922”

方法 4。不支持:从前 36 项数据创建一个数组。手动创建一个带有表格的幻灯片,并使用尽可能有限的属性对其进行格式化。在幻灯片上使用简单的更新表格,而无需批量更新。 theTbl.getCell 未设置或插入方法。

方法 5。获取错误:从前 36 项数据创建一个数组。手动创建一个带有表格的幻灯片,并使用尽可能有限的属性对其进行格式化。使用简单的批量更新 insertText 用数组中的文本填充幻灯片表格。将表格下载为图像并将其作为背景图像上传。这与方法三不同,因为幻灯片上的表格是现有的。这是 @Kos 在他的“答案”中讨论的方法。请参阅上面的错误(搜索 Kos)

方法 6。获取错误:从数据创建一个数组。创建具有漂亮样式和文本属性的模型的幻灯片副本。使用复杂的批量更新,用数组中的文本填充幻灯片表。下载为图像并保存为新或现有演示文稿中新幻灯片的背景。删除所有临时内容。参见上面的错误(顶部示例)

您可能已经注意到我对用户名的选择不太恰当。我只有 85 分,我冒着 50 分的风险来回答问题!

3个回答

首先,它不会起作用,因为您调用了错误的幻灯片!:) 复制幻灯片时,您现在必须填写第二张幻灯片,而不是第一张。

function populateMockupTable(inArr)   {
  console.log('Begin populateMockupTable' );
//  console.log(inArr);
  const ui = SpreadsheetApp.getUi();
  let templatePres, slidesArr, tblArr;

  try    {
    templatePres = SlidesApp.openById(templatePresId);
  }  catch ( err)    {
    ui.alert('You do not have a presentation. Ending.');
    return;
  }
  
  try    {
    slidesArr = templatePres.getSlides();
  }  catch ( err)    {
    ui.alert('Could not get slides from presentation. Ending.');
    return;
  }
  let templateSlideId = slidesArr[1].getObjectId();
//  console.log('templateSlideId: ', templateSlideId );
  
  try    {
    tblArr = ***slidesArr[1]***.getTables();
  }  catch ( err)    {
    ui.alert('Could not get slides from presentation. Ending.');
    return;
  }
  let theTblId = tblArr[0].getObjectId();  // table page element
//  console.log('theTblId: ', theTblId );
  
    let requests =[], numRows = inArr.length, numCols = inArr[0].length, r, c;
  
  
  for ( let r = 0 ; r < numRows ; r++ ) {
    for ( let c = 0 ; c < numCols ; c++ ) {
      requests.push(
        {"insertText":
          {"objectId": theTblId
          ,"cellLocation": {
             "rowIndex": r,
             "columnIndex": c
           }
          ,"text": inArr[r][c].toString()
          }
        }
      );
    }
  }

//  console.log('number of updates: ', requests.length);
  if (requests.length > 0)   {
  var response = Slides.Presentations.batchUpdate(
      { 'requests': requests }, templatePresId );
  }
 

//  console.log('End populateMockupTable' );
//  console.log(requests);
}
Clark Lind
2021-08-09

您的代码是正确的,除了这里您遗漏了一点:

It gets the error: GoogleJsonResponseException: API call to slides.presentations.batchUpdate failed with error: Invalid requests[0].insertText: The object (SLIDES_API1834905201_1) could not be found.

SLIDES_API1834905201_1 is the id of the existing slide with the mockup table. The above request contains the presentation id and the page element / table id but there is no place to enter the slide id???

insertText 请求的 objectId 不应该是幻灯片 ID(如您所想),而应该是表格 ID。将其修复为正确的对象 ID 将允许应用请求。

来自 文档

objectId - string The object ID of the shape or table where the text will be inserted.

2021-08-04

这是一个简单的解决方案,您可以利用 Google Slides 的现有表格并在任何您想要的地方合并数据。例如:

在此处输入图片说明

 // Create the text merge (replaceAllText) requests for this presentation.
  let requests = [{
    replaceAllText: {
      containsText: {
        text: '{{customer-name}}',
        matchCase: true
      },
      replaceText: customerName //Here the variable with data
    }
  }, {
    replaceAllText: {
      containsText: {
        text: '{{case-description}}',
        matchCase: true
      },
      replaceText: caseDescription //Here the variable with data
    }
  }, {
    replaceAllText: {
      containsText: {
        text: '{{total-portfolio}}',
        matchCase: true
      },
      replaceText: totalPortfolio + '' //Here de variable with data
    }
  }];


// Execute the requests for this presentation.
  var result = Slides.Presentations.batchUpdate({
    requests: requests
  }, presentationId);

它对我有用

在此处输入图片说明

文档:

https://developers.google.com/slides/api/guides/merge#apps-script

Julian Benavides
2021-08-10