Criando novos formatos de exportação

Introdução

Alguns tipos de visualização de consultas automatizadas podem ter seu conteúdo exportado para arquivos. Para esses tipos de visualização, é possível determinar formatos de exportação além dos formatos padrão, através da criação de novos processos de exportação.

Objetivo

Escrever processos de exportação para as visualizações de consultas automatizadas, aumentando o leque de opções de exportação para o usuário final.

Estrutura do guia

A estrutura conceitual dos assuntos abordados nesse guia é:

    • Pré-requisitos

        • Conceitos básicos do Sistema UNUM

    • Construindo um processo de exportação

        • Estrutura do processo de exportação

            • Campos das grades de exportação

        • API do processo de exportação

            • Métodos

            • Propriedades

        • Implementando o processo

        • Exemplo de processo de exportação

    • Utilizando os novos formatos na exportação da visualização

        • Exemplo

Pré-requisitos

Conceitos básicos do Sistema UNUM

Os seguintes temas devem ser conhecidos para o devido entendimento deste manual:

    • DataSourceVisualization

Recomenda-se a leitura do Guia das visualizações das consultas automatizadas.

Construindo um processo de exportação

Para montar um processo de exportação, é necessário incluir nesse processo o script no caminho ‘ufs:/webframework/templates/js/dataexporter.js’, através da função __include. Esse script irá adicionar ao processo a lógica necessária para receber os dados de um relatório e escrevê-los em um arquivo.

Estrutura do processo de exportação

Ao incluir o script mencionado, o processo de exportação terá duas grades, chamadas exporter (com as variáveis a usar na exportação) e preview (que contém um campo de texto, com uma prévia do conteúdo a ser gradado no arquivo). Essas grades podem ser editadas no processo de exportação. Além delas, o desenvolvedor também pode criar suas próprias grades.

Campos das grades de exportação

A grade preview possui dois campos:

    • lines - determina a quantidade de linhas da pré-visualização da exportação a serem mostradas na grade, no campo content.

    • content - campo de texto onde será se monta a pré-visualização do conteúdo exportado.

A grade exporter não possui, por conta própria, campos fixos. Seus campos são gerados automaticamente, sendo um campo booleano para cada campo a ser exportado. Dessa forma, o usuário pode indicar quais campos deseja incluir na exportação. Por padrão, todos esses campos se inicializam marcados.

API do processo de exportação

O script mencionado anteriormente também provê os seguintes métodos e propriedades públicos para o processo:

Métodos

    • finishExport - finaliza a exportação e redireciona o usuário para a interação na qual ele poderá baixar o arquivo.

    • getRandomName - gera uma string aleatória, para compor o nome do arquivo;

    • getSelectedFieldIndexes - Obtém os índices dos campos que estão selecionados na grade exporter;

    • updatePreview - Atualiza a grade de pré-visualização do processo;

    • writeGrids - Escreve as grades padrão do processo.

Note que a função getFileName pode ser sobrescrita sem maiores problemas. Ela só precisa retornar uma string.

A seguinte função é virtual e deve ser obrigatoriamente sobrescrita:

    • formatFileContent - deve retornar uma representação textual do conteúdo a ser gravado. Seu conteúdo será exibido na grade de pré-visualização.

Propriedades

    • baseFieldOrder - número base de ordem do qual os campos específicos do processo de exportação devem suceder. Ao criar um campo específico do processo de exportação, sempre defina uma ordem superior a baseOrder, garantindo que os campos definidos sejam exibidos após os campos padrão de qualquer processo de exportação.

    • exportFile - objeto do tipo File, usado para escrever o arquivo com o conteúdo da exportação;

    • exportFilePath - o caminho, no disco, onde o arquivo será escrito;

    • hasPreview - indica se a exportação deve exibir a grade de pré-visualização do conteúdo gerado. Por padrão, seu valor é verdadeiro. Deve ser setado para false caso o conteúdo a exportar seja binário.

    • help - a ajuda do processo. É obrigatório setar esta propriedade.

Existe ainda uma propriedade do processo que não é dada pelo script que incluímos, mas sim pelo processo ou relatório daonde vem os dados a serem exportados. Essa propriedade se chama dataExporter e é um objeto da classe DataExporter ou de uma de suas filhas.

Implementando o processo

Após incluso o script já mencionado, devemos implementar no novo processo a interação main. Recomenda-se que as grades padrão sejam exibidas nessa interação.

A partir desse ponto o processo pode utilizar as propriedades e funções publicadas, bem como funcionalidades próprias, para que o usuário possa interagir com o fluxo e para que o arquivo com o conteúdo a exportar seja escrito.

Exemplo de processo de exportação

Segue abaixo um exemplo de código de processo que, dada uma fonte de dados, a exporta para o formato CSV:

