sql >> Base de Datos >  >> NoSQL >> Redis

Cómo hacer que el cliente descargue un archivo muy grande que se genera sobre la marcha

Exportación de Excel:

Utilice flujos. Lo siguiente es una idea aproximada de lo que podría hacerse:

  1. Utilice el módulo exceljs. Porque tiene una API de transmisión dirigida a este problema exacto.

    var Excel = require('exceljs')
    
  2. Ya que estamos tratando de iniciar una descarga. Escriba encabezados apropiados para la respuesta.

    res.status(200);
    res.setHeader('Content-disposition', 'attachment; filename=db_dump.xls');
    res.setHeader('Content-type', 'application/vnd.ms-excel');
    
  3. Cree un libro de trabajo respaldado por Streaming Excel Writer. El flujo dado al escritor es la respuesta del servidor.

    var options = {
        stream: res, // write to server response
        useStyles: false,
        useSharedStrings: false
    };
    
    var workbook = new Excel.stream.xlsx.WorkbookWriter(options);
    
  4. Ahora, el flujo de transmisión de salida está configurado. para la transmisión de entrada, prefiera un controlador de base de datos que brinde resultados de consulta/cursor como una transmisión.

  5. Defina una función asíncrona que vuelque 1 tabla en 1 hoja de trabajo.

    var tableToSheet = function (name, done) {
        var str = dbDriver.query('SELECT * FROM ' + name).stream();
        var sheet = workbook.addWorksheet(name);
    
        str.on('data', function (d) {
            sheet.addRow(d).commit(); // format object if required
        });
    
        str.on('end', function () {
            sheet.commit();
            done();
        });
    
        str.on('error', function (err) {
            done(err);
        });
    }
    
  6. Ahora, exportemos algunas tablas de db, usando mapSeries del módulo asíncrono:

    async.mapSeries(['cars','planes','trucks'],tableToSheet,function(err){
       if(err){
         // log error
       }
       res.end();
    })
    

Exportación CSV:

Para la exportación a CSV de un solo módulo de tabla/colección, se puede utilizar fast-csv:

// response headers as usual
res.status(200);
res.setHeader('Content-disposition', 'attachment; filename=mytable_dump.csv');
res.setHeader('Content-type', 'text/csv');

// create csv stream
var csv = require('fast-csv');
var csvStr = csv.createWriteStream({headers: true});

// open database stream
var dbStr = dbDriver.query('SELECT * from mytable').stream();

// connect the streams
dbStr.pipe(csvStr).pipe(res);

Ahora está transmitiendo datos de la base de datos a la respuesta HTTP, convirtiéndolos al formato xls/csv sobre la marcha. No es necesario almacenar en búfer o almacenar todos los datos en la memoria o en un archivo.