The right way to Work with Doc Tabs in Google Apps Script

Shubham
7 Min Read

Google Docs now enables you to set up your paperwork into tabs and sub-tabs. This alteration is especially helpful for managing lengthy paperwork like worker handbooks and coaching manuals. As a result of the doc is now divided into a number of sections, the navigation by means of the doc is extra intuitive and simpler.

Nonetheless, this structural change considerably impacts how we work with paperwork by means of the DocumentApp service of Google Apps Script.

Beforehand, Google Docs handled your complete doc as a single entity. With the brand new tabbed construction, every tab is now a doc itself with its personal physique, header, footer, and footnotes. Your Google Apps Script code will have to be up to date to work with the brand new doc construction.

Let me clarify with some examples:

Discovering and Changing Textual content

Within the non-tabbed model of Google Docs, you may get the physique of the doc and use the findText methodology to search out and substitute textual content.

const findAndReplaceText = (searchText, replaceText) => {
  const doc = DocumentApp.getActiveDocument();
  const documentBody = doc.getBody();

  const searchResult = documentBody.findText(searchText);

  if (searchResult !== null) {
    const startIndex = searchResult.getStartOffset();
    const endIndex = searchResult.getEndOffsetInclusive();
    const textElement = searchResult.getElement().asText();
    textElement.deleteText(startIndex, endIndex);
    textElement.insertText(startIndex, replaceText);
  }
};

Working with A number of Tabs

The above code will nonetheless work within the tabbed model of Google Docs. Nonetheless, it could solely work on the primary (default) tab or the tab that’s at present energetic. You probably have a doc with a number of tabs, you would wish to use the identical operations to every tab to search out and substitute textual content in your complete doc.

Get the Listing of Doc Tabs

To work with all tabs in a doc, we first want a perform to retrieve all tabs in a doc.

const getDocumentTabs = doc => {
  const allTabs = [];

  const collectTabs = (tabs = []) => {
    tabs.forEach(tab => {
      if (tab.getType() === DocumentApp.TabType.DOCUMENT_TAB) {
        allTabs.push(tab);
        collectTabs(tab.getChildTabs());
      }
    });
  };

  collectTabs(doc.getTabs());
  return allTabs;
};

Discover and Substitute Textual content in Doc Tabs

Now that you’ve an array of all tabs (most important tabs and sub-tabs), you may apply the search and substitute operations to every tab.

const findAndReplaceTextInAllTabs = (searchText, replaceText) => {
  const doc = DocumentApp.getActiveDocument();
  const allTabs = getDocumentTabs(doc);
  allTabs.forEach(tab => {
    findAndReplaceTextInTab(searchText, replaceText, tab);
  });
  doc.saveAndClose();
};

const findAndReplaceTextInTab = (searchText, replaceText, tab) => {
  const tabBody = tab.getBody();
  const searchResult = tabBody.findText(searchText);

  if (searchResult !== null) {
    const startIndex = searchResult.getStartOffset();
    const endIndex = searchResult.getEndOffsetInclusive();
    const textElement = searchResult.getElement().asText();
    textElement.deleteText(startIndex, endIndex);
    textElement.insertText(startIndex, replaceText);
  }
};

Export Google Docs to PDF

Let’s take a look at one other instance the place you need to export a Google Docs doc to a PDF or a Phrase doc.

Within the non-tabbed model of Google Docs, you may use the Google Drive API to export your complete Google Docs doc to a different format.

const exportGoogleDocumentToPdf = () => {
  const doc = DocumentApp.getActiveDocument();
  const fileId = doc.getId();
  const exportMime = "software/pdf";
  const baseUrl = "https://www.googleapis.com/drive/v3/recordsdata";
  const apiUrl = `${baseUrl}/${fileId}/export?mimeType=${encodeURIComponent(exportMime)}`;
  const response = UrlFetchApp.fetch(apiUrl, {
    headers: {
      Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
    },
  });
  const blob = response.getBlob();
  const fileName = `${doc.getName()}.pdf`;
  const file = DriveApp.createFile(blob);
  Logger.log(`Exported Google doc to PDF: ${file.getUrl()}`);
};

The export perform will proceed to work within the new tabbed model of Google Docs. Nonetheless, it is going to export your complete doc as a single PDF or Phrase doc. If you wish to export every tab as a separate doc, you would need to make some modifications to the code.

Export Particular Google Tabs as PDF

We’ve earlier written a perform to get the record of tabs in a Google Docs doc. You may additional broaden this code to get the record of all tab IDs and their names.

const getDocumentTabIds = doc => {
  const allTabs = getDocumentTabs(doc);
  return allTabs.map(tab => tab.getId());
};

You may then use the tab IDs to export every tab as a separate PDF or Phrase doc. Please word that our export endpoint will change for the reason that Drive API doesn’t help exporting particular person tabs.

const exportDocumentTabsToPdf = (documentId, tabId) => {
  const baseUrl = "https://docs.google.com/doc/export";
  const exportUrl = `${baseUrl}?id=${documentId}&exportFormat=pdf&tabId=${tabId}`;
  const response = UrlFetchApp.fetch(exportUrl, {
    headers: {
      Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
    },
  });
  const blob = response.getBlob();
  const file = DriveApp.createFile(blob);
  Logger.log(`Exported tab ${tabId} to PDF: ${file.getUrl()}`);
};

The identical applies to headers and footers in Google Docs.

The doc.getHeader() and doc.getFooter() strategies will now return the header and footer of the present tab. To switch headers and footers throughout all tabs, you’ll want to use modifications to every tab individually.

Doc Studio Integration

The Doc Studio addon enables you to create personalized documents from Google Doc templates. You may even combine multiple documents right into a single doc. The addon is now suitable with the tabbed model of Google Docs.

Share This Article
Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *