我有一个导出功能,可以读取整个数据库并创建一个包含所有记录的 .xls 文件。然后文件被发送到客户端。
当然,导出完整数据库的时间需要大量时间,并且请求很快就会以超时错误结束。
处理这种情况的最佳解决方案是什么?
例如,我听说过使用 Redis 创建队列,但这需要两个请求:一个用于启动将生成文件的作业,第二个用于下载生成的文件。
这可以通过客户的单个请求实现吗?
Excel 导出:
Use Streams https://nodejs.org/dist/latest-v7.x/docs/api/stream.html#stream_stream。以下是可能采取的措施的粗略想法:
-
Use Exceljs模块 https://www.npmjs.com/package/exceljs。因为它有一个流媒体API https://www.npmjs.com/package/exceljs#streaming-io针对这个问题。
var Excel = require('exceljs')
-
因为我们正在尝试启动下载。写入适当的标头以进行响应。
res.status(200);
res.setHeader('Content-disposition', 'attachment; filename=db_dump.xls');
res.setHeader('Content-type', 'application/vnd.ms-excel');
-
创建一个由以下内容支持的工作簿流式 Excel 编写器 https://www.npmjs.com/package/exceljs#streaming-xlsx-writer。提供给 writer 的流是服务器响应。
var options = {
stream: res, // write to server response
useStyles: false,
useSharedStrings: false
};
var workbook = new Excel.stream.xlsx.WorkbookWriter(options);
现在,输出流已全部设置完毕。对于输入流,更喜欢将查询结果/光标作为流提供的数据库驱动程序。
-
定义一个异步函数,将 1 个表转储到 1 个工作表。
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);
});
}
-
现在,让我们导出一些数据库表,使用async https://www.npmjs.com/package/async模块的地图系列 http://caolan.github.io/async/docs.html#mapSeries:
async.mapSeries(['cars','planes','trucks'],tableToSheet,function(err){
if(err){
// log error
}
res.end();
})
导出 CSV:
用于单个表/集合模块的 CSV 导出fast-csv https://www.npmjs.com/package/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);
您现在正在将数据从 DB 流式传输到 HTTP 响应,并将其即时转换为 xls/csv 格式。无需将整个数据缓冲或存储在内存或文件中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)