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.

O que você vai aprender:

✅ 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.

Código.gs

/**
 * 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 };
  }
}

Index.html

<!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>

Acompanhe nas redes sociais

Projetos Personalizados

Precisa de uma solução sob medida?

© 2025 Transformando Planilhas. Todos os direitos reservados.