/// INTEGRATION

Sheet rows to PDFs, in one script.

A short Apps Script turns any row into a PDF in Drive and writes the link back to the sheet — triggered from a custom menu or a form submission.

Works today with Google Sheets's built-in Apps Script — nothing to install

Prerequisites

Test the key before building anything:

curl https://www.ashdocs.com/api/v1/me -H "X-API-Key: ash_live_..."

Setup, step by step

  1. 1

    Open the script editor

    In your spreadsheet: Extensions → Apps Script. A bound project opens — no add-on, no deployment.

  2. 2

    Paste the function

    The API returns JSON with a signed URL; a second UrlFetchApp call downloads the PDF and files it in Drive.

    var ASHDOCS_API = "https://www.ashdocs.com";
    
    function generatePdfFromActiveRow() {
      var sheet = SpreadsheetApp.getActiveSheet();
      var row = sheet.getActiveRange().getRow();
      var values = sheet.getRange(row, 1, 1, 3).getValues()[0];
      var invoiceNo = values[0], client = values[1], amount = values[2];
    
      var res = UrlFetchApp.fetch(ASHDOCS_API + "/api/v1/tools/html-to-pdf", {
        method: "post",
        contentType: "application/json",
        headers: { "X-API-Key": "ash_live_..." },
        payload: JSON.stringify({
          html: "<h1>Invoice " + invoiceNo + "</h1><p>" + client + " — $" + amount + "</p>",
          options: { format: "A4", output: "url" }
        }),
        muteHttpExceptions: true
      });
      if (res.getResponseCode() !== 200) throw new Error(res.getContentText());
    
      var fileUrl = JSON.parse(res.getContentText()).file_url;
      var blob = UrlFetchApp.fetch(fileUrl).getBlob().setName("invoice-" + invoiceNo + ".pdf");
      var file = DriveApp.createFile(blob);
      sheet.getRange(row, 4).setValue(file.getUrl());
    }
  3. 3

    Authorize and run

    Run the function once from the editor — approve the Drive and external-request scopes when prompted. Then wire it to a custom menu (onOpen) or an onFormSubmit trigger so non-technical teammates can use it.

Files in

Sheets holds values, not files — but any URL sitting in a cell (a Drive share link, a hosted upload) can be sent as “file_url” in the JSON payload to any file tool.

Files out

Request "output": "url", then UrlFetchApp.fetch(file_url).getBlob() downloads the PDF and DriveApp.createFile saves it. One line on quotas: UrlFetchApp has daily limits per Google account — high-volume runs belong on Make or n8n instead.

Prefer no code at all? The Make and Zapier pages cover the same “new Sheets row → PDF → Drive” flow with zero scripting.

Three ready-made recipes

Form submission → certificate PDF → Drive + link in row

  1. Attach an onFormSubmit trigger to the function (Triggers → Add Trigger).
  2. Build the HTML from the submitted row's values.
  3. The PDF lands in Drive and column D receives the link — automatically on every submission.

Custom menu: “Generate invoice” for the selected row

  1. Add an onOpen() that creates a menu: SpreadsheetApp.getUi().createMenu("ASHDOCS").addItem("Generate invoice", "generatePdfFromActiveRow").addToUi().
  2. Anyone with edit access selects a row and clicks the menu item — no script knowledge needed.

No-code alternative via Make or Zapierasync / webhook

  1. Trigger: new Sheets row (Make “Watch Rows” or Zapier “New Spreadsheet Row”).
  2. Call html-to-pdf as documented on the Make or Zapier page.
  3. Upload the result to Drive — same outcome, zero script, and the async webhook pattern is available there for slow jobs.

Troubleshooting

SymptomFix
The authorization prompt loopsApprove both requested scopes — Drive access and external requests. Rejecting either makes Google re-prompt on the next run.
Blank PDFLog the HTML string you built from the row values — an off-by-one column range produces empty variables and an empty-looking document.
“Service invoked too many times”Google's daily UrlFetchApp quota is exhausted for the account. Batch less aggressively, or move volume runs to Make or n8n.
401 UnauthorizedCheck for trailing whitespace in the pasted key — Sheets cells and clipboards love adding it.

Frequently asked questions

Do I need to install an add-on?

No. Apps Script is built into every Google Sheet under Extensions → Apps Script — the whole integration is the pasted function on this page.

Where do the PDFs go?

DriveApp.createFile saves them to the My Drive root of the account running the script; the file's link is written back into the row. Use DriveApp.getFolderById(...).createFile(blob) to target a specific folder.

Can non-technical teammates trigger it?

Yes — expose it as a custom menu item (recipe 2) or attach it to a form-submission trigger (recipe 1). After the one-time authorization, it's a click, not code.

Is the script safe to share?

Move the key out of the source first — a two-line change: store it once under Project Settings → Script Properties as ASHDOCS_KEY, then read it with PropertiesService.getScriptProperties().getProperty("ASHDOCS_KEY") instead of the literal string.

Tools used on this page