Relatórios: Excel e cópias de segurança
O CRM passa a exportar os clientes para o Excel e a fazer (e restaurar) cópias de segurança de todos os dados. É o último código guiado: a partir daqui, o CRM é teu!
🎯 No fim desta aula vais conseguir
- Explicar o que é um ficheiro CSV e porque é que o Excel português usa ponto e vírgula.
- Exportar os clientes para um ficheiro que abre no Excel com os acentos corretos.
- Fazer uma cópia de segurança de todo o CRM num ficheiro JSON e restaurá-la depois de perder os dados.
- Explicar porque é que as empresas fazem cópias de segurança (perda de dados e RGPD).
🧰 Antes de começar
- Abre a pasta
meu-crmno VS Code e oindex.htmlcom o Live Server. - Confirma que o painel da aula 15 funciona.
- Para testar bem os acentos, cria (ou edita) um cliente com letras portuguesas, por exemplo: nome João Gonçalves, empresa Pastelaria Ribeirão, notas Ligar às 10h; prefere email.
- Verifica se o computador tem o Excel. Se não tiver, serve o LibreOffice Calc ou o Google Sheets (vê as instruções no passo 4).
😕 Faltaste à aula 15 ou o teu projeto não funciona? Descarrega o ponto de controlo da aula 15, descompacta-o e trabalha a partir dele.
Parte A — A ideia: tirar os dados do CRM (e não os perder) (≈ 15 min)
💡 Relatórios: os dados têm de sair da aplicação
Numa empresa, os dados não ficam fechados dentro de uma aplicação. O chefe pede «manda-me a lista de clientes em Excel»; o contabilista quer os negócios ganhos do mês; o colega do marketing quer os emails dos leads. Por isso, quase todas as aplicações de gestão têm um botão Exportar. O formato mais universal para isso é o CSV.
CSV (Comma-Separated Values, «valores separados por vírgulas») é um ficheiro de texto simples em que:
- cada linha é um registo (um cliente);
- a primeira linha tem os nomes dos campos (o cabeçalho);
- os valores de cada linha estão separados por um separador.
Abre-se no Excel, no LibreOffice, no Google Sheets… e até no Bloco de Notas. O nosso vai ser assim:
Três pormenores importantes (que já estão tratados no código que vais copiar):
- Ponto e vírgula em vez de vírgula. Em Portugal, a vírgula é usada nos números decimais (
12,50 €). Por isso, o Excel configurado em português espera;a separar as colunas. - Tudo entre aspas. Se as notas tiverem um
;(como «Ligar às 10h; prefere email»), as aspas dizem ao Excel que aquilo é tudo uma célula só. E se um valor tiver aspas lá dentro, escrevem-se duas seguidas ("") — é a regra do CSV. - Os acentos. O computador guarda cada letra como um número. A tabela mais usada hoje, a UTF-8, tem todas as letras do mundo (e os emojis). Mas o Excel nem sempre adivinha que o ficheiro está em UTF-8 e pode mostrar «João» em vez de «João». A solução é pôr no início do ficheiro um carácter invisível, o BOM, que funciona como um carimbo a dizer «este texto está em UTF-8».
💾 Cópias de segurança
Lembras-te da aula 8? Os dados do CRM ficam no localStorage deste browser, neste computador. Se alguém limpar os dados do browser, se mudares de computador ou se o disco avariar… perdes tudo.
Por isso vamos criar uma cópia de segurança (em inglês, backup): um ficheiro copia-crm.json com as 3 tabelas (clientes, interações e oportunidades), no formato JSON que já conheces.
Com esse ficheiro, consegues restaurar tudo, neste ou noutro computador.
🏢 Nas empresas, as cópias de segurança são obrigatórias: fazem-se todos os dias e guardam-se noutro sítio (outro disco, a «nuvem»), para o caso de incêndio, roubo ou vírus. E o RGPD (Regulamento Geral sobre a Proteção de Dados) obriga as empresas a proteger os dados pessoais dos clientes — não os perder, mas também não os deixar cair em mãos erradas. Uma cópia com dados de clientes guarda-se em lugar seguro, não numa pen esquecida no autocarro!
🤔 Pensa: uma página web pode escrever ficheiros no teu disco sempre que quiser? Porque é que isso seria perigoso?
Parte B — Os botões e o código (≈ 20 min)
1 O link do menu
No index.html, dentro do <nav class="menu">, por baixo do comentário AULA 16: COLAR AQUI O LINK DOS RELATÓRIOS:
2 A secção dos relatórios (HTML)
Três botões. Os dois primeiros já conheces. O terceiro tem um truque: o <input type="file"> (que abre a janela para escolher um ficheiro) é feio, por isso o CSS esconde-o e mostra só o <label> com o aspeto de um botão.
Clicar no <label> é o mesmo que clicar no <input> que está lá dentro. O accept=".json" faz a janela mostrar só ficheiros .json.
⚠️ Atenção ao sítio: este bloco vai para o comentário AULA 16: COLAR AQUI OS RELATÓRIOS, dentro do <main> (por baixo do painel) — não para o do menu.
🤔 Prevê: o que acontece se clicares agora em 📄 Exportar clientes (Excel)? Experimenta, com a Consola aberta.
✅ Deves ver: o cartão Relatórios e cópias de segurança com 3 botões. Ao clicar no primeiro aparece na Consola o erro exportarClientesCSV is not defined — é normal: a função ainda não existe.
3 As funções de exportar e restaurar (JavaScript)
No app.js, por baixo do comentário // ===== AULA 16: COLAR AQUI =====. Desta vez só há um comentário da aula 16 no app.js e não é preciso acrescentar nada a atualizarEcra(): os relatórios não se desenham no ecrã, só trabalham quando carregas num botão.
O que faz cada função:
descarregarFicheiro(nome, conteudo, tipo)— por segurança, uma página web não pode escrever no teu disco. O truque é: (1) criar um ficheiro na memória — um Blob; (2) criar um link<a>que aponta para ele, com o atributodownload(o nome do ficheiro); (3) «clicar» no link por código (link.click()). O browser faz o resto e guarda o ficheiro nas Transferências.celulaCSV(valor)— põe um valor entre aspas e duplica as aspas que já lá estejam.linhaCSV(valores)— junta várias células com;(join(';')) e acaba com'\r\n', a mudança de linha à maneira do Windows (o Excel gosta assim).exportarClientesCSV()— o relatório: uma linha de cabeçalho e uma linha por cliente; no fim, junta o BOM ao início e descarregaclientes.csv.exportarCopia()— a cópia de segurança: junta as 3 tabelas num objeto e transforma-o em texto comJSON.stringify(copia, null, 2). O2quer dizer «afasta cada nível 2 espaços», para o ficheiro ficar fácil de ler.importarCopia(evento)— o restauro: umFileReader(«leitor de ficheiros») lê o ficheiro que escolheste. Ler demora um bocadinho, por isso dizemos o que fazer quando acabar (leitor.onload = function () { … }). Lá dentro,try { … } catch { … }quer dizer «tenta; se der erro, apanha-o»: se o ficheiro não for um JSON válido, aparece uma mensagem simpática em vez de o programa «rebentar». Antes de substituir os dados, pede confirmação.
⚠️ Atenção ao BOM: em exportarClientesCSV vais ver '\uFEFF' + csv. O \uFEFF é a forma de escrever o BOM (o tal carimbo invisível) em JavaScript. Não o apagues: sem ele, os acentos aparecem estragados no Excel. Se escreveres a linha à mão (por exemplo no E2), copia-o tal e qual: barra, u, FEFF.
✅ Deves ver: nenhum erro na Consola. Agora os três botões já fazem alguma coisa — vamos testá-los com calma na Parte C.
Parte C — Testar a sério: Excel, cópia e restauro (≈ 20 min)
4 Abrir o relatório no Excel
- Clica em 📄 Exportar clientes (Excel). O browser descarrega o ficheiro
clientes.csv(normalmente vai para a pasta Transferências; para ver a lista das transferências do browser, carrega em Ctrl+J). - Abre-o no Excel: duplo clique no ficheiro, ou, no Excel, Ficheiro → Abrir → Procurar e escolhe a pasta Transferências (se não o vires, escolhe «Todos os ficheiros» no tipo de ficheiro).
- Confirma: cada campo na sua coluna, o cabeçalho na linha 1, os acentos certos (João Gonçalves, Ribeirão) e as notas «Ligar às 10h; prefere email» numa só célula.
✅ Deves ver: uma folha de cálculo arrumada, com 8 colunas (Nome, Empresa, Email, Telefone, NIF, Estado, Criado em, Notas) e uma linha por cliente. Os telefones, os NIF e as datas podem aparecer alinhados à direita ou com outro formato (ex.: 15/09/2026): é o Excel a reconhecer números e datas — está tudo bem.
😕 Não foi descarregado nada
- Olha para o canto superior direito do browser (ícone de transferências) ou carrega em Ctrl+J: o ficheiro pode estar lá e tu não reparaste.
- O browser pode ter bloqueado a transferência ou estar à espera da tua autorização: procura uma mensagem como «Este site tentou transferir vários ficheiros» (clica em Permitir) ou um aviso na lista de transferências (escolhe Manter).
- O Firefox pode perguntar o que fazer com o ficheiro: escolhe Guardar ficheiro.
- Alguns computadores da escola não deixam transferir ficheiros: avisa o professor.
- Abre a Consola: se aparecer
exportarClientesCSV is not defined, o passo 3 não está no sítio certo ou não foi gravado.
😕 O Excel abre tudo numa só coluna (com os ; e as aspas à vista)
O teu Windows ou o teu Excel estão configurados para usar a vírgula como separador (acontece com o Excel em inglês). Não precisas de mudar o código:
- Solução rápida: seleciona a coluna A → separador Dados → Texto para Colunas → Delimitado → Seguinte → marca Ponto e vírgula → Concluir.
- Solução «profissional»: num livro novo, Dados → De Texto/CSV (nalgumas versões: Dados → Obter Dados → De Ficheiro → De Texto/CSV), escolhe o
clientes.csv, confirma que o Delimitador é Ponto e vírgula e clica em Carregar.
😕 Os acentos aparecem estragados (João, Gonçalves) ou aparece  antes de «Nome»
- Quase sempre é o BOM que se perdeu: escreveste a linha do
descarregarFicheirosem o'\uFEFF' +, ou apagaste-o. Volta a copiar a funçãoexportarClientesCSVcom o botão 📋 Copiar, grava e exporta outra vez. - Se mesmo assim não resultar (Excel muito antigo), importa com Dados → De Texto/CSV e, em Origem do Ficheiro, escolhe 65001: Unicode (UTF-8).
😕 Outros problemas com o Excel (ou não tenho Excel)
- Aparece uma barra amarela «Vista Protegida»: é porque o ficheiro veio da Internet (do browser). Clica em Ativar Edição.
- O ficheiro chama-se
clientes (1).csv: o browser acrescenta um número quando já existe um ficheiro com o mesmo nome. É normal (o E2 resolve isto). - O Excel diz que o ficheiro está a ser usado: fecha o
clientes.csvno Excel antes de exportares outra vez com o mesmo nome. - LibreOffice Calc: ao abrir aparece a janela Importar texto: em Conjunto de caracteres escolhe Unicode (UTF-8), em Opções de separador marca só Ponto e vírgula e clica em OK.
- Google Sheets: Ficheiro → Importar → Carregar, escolhe o ficheiro e, em Tipo de separador, deixa Detetar automaticamente (ou escolhe Personalizado e escreve
;). - Mac: o duplo clique pode abrir no Numbers, que também serve; o Excel para Mac funciona como no Windows.
5 Fazer a cópia de segurança e espreitá-la
- Clica em 💾 Fazer cópia de segurança. O browser descarrega o ficheiro
copia-crm.json. - Abre-o no VS Code: Ficheiro → Abrir Ficheiro… e escolhe-o na pasta Transferências (ou arrasta o ficheiro para dentro da janela do VS Code).
- Não alteres nada neste ficheiro: basta faltar uma vírgula para deixar de ser um JSON válido.
✅ Deves ver: um texto arrumado, que começa por { e tem três listas: "clientes": [ … ], "interacoes": [ … ] e "oportunidades": [ … ], com todos os teus dados. É o CRM inteiro num só ficheiro!
💡 Se o ficheiro abrir no browser em vez do VS Code, não faz mal: dá para ver na mesma. Para o abrires no VS Code, botão direito no ficheiro → Abrir com → Visual Studio Code.
6 O grande teste: apagar tudo e restaurar
⚠️ Faz isto pela ordem certa! Só apagas os dados depois de teres confirmado, no passo 5, que o copia-crm.json tem os teus dados. Sem cópia, o que apagares perde-se para sempre.
- Abre o DevTools (F12) → Aplicação (Application) → Armazenamento local → o endereço do Live Server.
- Clica em
crm_clientese carrega na tecla Delete (ou botão direito → Eliminar). Faz o mesmo acrm_interacoese acrm_oportunidades. Apaga só estas três. - Carrega em F5: o CRM fica vazio — sem clientes, quadro vazio, painel a zeros. (Se fizeste o desafio da aula 8, aparecem os 3 clientes de exemplo: é normal.)
- Clica em 📂 Restaurar cópia, escolhe o
copia-crm.jsone responde OK à pergunta «Isto vai SUBSTITUIR todos os dados atuais. Continuar?».
✅ Deves ver: a mensagem «Cópia restaurada com sucesso!» e tudo de volta: clientes, interações (abre uma ficha!), oportunidades nas mesmas fases e o painel com os mesmos números. Carrega em F5: continua tudo lá, porque o restauro também gravou no browser.
😕 O restauro não funcionou
- Aparece «Este ficheiro não é uma cópia válida do Mini-CRM.» → escolheste outro ficheiro (por exemplo o
clientes.csv), ou o JSON foi alterado e ficou com um erro. Faz uma cópia nova. - Escolhes o ficheiro e não acontece nada → abre a Consola:
importarCopia is not definedquer dizer que o passo 3 não está no sítio certo. (Se clicaste em Cancelar na pergunta, é normal não mudar nada.) - Não encontras o ficheiro na janela → procura na pasta Transferências; lembra-te de que a janela só mostra ficheiros
.json. - Voltaram os clientes, mas faltam as oportunidades → a cópia foi feita antes de as criares. Abre o JSON no VS Code e confirma.
- Apagaste os dados sem ter feito a cópia → infelizmente não há volta a dar: cria uns clientes novos e aprende a lição que as empresas aprendem da pior maneira. 😉
🔎 Investiga
- Abre o
clientes.csvno Bloco de Notas (botão direito → Abrir com → Bloco de Notas) ou no VS Code. O que é cada linha? E a primeira? O que separa os valores? Vês as aspas? - Cria um cliente com aspas no nome, por exemplo Pastelaria "O Doce", e exporta outra vez. Como aparece o nome no Bloco de Notas? E no Excel? Que função tratou disto? E o que acontecia às notas «Ligar às 10h; prefere email» se não houvesse aspas à volta das células?
- Para que serve uma cópia de segurança numa empresa? Escreve 3 situações em que uma cópia salvava a empresa. Onde guardarias a cópia do CRM? E onde é que nunca a deixarias, tendo em conta o RGPD?
- No
copia-crm.json, procura uma interação. Tem o nome do cliente ou só oclienteId? Porque é que, depois de restaurar, cada interação continua a aparecer no cliente certo?
✍️ Exercícios (fazem parte do teu projeto)
Estes exercícios não têm o código pronto: usa as funções de hoje como modelo.
E1 · Exportar as oportunidades (com o nome do cliente)
Acrescenta um botão «📄 Exportar oportunidades (Excel)» na secção dos relatórios, que descarrega um ficheiro oportunidades.csv com as colunas Título; Cliente; Valor; Fase; Data prevista.
Na coluna Cliente tem de aparecer o nome do cliente, e não o número do clienteId.
💡 Dica: copia a ideia de exportarClientesCSV para uma função nova. Para o nome, faz como no cartaoOportunidade da aula 14: procurarCliente(op.clienteId) (e cuidado se devolver null). Isto é juntar duas tabelas pela chave estrangeira — o JOIN da aula 11! Para o Excel português perceber o valor como número, troca o ponto pela vírgula: depois de toFixed(2), usa .replace('.', ',').
E2 · A data no nome do ficheiro
Faz com que o ficheiro dos clientes passe a chamar-se, por exemplo, clientes-2026-10-03.csv, com a data de hoje. Assim, quem exporta todas as semanas não fica com clientes (1).csv, clientes (2).csv…
💡 Dica: já usaste no CRM uma expressão que dá a data de hoje no formato AAAA-MM-DD — procura criadoEm em guardarCliente(). Guarda-a numa variável e junta os textos com + no primeiro valor do descarregarFicheiro(…).
⭐ Desafio · Relatório imprimível
Acrescenta um botão «🖨️ Imprimir relatório» que abre a janela de impressão do browser. Na impressão não devem aparecer o menu, os formulários, os filtros, os botões nem a secção dos relatórios — só as tabelas, o quadro e o painel.
💡 Dica: o JavaScript tem uma função pronta que abre a janela de imprimir: window.print(). No CSS, as regras escritas dentro de @media print { … } só se aplicam quando se imprime; lá dentro, display: none esconde o que não interessa. Para testar sem gastar papel, usa Ctrl+P e vê a pré-visualização (ou escolhe «Guardar como PDF»).
📦 O que mostrar ao professor
⏱️ Se sobrar tempo
- Faz o desafio ⭐.
- Se tens o campo Cidade (aula 12), acrescenta-o ao CSV dos clientes (no cabeçalho e em cada linha).
- Põe também a data no nome da cópia de segurança (
copia-crm-2026-10-03.json). - Exporta as interações para CSV, com o nome do cliente em cada linha.
🏁 A partir daqui, o CRM é teu
Acabou o código guiado! O teu Mini-CRM já faz o que fazem muitas aplicações de gestão a sério: guarda clientes, regista o histórico, acompanha negócios por fases, mostra indicadores, exporta relatórios e faz cópias de segurança. Nas próximas aulas vais adaptá-lo ao teu setor (aula 17), testá-lo e escrever o manual (aula 18), publicá-lo na Internet (aula 19) e apresentá-lo (aula 20).
- Faz uma cópia da pasta
meu-crm(botão direito na pasta → Comprimir para ficheiro ZIP; no Windows 10, Enviar para → Pasta comprimida) e guarda-a na tua pen, no OneDrive ou no teu email. É a cópia de segurança do teu código! - Até à próxima aula, pensa: que empresa é a tua? Que campos, estados e indicadores fazem sentido no teu setor?
🤖 Pedir ajuda à IA (opcional)
Se ficaste com dúvidas sobre CSV, codificação de caracteres ou cópias de segurança, pede a uma IA gratuita que te explique. Copia este pedido e cola-o na IA:
📖 Palavras novas
- Relatório
- Informação tirada da aplicação para ser lida, partilhada ou impressa (ex.: lista de clientes em Excel).
- CSV
- Ficheiro de texto com uma linha por registo e os valores separados por um separador (no nosso caso,
;). - Separador
- O carácter que separa as colunas num CSV (vírgula ou ponto e vírgula).
- UTF-8
- A forma mais usada de guardar letras como números; inclui acentos, ç e emojis.
- BOM
- Carácter invisível no início de um ficheiro que avisa «este texto está em UTF-8».
- Blob
- Um «ficheiro na memória», criado pelo JavaScript, que se pode descarregar.
- Transferência (download)
- Guardar no computador um ficheiro que vem do browser ou da Internet.
- Cópia de segurança (backup)
- Cópia dos dados guardada noutro sítio, para os recuperar se se perderem.
- Restaurar
- Repor os dados a partir de uma cópia de segurança.
FileReader- Objeto do JavaScript que lê um ficheiro escolhido pelo utilizador.
try { … } catch { … }- «Tenta fazer isto; se der erro, apanha-o e faz aquilo» — evita que o programa pare.
- RGPD
- Regulamento Geral sobre a Proteção de Dados: regras europeias sobre como as empresas tratam e protegem os dados pessoais.