/*jshint bitwise: true, boss: false, curly: true, debug: false, devel: false, eqeqeq: false, evil: true, forin: false, immed: true, laxbreak: false, newcap: true, noarg: true, noempty: true, nomen: false, onevar: false, plusplus: false, regexp: true, undef: true, sub: false, strict: false, white: true, loopfunc: true */ /*global __include, __includeOnce, goog, inherited, Progress, uwl */ /** * Exporta dados da grid em formato CSV * http://en.wikipedia.org/wiki/Comma-separated_values */ __includeOnce('ufs:/goog/array/array.js'); __includeOnce('ufs:/uwl/dataset/dataset.js'); __includeOnce('ufs:/uwl/string/string.js'); __include('ufs:/webframework/templates/js/dataexporter.js'); this.help = 'Este processo converte uma massa de dados para o formato ' + 'CSV (comma-separated values).'; var fld = this.exporter.field('separator', 'string', 2); fld.label = 'Separador'; fld.help = 'Indique o separador a ser utilizado para separar os valores'; fld.defaultValue = ';'; fld.required = true; fld.order = this.baseFieldOrder + 1; fld.group = "Outras opções de exportação"; fld.onAfterChange.set(function (sender) { sender.parent.process.updatePreview(); }); var fld = this.exporter.field('showFieldNamesAtFirtstLine', 'boolean'); fld.label = 'Exibe Títulos'; fld.help = 'Marque esta opção caso deseje que a primeira linha do ' + 'arquivo apresente os nomes das colunas da grid.'; fld.order = this.baseFieldOrder + 2; fld.group = "Outras opções de exportação"; fld.onAfterChange.set(function (sender) { sender.parent.process.updatePreview(); }); this.formatToCSV = function (value) { var result = value + ''; if (result) { result = result.replace("&nbsp;", " "); result = result.replace("<b>", ""); result = result.replace("</b>", ""); result = result.replace('"', '""'); result = '"' + result + '"'; } return result; }; this.interaction('main', function () { inherited(); this.visibleActions = 'Export'; this.title = 'Exportar dados para CSV'; this.writeGrids(); }); /** * @override */ this.formatFileContent = function (fieldIndexes, opt_linesQty) { if (opt_linesQty === 0) { return ""; } var result = ""; var ds = this.dataExporter.dataSet; var fieldsToUse = goog.array.map(fieldIndexes, function (index) { return this.dataExporter.getField(index); }, this); if (this.showFieldNamesAtFirtstLine) { result += goog.array.reduce(fieldsToUse, function (line, fld) { line.push(fld.label || fld.name); return line; }, []).join(this.separator) + "\r\n"; } var status = opt_linesQty ? "Gerando Pré-Visualização" : "Gerando arquivo"; var totalWork = opt_linesQty || ds.recordCount; var progress = new Progress(); progress.beginTask(status, totalWork); for (ds.first(); !ds.eof; ds.next()) { result += goog.array.reduce(fieldsToUse, function (line, fld) { var value = this.formatToCSV( this.dataExporter.formatFieldValue(fld), this.exportLookupKeys); line.push(uwl.string.removeLineBreaks(value)); return line; }, [], this).join(this.separator) + "\r\n"; progress.worked(); if (opt_linesQty && ds.recNo == opt_linesQty) { break; } } progress.done(); return result; }; this.activity('Export', function () { this.exportFileName = this.dataExporter.title + '.csv'; try { this.exportFile.write(this.formatFileContent( this.getSelectedFieldIndexes())); } finally { this.finishExport(); } });

Utilizando os novos formatos na exportação da visualização

As visualizações de consultas automatizadas possuem a propriedade extraExportFormats. Essa propriedade é um array de objetos literais, que devem declarar três propriedades:

    • name: o nome do formato de exportação, que será exibido em tela quando o usuário for selecionar um formato;

    • processKey: a chave do processo que implementa a exportação para aquele formato.

    • useRawData: indica se o formato de exportação utiliza os dados “crus” da visualização, isto é, aqueles utilizados para a montagem da exibição. Por padrão é falsa, caso no qual serão utilizados os dados da visualização já transformados e formatados pela visualização.

Caso a propriedade seja declarada na definição de uma visualização, as opções declaradas serão exibidas junto às opções padrão quando o usuário solicitar uma exportação. Quando o usuário selecionar uma dessas opções, será redirecionado ao processo correspondente.

Exemplo

Segue abaixo um exemplo de um script .idsv com a propriedade extraExportFormats declarada:

{ dataSourceQueryKey: -1892603784, //./Users.idsq */ type: "report", filters: [ {name: "U_iName", label: "Nome de usuário"} ], columns: [ {name: "U_iName", label: "Nome"} ], extraExportFormats: [ /* Export to CSV.ip */ {name: 'CSV', processKey: -1898145324}, /* Export to EXCEL CSV.ip */ {name: 'CSV para Excel', processKey: -1898144677}, {name: 'Formato customizado', processKey: 123456, useRawData: true} ] }