Back to BlogAutomation

Generate PDF Invoices from Google Sheets Automatically

Stop manually creating invoices in Word. Build a system that generates PDFs from Google Sheets data and emails them to clients in one click.

December 24, 2025
3 min read

You track your work in a spreadsheet. Then you spend 3 hours a month manually copying that data into a Word template, exporting to PDF, attaching to emails.

If your invoice data already lives in Sheets, the PDF should generate itself.

Here's how we automate it. The script will read your pending invoices, fill a template, export to PDF, email the client, and mark the row as sent.

The Code: One-Click Invoicing

1. Setup

  • Sheet: Headers: Invoice #, Client Name, Email, Amount, Date, Service Description, Status.
  • Template: A Google Doc with text like: "Invoice for {{Client}}", "Amount Due: {{Amount}}".

2. The Script

// CONFIGURATION
const TEMPLATE_ID = "YOUR_DOC_TEMPLATE_ID";
const FOLDER_ID = "YOUR_INVOICE_FOLDER_ID";
 
function generateInvoices() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Invoices');
  const data = sheet.getDataRange().getValues();
  
  // Skip headers
  for (let i = 1; i < data.length; i++) {
    const row = data[i];
    const status = row[6]; // Col G
    
    if (status === "Sent") continue;
    
    try {
      createAndSendInvoice(row, i + 1, sheet);
    } catch (e) {
      Logger.log("Error: " + e.toString());
    }
  }
}
 
function createAndSendInvoice(row, rowIndex, sheet) {
  const [invNum, client, email, amount, date, desc] = row;
  
  // 1. Setup Files
  const template = DriveApp.getFileById(TEMPLATE_ID);
  const folder = DriveApp.getFolderById(FOLDER_ID);
  const tempFile = template.makeCopy(`Invoice ${invNum} - ${client}`, folder);
  const tempDoc = DocumentApp.openById(tempFile.getId());
  const body = tempDoc.getBody();
  
  // 2. Replace Placeholders
  body.replaceText("{{Client}}", client);
  body.replaceText("{{Amount}}", "$" + amount);
  body.replaceText("{{Date}}", new Date(date).toLocaleDateString());
  body.replaceText("{{Description}}", desc);
  body.replaceText("{{InvoiceNum}}", invNum);
  
  tempDoc.saveAndClose();
  
  // 3. Convert to PDF
  const pdf = tempFile.getAs(MimeType.PDF);
  
  // 4. Email
  MailApp.sendEmail({
    to: email,
    subject: `Invoice #${invNum} from [Your Company]`,
    body: `Hi ${client},\n\nPlease find your invoice attached for ${desc}.\n\nThanks!`,
    attachments: [pdf]
  });
  
  // 5. Cleanup & Update Status
  tempFile.setTrashed(true);
  sheet.getRange(rowIndex, 7).setValue("Sent"); // Col G
}

Three things to remember:

  1. Drive API exports PDFs natively-no DocuSign, no Zapier tax. Watch your 20K daily URL fetch quota if you're processing hundreds daily.

  2. One trigger handles 50 invoices in under 2 minutes-test your batch size before going live. Script execution maxes at 6 minutes total.

  3. Branded PDFs saved + Gmail drafts ready-eliminates 6 hours of weekly clicking and kills the "wrong attachment" panic.

Your accountant gets Monday mornings back. Your clients get professional invoices. You get an audit trail in Drive. Build it this weekend, or call me Friday and it's running Monday.

Why Not QuickBooks?

QuickBooks is great for accounting, but it sucks at custom workflows. If you need to pull data from a project tracker or time-sheet that lives in Google Sheets, this script bridges the gap perfectly.

Get the template + script logic pre-packaged. Book a set-up call.

Newsletter

Get more tips like this

Subscribe for practical Google Workspace automation tips.

Free updates. No spam. Unsubscribe any time.

Want more help?

We're here to help. Drop us an email and let's explore how we can optimize your workflows.

Email us

hello@mereth.dev

business automationinvoice automationGoogle Apps ScriptPDF generationworkflow automationfinance automation