使用 setLinkUrl() 和 Google Apps 脚本将 URL 地址文本设置为可点击的 URL

问题描述 投票:0回答:1

祝大家新年快乐..

我有一个名称列表和一个 URL 列表,我将使用它们来生成包含每个数据内容的 PDF 文档。在文档中,我希望 URL 地址是可点击的文本。 对于单个数据,这不是问题,我成功地创建了它。当我生成多个文档时,我会遇到困难。我制作的脚本如下:

 function createPDFDocuments() {
   var sheetDatabase  = SpreadsheetApp.getSheetByName('DATABASE"');
   var startRow       = 2 ; 
   var rowNo          = sheetDatabase.getLastRow();
   var sumRow         = rowNo - startRow  ;
   var fileMasterID   = DriveApp.getFileById('DOCUMENT ID XXXXX') ;  

// I have a list of Name  in a Spreadsheet, that are in column number 2
   var nameList       = sheetDatabase.getRange(2,2,sumRow,1).getValues() ;

// I have a list of URLs to, in a Spreadsheet that are in column number 8
   var urlDataList    = sheetDatabase.getRange(2,8,sumRow,1).getValues() ;

   for(var i=0;i<nameList.length;i++){ 

   var urlData  = (urlDataList[i][0]) ;
   var name     = (nameList[i][0]) ;

// Copy New Document from Document Master
   var copyId     = DriveApp.getFileById(fileMasterID).makeCopy('DOC FOR : '+name).getId();                      
   var copyDoc    = DocumentApp.openById(copyId);
   var copyBody   = copyDoc.getActiveSection();

// The master document has text that will be replaced with data, namely <<TEXT NAME>> 
// to be replaced with the names in the list, and <<TEXT URL ADDRESS>> 
// which will be replaced with the URL in the list

   copyBody.replaceText('<<TEXT NAME>>', name );
   copyBody.replaceText('<<TEXT URL ADDRESS>>', urlData);

// Replace with the text to make a link and the corresponding URL
   var teksUrlData  =  urlData ;

// Find the text, to turn into a link
   var teksRangeUrlData =copyBody.findText(teksUrlData);

// This is where my script failed, when I create a log, it returns null.
   Logger.log("Range URL Data   : "+teksRangeUrlData)

// If text is found, convert it to a link
   if (teksRangeUrlData) {
      var teksElement  = teksRangeUrlData.getElement();
      var teksStart    = teksRangeUrlData.getStartOffset();
      var teksEnd      = teksRangeUrlData.getEndOffsetInclusive();

// Delete the text between the Start text and the End text    
   teksElement.deleteText(teksStart, teksEnd);

// Enter the link with the appropriate text
   teksElement.insertText(teksStart, teksUrlData).setLinkUrl(urlData);
  
    }

   copyDoc.saveAndClose();

// Convert temporary document to PDF by using the getAs blob conversion

   docblob = DriveApp.getFileById(copyId).getAs("application/pdf"); 

   docblob.setName("DOC FOR : "+name+".pdf");

   var file        = DriveApp.createFile(docblob);
   var newFileId   = file.getId();   
   var newFile     = DriveApp.getFileById(newFileId);

// Move To Destination Folder 
   var docFolder = DriveApp.getFolderById("FOLDER TO SAVE DOC ID XXXX")

   newFile.moveTo( docFolder);

//  Dell Temporary FIle
   DriveApp.getFileById(copyId).setTrashed(true);
      }
   }

我也使用了这个文档,但仍然失败。

任何帮助将不胜感激。

google-apps-script pdf-generation
1个回答
0
投票

修改要点:

  • 我认为 SpreadsheetApp 类没有
    getSheetByName
    的方法。所以,我认为在您的显示脚本中,错误发生在
    var sheetDatabase = SpreadsheetApp.getSheetByName('DATABASE"');
    。但是,你说
    For single data, this is not a problem, and I managed to create it.
    。所以,我担心你可能复制了当前的脚本。
  • 并且,在您的脚本中,
    DATABASE"
    用作工作表名称。是
    DATABASE
    而不是
    DATABASE"
    吗?请再次确认您的工作表名称。
  • sheetDatabase.getRange(2, 2, sumRow, 1)
    的情况下,不会检索最后一行的值。
  • 我认为目标文件夹可以在循环之外声明。
  • 使用类Folder的createFile方法可以直接创建PDF文件到文件夹中。

当这些要点反映在示例脚本中时,就会变成如下所示。

示例脚本:

请将以下脚本复制并粘贴到电子表格的脚本编辑器中。并且,请设置

sheetName
templateDocumentId
dstFolderId
的变量。 请再次确认您的工作表名称。

function createPDFDocuments() {
  const sheetName = "DATABASE"; // Please set your sheet name.
  const templateDocumentId = "###"; // Please set your template document ID.
  const dstFolderId = "###"; // Please set your destination folder ID.

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  const [, ...values] = sheet.getDataRange().getDisplayValues().map(r => [r[1], r[7]]);
  const template = DriveApp.getFileById(templateDocumentId);
  const folder = DriveApp.getFolderById(dstFolderId);
  values.forEach(([name, url]) => {
    if (!name || !url) return;
    const copiedTemplate = template.makeCopy('DOC FOR : ' + name);
    const doc = DocumentApp.openById(copiedTemplate.getId());
    const body = doc.getBody();
    body.replaceText('<<TEXT NAME>>', name);
    const t = "<<TEXT URL ADDRESS>>";
    let s = body.findText(t);
    while (s) {
      const e = s.getElement();
      const start = s.getStartOffset();
      e.asText().replaceText(t, url).asText().setLinkUrl(start, start + url.length - 1, url);
      s = body.findText(t, s);
    }
    doc.saveAndClose();
    folder.createFile(doc.getBlob().setName("DOC FOR : " + name + ".pdf"));
    copiedTemplate.setTrashed(true);
  });
}

运行此脚本时,将复制模板文档,并使用从“B”和“H”列检索的值替换占位符

<<TEXT NAME>>
<<TEXT URL ADDRESS>>
。并且,文档将以 PDF 格式保存到目标文件夹。并且,复制的模板文档将被删除。

注:

  • 从您的显示脚本中,假设
    DATABASE
    工作表的“B”列和“H”列分别是
    name
    url
    的值。请再次确认。

参考资料:

© www.soinside.com 2019 - 2024. All rights reserved.