Search code examples
google-apps-scriptgoogle-docsgoogle-docs-api

How to add header section in merged Google document via Google Apps script?


I'm trying to merge 2 Google doc files using their ids. Below is the code snippet I followed.

  var docIDs = ['documentID_1', 'documentID_2', 'documentID_3', 'documentID_4'];
  var baseDoc = DocumentApp.openById(docIDs[0]);

  var body = baseDoc.getActiveSection();

  for (var i = 1; i < docIDs.length; ++i) {
    var otherBody = DocumentApp.openById(docIDs[i]).getActiveSection();
    var totalElements = otherBody.getNumChildren();
    for (var j = 0; j < totalElements; ++j) {
      var element = otherBody.getChild(j).copy();
      var type = element.getType();
      if (type == DocumentApp.ElementType.PARAGRAPH) body.appendParagraph(element);
      else if (type == DocumentApp.ElementType.TABLE) body.appendTable(element);
      else if (type == DocumentApp.ElementType.LIST_ITEM) body.appendListItem(element);
      else throw new Error('Unknown element type: ' + type);
    }
  }

The merged document looks fine. But the header and footer section is not added in the merged document. I can see there is a header and footer section in the original document. Someone, please help me to fix this.


Solution

  • The script you're using is only working with certain elements from a document like paragraphs, tables and lists. I made some updates to the script to get the HeaderSection and FooterSection as well.

    You can try the following script:

    UPDATED SCRIPT

    function myFunction() {
      var docIDs = ['documentID_1', 'documentID_2'];
      var newDoc = DocumentApp.create('Document Name');//You can change the name of the new document
      var newDocID = newDoc.getId();
      var baseDoc = DocumentApp.openById(newDocID);
      baseDoc.addHeader();
      baseDoc.addFooter();
    
      var body = baseDoc.getBody();
      var bodyHeader = baseDoc.getHeader();
      var bodyFooter = baseDoc.getFooter();
    
      for (var i = 0; i < docIDs.length; ++i) {
        var otherBody = DocumentApp.openById(docIDs[i]).getBody();
        var otherHeader = otherBody.getParent();
        var totalEl = otherHeader.getNumChildren();
        var totalElements = otherBody.getNumChildren();
    
        for (var j=0; j < totalEl; ++j){
          var el = otherHeader.getChild(j).copy()
          var t = el.getType();
          if (t == DocumentApp.ElementType.BODY_SECTION) continue;
          else if (t == DocumentApp.ElementType.HEADER_SECTION){
            var header = otherHeader.getChild(j).asHeaderSection().getText();
            bodyHeader.appendParagraph(header);
          }
          else if (t == DocumentApp.ElementType.FOOTER_SECTION){
            var footer = otherHeader.getChild(j).asFooterSection().getText();
            bodyFooter.appendParagraph(footer);
          }
          else throw new Error('Unknown element type: ' + type);
        }
    
        for (var k = 0; k < totalElements; ++k) {
          var element = otherBody.getChild(k).copy();
          var type = element.getType();
          if (type == DocumentApp.ElementType.PARAGRAPH) body.appendParagraph(element);
          else if (type == DocumentApp.ElementType.TABLE) body.appendTable(element);
          else if (type == DocumentApp.ElementType.LIST_ITEM) body.appendListItem(element);
          else throw new Error('Unknown element type: ' + type);
        }
      }
    }
    

    I tested the script with Google docs that includes headers/footers and it worked. I'm sure there is a better way to achieve this but at least it can give you an idea on how to work with different elements of a Google Doc.

    If you have any questions let me know.