DEV Community

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)