DEV Community

Justin Poehnelt for Google Workspace Developers

Posted on

Exporting Individual Tabs from Google Docs as PDFs

Google Docs tabs are great for organizing large documents, but there's no built-in way to export each tab as a separate PDF. Here's how to automate this using the Google Docs API and Google Drive API

Setup

You'll need a Google Cloud project with the Docs API and Drive API enabled, plus a service account with a JSON key. Share your Google Doc with the service account email. You could also use OAuth with user credentials.

The Code

import { google } from "googleapis";
import fs from "fs";
import path from "path";
import { Readable } from "stream";

const FILE_ID = "YOUR_DOCUMENT_ID";
const OUT_DIR = "exports";

async function main() {
  const auth = new google.auth.GoogleAuth({
    credentials: {
      client_email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
      private_key: process.env.GOOGLE_PRIVATE_KEY
        .replace(/\\n/g, "\n"),
    },
    scopes: [
      "https://www.googleapis.com/auth/drive.readonly",
      "https://www.googleapis.com/auth/documents.readonly",
    ],
  });

  const docs = google.docs({ version: "v1", auth });
  const { token } = await auth.getAccessToken();

  const res = await docs.documents.get({
    documentId: FILE_ID,
    includeTabsContent: true,
  });

  for (const tab of res.data.tabs) {
    const { title, tabId } = tab.tabProperties;
    const name = `${title.replace(/ /g, "-")}.pdf`;
    const dest = path.join(OUT_DIR, name);

    const url =
      `https://docs.google.com/document/d/` +
      `${FILE_ID}/export?format=pdf&tab=${tabId}`;

    const response = await fetch(url, {
      headers: { Authorization: `Bearer ${token}` },
    });

    if (!response.ok || !response.body) {
      throw new Error(`Failed to download "${name}"`);
    }

    await new Promise((resolve, reject) => {
      Readable.fromWeb(response.body)
        .pipe(fs.createWriteStream(dest))
        .on("finish", resolve)
        .on("error", reject);
    });

    console.log(`Downloaded ${name}`);
  }
}

main();
Enter fullscreen mode Exit fullscreen mode

How It Works

Two key pieces make this work:

  1. includeTabsContent: true - When calling docs.documents.get, this parameter populates the tabs array with metadata for each tab, including the tabId.

  2. Undocumented tab URL parameter - The export URL pattern https://docs.google.com/document/d/{FILE_ID}/export?format=pdf&tab={tabId} allows exporting individual tabs. The official files.export API doesn't support per-tab exports (issue tracker). Since this is undocumented, it could change.

Top comments (0)