Tutorial – Crie uma Página Web para Enviar Dados à sua Planilha Google
Neste guia completo, você aprenderá o passo a passo para construir uma página web personalizada, capaz de enviar dados — como lançamentos de despesas, novos contatos ou qualquer outra informação — diretamente para a sua Planilha Google.
Vamos transformar uma simples planilha em um sistema com uma interface dedicada, usando o poder do Google Apps Script.
✅ Como estruturar sua planilha para receber dados de forma organizada.
✅ Os fundamentos do Google Apps Script para criar a lógica da sua aplicação (Código.gs).
✅ A estrutura de uma interface web (HTML, CSS e JavaScript) que se comunica com sua planilha.
✅ O passo a passo para publicar seu projeto como um Aplicativo Web seguro e acessível.
Este projeto é a porta de entrada para o mundo da automação com Google Planilhas e mostra o poder que você tem em mãos para criar suas próprias ferramentas.
/**
* Função principal que é executada quando acessamos o link do nosso App.
* Ela serve a nossa página HTML.
*/
function doGet(e) {
// ⚠️ ATENÇÃO: O nome do arquivo abaixo ('Index') deve ser IDÊNTICO
// ao nome do seu arquivo HTML. O código diferencia maiúsculas de minúsculas.
// Se o seu arquivo for 'index.html' (minúsculo), mude para 'index'.
return HtmlService.createHtmlOutputFromFile('Index')
.setTitle('Lançador de Despesas');
}
/**
* Esta é a função que será chamada pelo nosso formulário.
* Ela recebe os dados da despesa e os adiciona na planilha.
* @param {Object} dadosDoFormulario - Um objeto contendo os valores dos campos do formulário.
*/
function lancarDespesa(dadosDoFormulario) {
try {
const planilha = SpreadsheetApp.getActiveSpreadsheet();
const abaDespesas = planilha.getSheets()[0];
// 1. Convertemos o valor que vem do formulário (texto) para um número decimal
// O parseFloat garante que "25.50" vire o número 25,50 para a planilha
const valorNumerico = parseFloat(dadosDoFormulario.valor);
const novaLinha = [
new Date(),
dadosDoFormulario.descricao,
dadosDoFormulario.categoria,
valorNumerico // Enviamos agora como NÚMERO e não texto
];
abaDespesas.appendRow(novaLinha);
// 2. Formatamos a célula que acabamos de inserir para o padrão brasileiro
// Pegamos a última linha, na coluna 4 (onde está o valor)
const ultimaLinha = abaDespesas.getLastRow();
abaDespesas.getRange(ultimaLinha, 4).setNumberFormat("#,##0.00");
return { success: true, message: "Despesa lançada com sucesso!" };
} catch (e) {
Logger.log(e);
return { success: false, message: "Ocorreu um erro: " + e.message };
}
} <!DOCTYPE html>
<html>
<head>
<base target="_top">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
/* Reseta estilos básicos e define a fonte */
body {
font-family: Arial, sans-serif;
background-color: #f4f4f9;
margin: 0;
padding: 15px;
}
/* Container principal do formulário */
.container {
max-width: 500px;
margin: 0 auto;
background-color: #ffffff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
/* Estilo para o título */
h2 {
text-align: center;
color: #333;
}
/* Estilo para os grupos de formulário (rótulo + campo) */
.form-group {
margin-bottom: 15px;
}
/* Estilo para os rótulos (labels) */
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #555;
}
/* Estilo para os campos de texto e a caixa de seleção */
.form-group input, .form-group select {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box; /* Garante que o padding não aumente a largura */
font-size: 16px;
}
/* Estilo para o botão de envio */
.btn {
width: 100%;
padding: 12px;
background-color: #4A86E8; /* Azul Google */
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 18px;
font-weight: bold;
}
/* Efeito visual quando o mouse passa por cima do botão */
.btn:hover {
background-color: #357ae8;
}
</style>
</head>
<body>
<main class="container">
<h2>Lançador de Despesas</h2>
<form id="despesaForm">
<div class="form-group">
<label for="descricao">Descrição</label>
<input type="text" id="descricao" name="descricao" required>
</div>
<div class="form-group">
<label for="valor">Valor (R$)</label>
<input type="number" step="0.01" id="valor" name="valor" placeholder="Ex: 25,50" required>
</div>
<div class="form-group">
<label for="categoria">Categoria</label>
<select id="categoria" name="categoria" required>
<option value="">Selecione...</option>
<option value="Mercado">Mercado</option>
<option value="Transporte">Transporte</option>
<option value="Lazer">Lazer</option>
<option value="Contas">Contas</option>
<option value="Outros">Outros</option>
</select>
</div>
<button type="submit" class="btn" id="submitBtn">Lançar Despesa</button>
</form>
</main>
<script>
// Seleciona o formulário e o botão pelo ID
const form = document.getElementById('despesaForm');
const submitBtn = document.getElementById('submitBtn');
// Adiciona um "ouvinte" para o evento de envio do formulário
form.addEventListener('submit', function(e) {
// 1. Impede o comportamento padrão do formulário (que é recarregar a página)
e.preventDefault();
// 2. Desabilita o botão para evitar cliques duplos e dá um feedback visual
submitBtn.disabled = true;
submitBtn.textContent = 'Enviando...';
// 3. Cria um objeto com os dados do formulário
const despesa = {
descricao: form.elements['descricao'].value,
valor: form.elements['valor'].value,
categoria: form.elements['categoria'].value
};
// 4. A MÁGICA ACONTECE AQUI!
// 'google.script.run' é o que conecta o HTML com o seu Code.gs
google.script.run
.withSuccessHandler(function(response) {
// Esta função é executada se o backend retornar sucesso
alert(response.message); // Mostra a mensagem de sucesso
form.reset(); // Limpa o formulário
submitBtn.disabled = false; // Reabilita o botão
submitBtn.textContent = 'Lançar Despesa'; // Restaura o texto do botão
})
.withFailureHandler(function(error) {
// Esta função é executada se ocorrer um erro
alert('Erro: ' + error.message);
submitBtn.disabled = false; // Reabilita o botão em caso de erro
submitBtn.textContent = 'Lançar Despesa';
})
.lancarDespesa(despesa); // Chama a função no Code.gs, passando nosso objeto de despesa
});
</script>
</body>
</html> Precisa de uma solução sob medida?
Nós usamos cookies para analisar o tráfego do site e melhorar sua experiência. Ao clicar em 'Aceitar', você concorda com o uso de ferramentas de estatística, conforme detalhado em nossa Política de Privacidade.