请求开发Google Forms手写签名转PNG功能及相关脚本支持
Solution: Capture Handwritten Signatures & Sync to Google Sheet via Web App
Since Google Forms doesn’t include a native signature field, building a custom Web App is the most reliable way to capture stylus signatures, convert them to PNGs, and auto-sync everything to a Google Sheet. Let’s break this down step by step.
Step 1: Create the Google Apps Script Project
- Head to your Google Drive → New → More → Google Apps Script
- Rename the project (e.g., "Signature Capture Sync") to keep things organized
Part 1: Frontend (index.html)
Replace the default Code.gs with a new HTML file (click + → HTML → name it index.html), then paste this code:
<!DOCTYPE html> <html> <head> <base target="_top"> <style> body { font-family: Arial, sans-serif; max-width: 600px; margin: 2rem auto; padding: 0 1rem; } #signatureCanvas { border: 2px solid #333; border-radius: 4px; width: 100%; height: 200px; } .button-group { margin-top: 1rem; display: flex; gap: 1rem; } button { padding: 0.8rem 1.5rem; border: none; border-radius: 4px; cursor: pointer; } #clearBtn { background-color: #dc3545; color: white; } #submitBtn { background-color: #28a745; color: white; } </style> </head> <body> <h2>Sign Here</h2> <canvas id="signatureCanvas"></canvas> <div class="button-group"> <button id="clearBtn">Clear Signature</button> <button id="submitBtn">Submit Signature</button> </div> <script> const canvas = document.getElementById('signatureCanvas'); const ctx = canvas.getContext('2d'); let isDrawing = false; // Fix blurry signatures by matching canvas to display size canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; // Basic drawing logic for mouse canvas.addEventListener('mousedown', startDrawing); canvas.addEventListener('mousemove', draw); canvas.addEventListener('mouseup', stopDrawing); canvas.addEventListener('mouseout', stopDrawing); // Touch support for styluses/mobile devices canvas.addEventListener('touchstart', (e) => { e.preventDefault(); const touch = e.touches[0]; const mouseEvent = new MouseEvent('mousedown', { clientX: touch.clientX, clientY: touch.clientY }); canvas.dispatchEvent(mouseEvent); }); function startDrawing(e) { isDrawing = true; ctx.beginPath(); ctx.moveTo(e.offsetX, e.offsetY); } function draw(e) { if (!isDrawing) return; ctx.lineTo(e.offsetX, e.offsetY); ctx.lineWidth = 3; ctx.lineCap = 'round'; ctx.stroke(); } function stopDrawing() { isDrawing = false; } // Clear button functionality document.getElementById('clearBtn').addEventListener('click', () => { ctx.clearRect(0, 0, canvas.width, canvas.height); }); // Submit signature to backend document.getElementById('submitBtn').addEventListener('click', async () => { const signatureData = canvas.toDataURL('image/png'); if (!signatureData.includes('data:image/png;base64,')) { alert('Please sign before submitting!'); return; } try { await google.script.run.withSuccessHandler(() => { alert('Signature submitted successfully!'); ctx.clearRect(0, 0, canvas.width, canvas.height); }).withFailureHandler((error) => { alert(`Error: ${error.message}`); }).saveSignature(signatureData); } catch (err) { alert(`Submission failed: ${err}`); } }); </script> </body> </html>
Part 2: Backend (Code.gs)
Create a new script file (click + → Script → name it Code.gs), then paste this code:
// Serve the frontend HTML when the Web App is accessed function doGet() { return HtmlService.createHtmlOutputFromFile('index.html') .setTitle('Signature Capture'); } // Save signature to Google Sheet and Drive function saveSignature(signatureData) { // Replace with your Google Sheet ID (find it in the sheet URL) const sheetId = 'YOUR_SHEET_ID_HERE'; const sheetName = 'Signatures'; const sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName); // Optional: Create or use an existing Drive folder for signatures const driveFolder = DriveApp.getFolderById('YOUR_DRIVE_FOLDER_ID_HERE') || DriveApp.createFolder('Signatures'); // Convert base64 signature data to a PNG blob const base64Data = signatureData.split(',')[1]; const blob = Utilities.newBlob(Utilities.base64Decode(base64Data), 'image/png', `Signature_${new Date().toISOString().replace(/[:.]/g, '-')}.png`); // Save the PNG to Drive and set sharing permissions const file = driveFolder.createFile(blob); file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW); // Adjust as needed // Add entry to Google Sheet sheet.appendRow([ new Date(), // Timestamp file.getUrl(), // Link to signature PNG 'Submitted' // Status (customize this if needed) ]); return 'Success'; }
Step 2: Configure & Deploy the Web App
- Replace
YOUR_SHEET_ID_HEREwith the ID from your target Google Sheet’s URL (looks likehttps://docs.google.com/spreadsheets/d/[SHEET_ID]/edit) - Replace
YOUR_DRIVE_FOLDER_ID_HEREwith the ID of a Drive folder (or remove that line to use your root Drive folder) - Click Deploy → New deployment
- Under Type, select Web app
- Set Execute as to Me (your email)
- Set Who has access to Anyone, even anonymous (restrict this if you need limited access)
- Click Deploy, authorize the script when prompted, then copy the Web App URL
Step 3: Test the Workflow
- Open the Web App URL in a browser (or on a tablet with a stylus)
- Draw your signature and click Submit
- Check your Google Sheet: you’ll see a new row with a timestamp, signature link, and status
- Click the link to view the PNG signature in Drive
Customization Tips
- Add user input fields (name, email) to the frontend and update the
appendRowcall to capture more data - Adjust the
file.setSharingline if you don’t want signature links to be publicly accessible - Expand error handling to log issues to a separate sheet for debugging
内容的提问来源于stack exchange,提问作者Filip Blomqvist
相关产品推荐
相关产品推荐

