将数据从图纸复制到文档并生成新文档

时间:2019-10-03 15:19:22

标签: google-apps-script google-sheets-api

我处于编程的初学者到中级的状态,在这里我足够了解将某些东西拼凑起来的过程,这些事情可能相当复杂,但也许我并没有以最好的方式去解决,陷入困境,而且它肯定没有优化

我已经构建了一个发票生成器,该发票生成器将从工作表输入的数据转换为google docs中的相同模板。我希望有一个脚本,该脚本接受报价信息,并将这些行复制到docs中的模板中,除非该行为空,在这种情况下,它会跳到下一个。

到目前为止,我已经通过将每个单元格指定为一个自变量,并分别复制它们(无论是否填充它们)来实现这一目标。

它可以工作,但是它似乎不是最有效的解决方案,并且由于我们仍然必须在生成的报价文档中修复某些格式,所以它很快变得很痛苦。


  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sinput = ss.getSheetByName("QUOTE TEMPLATE");

//TO GENERATE DOCUMENT
  var templateId = '1jIxHUZAoVd00a9eTZM-ORL0H7qMLfEmyat04l89GNwE';

  //devis
  var item1 = sinput.getRange("B18").getValues();
  var item2 = sinput.getRange("B19").getValues();
  var item3 = sinput.getRange("B20").getValues();

  var qty1 = sinput.getRange("C18").getValues();
  var qty2 = sinput.getRange("C19").getValues();
  var qty3 = sinput.getRange("C20").getValues();

  var unitprice1 = sinput.getRange("D18").getValues();
  var unitprice2 = sinput.getRange("D19").getValues();
  var unitprice3 = sinput.getRange("D20").getValues();

  var total1 = sinput.getRange("E18:G18").getValues();
  var total2 = sinput.getRange("E19:G19").getValues();  
  var total3 = sinput.getRange("E20:G20").getValues();


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

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

//All the text to be replaced

  body.replaceText('%DESCRIPTION_STRING1%', item1 );
  body.replaceText('%DESCRIPTION_STRING2%', item2 );
  body.replaceText('%DESCRIPTION_STRING3%', item3 );;

  body.replaceText('%Q1%', qty1 );
  body.replaceText('%Q2%', qty2 );
  body.replaceText('%Q3%', qty3 );

  body.replaceText('%PRIC1%',  unitprice1 );
  body.replaceText('%PRIC2%',  unitprice2 );
  body.replaceText('%PRIC3%',  unitprice3);;

  body.replaceText('%TOTAL_1%', total1 );
  body.replaceText('%TOTAL_2%',  total2);
  body.replaceText('%TOTAL_3%', total3 );;

}

这是简化版本,因为原始代码占20条不同的输入行,也许更多。 当前,任何空白单元格都会导致逗号(,)导出到google文档中。

我很想:

  1. 减少代码长度
  2. 使代码更快
  3. 构造代码以跳过空行
  4. 使用非body.replaceText
  5. 的东西

但是我不知道如何正确表达代码中的“如果一行为空,只需移至下一位”。

我有大约6个月的工作经验,因此我认为自己仍然是一名学习者。感谢您提供任何帮助或见识!

1 个答案:

答案 0 :(得分:1)

尝试一下:

function fn(){
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet3");
  var data = ss.getRange("B18:G20").getValues();

//Make a copy of the template file
  var documentId = DriveApp.getFileById(templateId).makeCopy().getId(); 
//Get the document body as a variable
  var body = DocumentApp.openById(documentId).getBody();

//All the text to be replaced
  body.replaceText('%DESCRIPTION_STRING1%', data[0][0]);
  body.replaceText('%DESCRIPTION_STRING2%', data[1][0]);
  body.replaceText('%DESCRIPTION_STRING3%', data[2][0]);

  body.replaceText('%Q1%', data[0][1]);
  body.replaceText('%Q2%', data[1][1]);
  body.replaceText('%Q3%', data[2][1]);

  body.replaceText('%PRIC1%',  data[0][2] );
  body.replaceText('%PRIC2%',  data[1][2]);
  body.replaceText('%PRIC3%',  data[2][2]);

  body.replaceText('%TOTAL_1%', data[0][3] + " " + data[0][4] + " " + data[0][5]);
  body.replaceText('%TOTAL_2%', data[1][3] + " " + data[1][4] + " "  + data[1][5]);
  body.replaceText('%TOTAL_3%', data[2][3] + " " + data[2][4] + " " + data[2][5]);
}

我假设您想要总计这些单元格中的值,如果不是这种情况,请告诉我,我将更新我的代码。

关于您所做的事情,根据Apps Script Best Practices,应避免多次调用API,因为它们是您要使用的最重的方法(尤其是getValue() )。理想的做法是使用getValues()获取一次值并处理返回的二维数组(Documentation here

另一件事,当您调用body.replaceText('%DESCRIPTION_STRING1%', item1 )item1item2item3都是2D数组时,因此在替换中使用它们是行不通的,这就是为什么我问你想和他们做什么。

最后,我认为body.replaceText()的替代方法是提取正文,并对字符串进行所有搜索,然后将整个正文替换为结果。这意味着更少的API调用。