Jon
Jon

Reputation: 51

Replace text in header of first page

I am trying to replace text in the first page header of my Google Doc template. If I have a common header on all pages, the "getHeader()" method works, but once I set up a unique first page header I can no longer replace the text. What method can I use to access the text I want to replace?

function createDocument() {
  let headers = Sheets.Spreadsheets.Values.get('1zYB57xVhhTpUQpSuvIjMlFbp3AgCbvQm36jZEFjpyEI', 'A1:Y1');
  let entries = Sheets.Spreadsheets.Values.get('1zYB57xVhhTpUQpSuvIjMlFbp3AgCbvQm36jZEFjpyEI', 'A2:Y');
  let templateId = '1jrYbqKcWhpg_G_IvfOKE8pzN1BfP4HANbGhwdHWO3Jk';
  
  for(let i = 0; i < entries.values.length; i++){
    
    let timestamp = entries.values[i][0];
    let buildingNumber = entries.values[i][1];
    
    // Make a copy of the template file
    let documentId = DriveApp.getFileById(templateId).makeCopy().getId();
    
    // Rename the copied file
    DriveApp.getFileById(documentId).setName(buildingNumber + ' Building Emergency Profile ' + timestamp);
    
    // Get the document body as a variable
    let header = DocumentApp.openById(documentId).getHeader();
    let body = DocumentApp.openById(documentId).getBody();
    
    // Replace tags with content from Sheet
    header.replaceText('{{timestamp}}', timestamp)
    body.replaceText('{{Building Number}}', buildingNumber)
    
           
  }
}

Upvotes: 1

Views: 2462

Answers (3)

Max Makhrov
Max Makhrov

Reputation: 18707

function test_replaceAllInFootersAndHeaders() {
  var doc = DocumentApp.getActiveDocument();
  var d = doc.getHeader().getParent();
  
  for (var i = 0; i < 4; i++) {
    try {
      d.getChild(i).replaceText('{{foo}}', 'bar');
      Logger.log(d.getChild(i).getType());
    }
    catch(err) {}
    // BODY_SECTION
    // HEADER_SECTION
    // HEADER_SECTION
    // FOOTER_SECTION
  }
}

This solution is based on the existing answer. It is for the demonstration of the possible workflow.

Figured out that header.getParent() gives type = DOCUMENT but it's children are headers and footers.

It is undocumanted feature:

https://developers.google.com/apps-script/reference/document/header-section#getParent()

Upvotes: 0

Jon
Jon

Reputation: 51

I figured out the following procedure to locate the first page header and make the text replacement.

// Get the document first page header as a variable
let header = DocumentApp.openById(documentId).getHeader();
let dHeader = header.getParent().getChild(3).asHeaderSection();

// Replace tags with content from Sheet
dHeader.replaceText('{{timestamp}}', timestamp)

Upvotes: 3

Tanaike
Tanaike

Reputation: 201368

I believe your goal as follows.

  • You want to separate the 1st page header and after the 2nd page headers.
  • You want to modify only the 1st page header.
    • You want to replace the texts in the 1st page header.
  • In your current situation, all pages are the same header in Google Document.

In the current stage, in order to separate the 1st page header and after the 2nd page headers and modify the 1st page header, it seems that it is required to use Google Docs API. So in this answer, I would like to introduce the method for separating the 1st page header and after the 2nd page headers and modifying only the 1st page header using Google Docs API.

Flow:

The flow of this sample script is as follows.

  1. Enable 1st page header using documents.batchUpdate method.
  2. Retrieve the 1st page header ID using documents.get method.
  3. Replace the texts of the 1st page header using documents.batchUpdate method.

Sample script:

Before you use this script, please enable Google Docs API at Advanced Google services.

function replace1stPageHeader(documentId, repObj) {
  // 1. Enable 1st page header using documents.batchUpdate method.
  const resource1 = {requests:[
    {updateDocumentStyle:{documentStyle:{useFirstPageHeaderFooter:true},fields:"useFirstPageHeaderFooter"}}
  ]};
  Docs.Documents.batchUpdate(resource1, documentId);
  
  // 2. Retrieve the 1st page header ID using documents.get method.
  const obj = Docs.Documents.get(documentId);
  const headerId = obj.documentStyle.firstPageHeaderId;
  
  // 3. Replace the texts of the 1st page header using documents.batchUpdate method.
  const hObj = obj.headers[headerId].content;
  const existingText = hObj.reduce((s, {paragraph}) => {
    paragraph.elements.forEach(({textRun}) => s += textRun.content);
    return s;
  }, "");
  const newText = Object.entries(repObj).reduce((s, [k, v]) => s.replace(new RegExp(k, 'g'), v), existingText);
  const resource2 = {requests:[
    {deleteContentRange:{range:{segmentId:headerId,startIndex:0,endIndex:hObj.pop().endIndex - 1}}},
    {insertText:{location:{segmentId:headerId,index:0},text:newText}}
  ]};
  Docs.Documents.batchUpdate(resource2, documentId);
}

// Please run this function.
function main() {
  const documentId = "###";  // Please set the Google Document ID.
  const replaceObject = {  // Please set the replace texts.
    "{{timestamp}}": "replace text 1",
    "{{Building Number}}": "replace text 2"
  }
  replace1stPageHeader(documentId, replaceObject);
}
  • replaceObject is used for replacing the header texts.
    • In above sample, {{timestamp}} and {{Building Number}} are replaced with replace text 1 and replace text 2, respectively.

References:

Upvotes: 3

Related Questions