CNPJ Completo

CNPJ no Google Planilhas

Razão social, endereço, telefone, atividade e sócios ao lado de cada CNPJ

Instalar

  1. Na planilha, abra Extensões → Apps Script.
  2. Apague o que estiver lá, cole o código abaixo e salve.
  3. 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.