CNPJ no Google Planilhas
Razão social, endereço, telefone, atividade e sócios ao lado de cada CNPJ
Instalar
- Na planilha, abra Extensões → Apps Script.
- Apague o que estiver lá, cole o código abaixo e salve.
- Recarregue a planilha: o menu CNPJ aparece depois de Ajuda.
Código
// Dados de empresas ativas pelo CNPJ, de https://cnpjcompleto.com.br
const API = "https://cnpjcompleto.com.br/api/v1/cnpj/";
const COLUNAS = [
["Razão social", (e) => e.razao_social],
["Nome fantasia", (e) => e.nome_fantasia],
["Abertura", (e) => e.data_abertura],
["Porte", (e) => e.porte],
["Simples", (e) => (e.simples ? "Sim" : "Não")],
["CNAE", (e) => e.cnae_principal && e.cnae_principal.codigo],
["Atividade", (e) => e.cnae_principal && e.cnae_principal.descricao],
["Endereço", (e) => [e.endereco.logradouro, e.endereco.numero, e.endereco.complemento].filter(Boolean).join(", ")],
["Bairro", (e) => e.endereco.bairro],
["CEP", (e) => (e.endereco.cep || "").replace(/^(\d{5})(\d{3})$/, "$1-$2")],
["Município", (e) => e.endereco.municipio],
["UF", (e) => e.endereco.uf],
["Telefone", (e) => e.telefones.map(telefone).join(", ")],
["E-mail", (e) => e.email],
["Sócios", (e) => e.socios.map((s) => s.nome).join(", ")],
];
/** Até 5 minutos por execução: o Google interrompe scripts aos 6. */
const TEMPO = 5 * 60 * 1000;
function onOpen() {
SpreadsheetApp.getUi().createMenu("CNPJ")
.addItem("Preencher dados", "preencherCnpjs")
.addItem("Chave da API", "definirChave")
.addToUi();
}
function definirChave() {
const ui = SpreadsheetApp.getUi();
const resposta = ui.prompt("Chave da API", "Em branco, vale o limite grátis.", ui.ButtonSet.OK_CANCEL);
if (resposta.getSelectedButton() !== ui.Button.OK) return;
const chave = resposta.getResponseText().trim();
const propriedades = PropertiesService.getDocumentProperties();
if (chave) propriedades.setProperty("CHAVE", chave);
else propriedades.deleteProperty("CHAVE");
}
/** Preenche, à direita de cada CNPJ selecionado, os dados da empresa. Linhas já preenchidas ficam como estão. */
function preencherCnpjs() {
const inicio = Date.now();
const planilha = SpreadsheetApp.getActiveSheet();
const selecao = planilha.getActiveRange();
const primeira = selecao.getRow();
const coluna = selecao.getColumn();
const valores = planilha.getRange(primeira, coluna, selecao.getNumRows(), 1 + COLUNAS.length).getValues();
const vazia = (linha) => linha.slice(1).every((valor) => valor === "");
const cnpj = (linha) => limpar(linha[0]).length >= 12;
if (valores.some((linha) => cnpj(linha) && linha[1] === "" && !vazia(linha))) {
SpreadsheetApp.getUi().alert("Deixe vazias as " + COLUNAS.length + " colunas à direita dos CNPJs.");
return;
}
const pendentes = [];
valores.forEach((linha, i) => {
if (cnpj(linha)) {
if (vazia(linha)) pendentes.push(i);
} else if (i === 0 && linha[0] !== "" && vazia(linha)) {
planilha.getRange(primeira, coluna + 1, 1, COLUNAS.length).setValues([COLUNAS.map(([nome]) => nome)]);
}
});
let feitas = 0;
for (const i of pendentes) {
if (Date.now() - inicio > TEMPO) break;
const resposta = consultar(valores[i][0], inicio + TEMPO - Date.now());
if (resposta.erro === "chave") {
SpreadsheetApp.getUi().alert("Chave inválida ou assinatura encerrada.");
return;
}
if (resposta.erro === "limite") break;
const linha = resposta.empresa
? COLUNAS.map(([, valor]) => valor(resposta.empresa) || "")
: [resposta.erro === "inexistente" ? "Sem cadastro ativo" : resposta.erro === "invalido" ? "CNPJ inválido" : "Tente de novo"].concat(COLUNAS.slice(1).map(() => ""));
const destino = planilha.getRange(primeira + i, coluna + 1, 1, COLUNAS.length);
destino.setNumberFormat("@");
destino.setValues([linha]);
feitas++;
}
const faltam = pendentes.length - feitas;
SpreadsheetApp.getActive().toast(faltam ? "Faltam " + faltam + ". Rode de novo para continuar." : "Pronto.", "CNPJ", 10);
}
/**
* Um dado de uma empresa ativa, pelo CNPJ.
* @param {string} cnpj O CNPJ, com ou sem pontuação
* @param {string} campo Razão social, Telefone, Município ou outra coluna do menu; em branco, a razão social
* @return O dado da empresa
* @customfunction
*/
function CNPJ(cnpj, campo) {
const nome = normalizar(campo || "Razão social");
const coluna = COLUNAS.find(([titulo]) => normalizar(titulo) === nome);
if (!coluna) throw new Error("Campo desconhecido: " + campo);
const resposta = consultar(cnpj, 20000);
if (resposta.empresa) return coluna[1](resposta.empresa) || "";
if (resposta.erro === "inexistente") return "Sem cadastro ativo";
if (resposta.erro === "invalido") return "CNPJ inválido";
throw new Error(resposta.erro === "chave" ? "Chave inválida ou assinatura encerrada." : resposta.erro === "limite" ? "Limite por minuto atingido. Recalcule em instantes." : "Tente de novo em alguns minutos.");
}
/** A empresa, ou o motivo de não vir. No limite por minuto, espera e tenta de novo enquanto houver `prazo` (ms). */
function consultar(cnpj, prazo) {
const codigo = limpar(cnpj);
const cache = obter(() => CacheService.getDocumentCache());
const guardada = cache && cache.get(codigo);
if (guardada) return { empresa: JSON.parse(guardada) };
const chave = obter(() => PropertiesService.getDocumentProperties().getProperty("CHAVE"));
const fim = Date.now() + prazo;
for (;;) {
const resposta = UrlFetchApp.fetch(API + encodeURIComponent(codigo), { muteHttpExceptions: true, headers: chave ? { Authorization: "Bearer " + chave } : {} });
const status = resposta.getResponseCode();
if (status === 200) {
const texto = resposta.getContentText();
if (cache && texto.length < 90000) cache.put(codigo, texto, 6 * 60 * 60);
return { empresa: JSON.parse(texto) };
}
if (status === 404) return { erro: "inexistente" };
if (status === 400) return { erro: "invalido" };
if (status === 401) return { erro: "chave" };
if (status !== 429) return { erro: "servidor" };
const espera = (Number(resposta.getHeaders()["Retry-After"] || resposta.getHeaders()["retry-after"]) || 60) * 1000;
if (Date.now() + espera > fim) return { erro: "limite" };
Utilities.sleep(espera);
}
}
/** O CNPJ só com letras e números; o número que a planilha guardou sem os zeros à esquerda volta a ter 14 dígitos. */
function limpar(cnpj) {
const codigo = String(cnpj).toUpperCase().replace(/[^0-9A-Z]/g, "");
return /^\d{12,13}$/.test(codigo) ? codigo.padStart(14, "0") : codigo;
}
function normalizar(texto) {
return String(texto).normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[_\s-]+/g, " ").trim();
}
function telefone(numero) {
return numero.replace(/^(\d{2})(\d{4,5})(\d{4})$/, "($1) $2-$3");
}
function obter(ler) {
try {
return ler();
} catch (erro) {
return null;
}
}
Usar
Selecione os CNPJs e escolha CNPJ → Preencher dados. Os dados entram nas 15 colunas à direita, que precisam estar vazias.
Para um dado só, use a fórmula =CNPJ(A2; "Telefone"), com o nome de qualquer coluna.
Na primeira vez, o Google pede permissão para o script acessar a internet.
Mais rápido
Grátis, 5 CNPJs por minuto.