Generate branded PDF invoices from a Google Sheets spreadsheet and email them to clients automatically using Google Apps Script.
This project adds a custom "Invoicing" menu to your Sheet. It reads each row, renders a luxury-themed HTML invoice, converts it to PDF, emails the client, and marks the row as Done.
- Custom Sheets menu: Invoicing → Generate & Send Invoices
- HTML template → high-quality PDF invoice (Drive conversion)
- Automated email with PDF attachment via Gmail
- Per-row status tracking and error logging in the sheet
- Easy branding: edit
invoice.htmlfor look & feel
- Google Apps Script (SpreadsheetApp, HtmlService, DriveApp, MailApp)
- HTML/CSS (invoice template)
Code.gs— Google Apps Script backend logic (menu, PDF generation, email)invoice.html— HTML invoice template used to render PDFssample Data.xlsx— Example dataset layout for quick testing (optional)
Create a Google Sheet with a header row that includes the following columns (case-sensitive):
Invoice_NoClient_NameEmailServiceAmount(numeric)Due_Date(date)AddressStatus(left blank; script updates toDoneor writes an error)
Rows with an empty Status are processed; others are skipped.
- Create a Drive folder for PDFs
- In Google Drive, create a folder (e.g.,
Invoices) - Copy its Folder ID from the URL
- Prepare the Sheet
- Create a new Google Sheet
- Add the headers listed above in row 1
- Add a few test rows
- Add Apps Script files
- In the Sheet, open Extensions → Apps Script
- Create a script file named
Code.gsand paste the contents from this repo’sCode.gs - Create an HTML file named
invoice.htmland paste the contents from this repo’sinvoice.html
- Configure the script
- In
Code.gs, set:PDF_FOLDER_IDto your Drive folder IDSHEET_NAMEto your sheet tab name (defaultSheet1)
- Authorize
- Click Run ▶ to execute a simple function (e.g.,
onOpen) and grant permissions for Drive, Gmail, and Sheets
- Open your Sheet → you’ll see a new menu: Invoicing → Generate & Send Invoices
- The script will:
- Read rows where
Statusis blank - Render
invoice.htmlwith row data - Create a PDF in your Drive folder
- Send an email with the PDF attached to
Email - Update
StatustoDone(orError: …on failure)
- Read rows where
Tip: Start with one or two test rows and your own email before sending to customers.
-
Spreadsheet headers and sample rows:
-
Apps Script editor with backend code:
-
Invoice HTML template (branding/customization):
-
Drive folder with generated PDFs:
-
View or download a generated sample invoice:
Tip: On GitHub, click the link above, then use “Download” or “View raw” to preview the PDF.
- Branding: Edit colors, logo, fonts inside
invoice.html - Currency: Replace the currency symbol (₹) in
invoice.htmlwith your own - Email body/subject: Tweak
sendEmailWithAttachmentinCode.gs - Sheet name: Update
SHEET_NAME - Folder: Update
PDF_FOLDER_ID
You can schedule the job (e.g., daily) via Apps Script Triggers:
- Apps Script editor → Triggers → Add Trigger
- Choose
createAndSendInvoices - Event source: Time-driven, then set frequency
Visual steps:
-
Trigger overview after creation:
-
Choose function to run:
-
Select event source:
-
Pick automation time/frequency:
Google quotas apply (Gmail send limits, Apps Script runtime, Drive operations). For most small businesses, this workflow stays within limits, but batch sizes should be moderate. If you hit limits, break the work into smaller chunks or run on a schedule.
- Status column not found: Ensure
Statusexists in row 1 - Dates look wrong: Confirm
Due_Datecells are valid dates; locale formatting is applied viatoLocaleDateString() - Attachments missing: Verify
PDF_FOLDER_IDis valid and Drive permissions are granted - Amount formatting:
invoice.htmlcallsamount.toFixed(2); ensureAmountis numeric in the Sheet - Authorization prompts: First run requires allowing Gmail/Drive/Sheets scopes
- The script uses Gmail, Drive, and Sheets APIs in your account context
- No third-party services are called
- Be careful committing real client data to GitHub; use test data only
- Multiple line items and taxes/discounts
- Currency/locale formatting helpers
- Retry and partial failure reporting
- Time-driven schedules and batching
- Unit tests with clasp + TypeScript (optional)
- See
docs/ARCHITECTURE.mdfor data flow internals - See
docs/USAGE_GUIDE.mdfor step-by-step screenshots and tips - See
docs/RESUME_BLURB.mdfor resume-ready bullets
Choose a license before open-sourcing (e.g., MIT, Apache-2.0). Add a LICENSE file to the repo.







