Outro dia desses um amigo precisava fazer a exportação de dados de venda de um supermercado para posterior importação em outro sistema.
Ele já havia tentado o processo utilizando algumas ferramentas, mas sem sucesso. A exportação compreendia aproximadamentes 4 milhões de registros de venda sendo que os arquivos deveriam ser gerados dia a dia, separados em uma hierarquia de pastas estruturadas num formato tipo /ano/mes.
A solução foi escrever um simples Script em Groovy, que concluiu todo o processo em menos de cinco minutos. Para execução do script foi necessário apenas a instalação do Groovy, baixar o Driver do banco de dados e executar o comando:
$ groovy -cp "jaybird-full-2.1.6.jar" MegaExport.groovy
Isto mostra a simplicidade e o poder da linguagem Groovy e como ela pode ser empregada para soluções de problemas corriqueiros. Abaixo o script em questão:
import java.sql.DriverManager; import groovy.sql.Sql //Parâmetros de configuração def SERVIDOR = "127.0.0.1" def BANCO_DE_DADOS = "/path/to/database.fdb" def USUARIO = "SYSDBA" def SENHA = "masterkey" def DIRETORIO_DESTINO = "/path/to/files" def DRIVER = "org.firebirdsql.jdbc.FBDriver" def STRING_CONEXAO = "jdbc:firebirdsql://${SERVIDOR}/${BANCO_DE_DADOS}" //Comando SQL de seleção dos períodos com vendas def COMANDO_SQL_PERIODO = """\ SELECT EXTRACT(year from sai_d_ve) AS ano , EXTRACT(month from sai_d_ve) AS mes FROM sai001 WHERE (not sai_d_ve is null) GROUP BY 1, 2 ORDER by 1, 2 """ //Comando SQL de seleção das vendas def COMANDO_SQL_VENDAS = """\ SELECT EXTRACT(day from sao.sai_d_ve) AS dia , sao.cupom AS cupom , sao.pro_barr AS ean , CAST(coalesce(sao.sai_quan,0) * 1000 AS bigint) AS quantidade , CAST(coalesce(sao.sai_quan,0) * coalesce(sao.sai_valo,0) * 100 AS bigint) AS subtotal , CAST(coalesce(sao.valor_desconto,0) * 100 AS bigint) AS desconto , CAST(coalesce(sao.acrescimo,0) * 100 AS bigint) AS acrescimo , CASE sao.item_excluido WHEN 'S' then 'C' ELSE 'V' END AS situacao , sao.descricao as descricao , CASE sao.id WHEN 'FF' then 'F ' WHEN 'II' then 'I ' WHEN 'NN' then 'N ' WHEN '01' then '0700' WHEN '02' then '1700' WHEN '03' then '1700' WHEN '04' then '2500' WHEN '05' then '0400' WHEN '06' then '0300' WHEN '07' then '2700' WHEN '08' then '1200' ELSE ' ' END AS tributacao FROM sai001 sao WHERE (EXTRACT(year from sao.sai_d_ve) = ?) AND (EXTRACT(month from sao.sai_d_ve) = ?) ORDER BY sao.sai_d_ve """ println "Carregando o driver de conexão (${DRIVER})"; Class.forName(DRIVER); println "Selecionando as datas para exportação" ; def sqlPeriodo = Sql.newInstance(STRING_CONEXAO, USUARIO, SENHA, DRIVER); try { sqlPeriodo.eachRow(COMANDO_SQL_PERIODO) { periodo -> println "Exportando período ${periodo.ANO}/${periodo.MES}"; int dia = 0; int mes = periodo.MES; int ano = periodo.ANO; println " > Criando diretório ${DIRETORIO_DESTINO}/${ano.toString().padLeft(4, '0')}/${mes.toString().padLeft(2, '0')}"; def diretorio = new File("${DIRETORIO_DESTINO}/${ano.toString().padLeft(4, '0')}/${mes.toString().padLeft(2, '0')}"); diretorio.mkdirs(); println " > Exportando os dados das vendas"; def writer = null; def arquivo = null; def sqlVendas = Sql.newInstance(STRING_CONEXAO, USUARIO, SENHA, DRIVER); try { sqlVendas.eachRow(COMANDO_SQL_VENDAS, [ano, mes]) { venda -> if (dia == 0 || dia != venda.DIA) { dia = venda.DIA; def nomeArquivo = "IT_${dia.toString().padLeft(2,'0') + mes.toString().padLeft(2, '0')}.txt"; println " > Criando arquivo ${diretorio.absolutePath}/${nomeArquivo}"; arquivo = new File("${diretorio.absolutePath}/${nomeArquivo}"); arquivo.delete(); arquivo.createNewFile(); if (writer) { writer.flush(); writer.close(); } //a escrita deve ser feita em buffer por questões de desempenho writer = arquivo.newWriter(); } writer.write ano.toString().padLeft(4, "0"); writer.write mes.toString().padLeft(2, "0"); writer.write venda.DIA.toString().padLeft(2, "0"); writer.write "000"; writer.write venda.CUPOM.toString().padLeft(6, "0"); writer.write "00000"; writer.write venda.EAN.toString().padLeft(14, "0"); writer.write "0000000"; writer.write venda.QUANTIDADE.toString().padLeft(9, "0"); writer.write venda.SUBTOTAL.toString().padLeft(11, "0"); writer.write venda.DESCONTO.toString().padLeft(7, "0"); writer.write venda.ACRESCIMO.toString().padLeft(7, "0"); writer.write venda.SITUACAO.toString().padLeft(1, " "); writer.write venda.DESCRICAO.toString().padRight(30, " "); writer.write venda.TRIBUTACAO.toString().padRight(4, " "); writer.newLine(); } } finally { sqlVendas.close(); if (writer) { writer.flush(); writer.close(); } } } } finally { sqlPeriodo.close(); } println "Exportação finalizada.";


