Exportação de dados
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.
Construindo um processo de exportação
Para montar um processo de exportação, é necessário incluir nesse processo as interações e métodos padrões que são utilizados no fluxo de exportação de dados do Web Framework. Para isso, pode ser carregado um módulo que define essa estrutura padrão, conforme exemplo abaixo:
this.loadModule('@nginstack/web-framework/mixins/process/dataExporter.js');
Estrutura do processo de exportação
Ao carregar o módulo mencionado acima, serão declaradas no processo de exportação duas grades:
- “exporter”: com as variáveis a usar na exportação;
- “preview”: 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 módulo 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.
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 de onde 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 a carga do módulo “dataExporter.js”, deve ser definida a atividade “run” do processo de exportação, que será responsável por gravar os dados exportados no formato desejado. Podem ser utilizadas 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.
O módulo “dataExporter.js” define uma interação inicial padrão “main” apresentando a grade de opções de exportação e um pré-visualizador. Essa interação pode ser redefinida pelo processo de exportação, recomendado-se apenas que as grades padrão sejam exibidas utilizando o método “writeGrids”.
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:
/**
* Exporta dados da grid em formato CSV
* http://en.wikipedia.org/wiki/Comma-separated_values
*/
const removeLineBreaks = require('@nginstack/engine/lib/string/removeLineBreaks.js');
this.loadModule('@nginstack/web-framework/mixins/process/dataExporter.js');
this.help = 'Este processo converte uma massa de dados para o formato ' +
'CSV (comma-separated values).';
let 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();
});
fld = this.exporter.field('showFieldNamesAtFirstLine', '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) {
let result = value + '';
if (result) {
result = result.replace(" ", " ");
result = result.replace("<b>", "");
result = result.replace("</b>", "");
result = result.replace('"', '""');
result = '"' + result + '"';
}
return result;
};
this.formatFileContent = function (fieldIndexes, opt_linesQty) {
if (opt_linesQty === 0) {
return "";
}
let result = "";
const ds = this.dataExporter.dataSet;
const fieldsToUse = fieldIndexes.map(function (index) {
return this.dataExporter.getField(index);
}, this);
if (this.showFieldNamesAtFirstLine) {
result += fieldsToUse.reduce(function (line, fld) {
line.push(fld.label || fld.name);
return line;
}, []).join(this.separator) + "\r\n";
}
const status = opt_linesQty ? "Gerando Pré-Visualização" : "Gerando arquivo";
const totalWork = opt_linesQty || ds.recordCount;
const progress = new Progress();
progress.beginTask(status, totalWork);
for (ds.first(); !ds.eof; ds.next()) {
result += fieldsToUse.reduce(function (line, fld) {
const value = this.formatToCSV(
this.dataExporter.formatFieldValue(fld),
this.exportLookupKeys
);
line.push(removeLineBreaks(value));
return line;
}.bind(this), []).join(this.separator) + "\r\n";
progress.worked();
if (opt_linesQty && ds.recNo == opt_linesQty) {
break;
}
}
progress.done();
return result;
};
this.activity('run', 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}
]
}