如何让客户端下载动态生成的非常大的文件

2024-04-17

我有一个导出功能,可以读取整个数据库并创建一个包含所有记录的 .xls 文件。然后文件被发送到客户端。

当然,导出完整数据库的时间需要大量时间,并且请求很快就会以超时错误结束。

处理这种情况的最佳解决方案是什么?

例如,我听说过使用 Redis 创建队列,但这需要两个请求:一个用于启动将生成文件的作业,第二个用于下载生成的文件。

这可以通过客户的单个请求实现吗?


Excel 导出:

Use Streams https://nodejs.org/dist/latest-v7.x/docs/api/stream.html#stream_stream。以下是可能采取的措施的粗略想法:

  1. Use Exceljs模块 https://www.npmjs.com/package/exceljs。因为它有一个流媒体API https://www.npmjs.com/package/exceljs#streaming-io针对这个问题。

    var Excel = require('exceljs')
    
  2. 因为我们正在尝试启动下载。写入适当的标头以进行响应。

    res.status(200);
    res.setHeader('Content-disposition', 'attachment; filename=db_dump.xls');
    res.setHeader('Content-type', 'application/vnd.ms-excel');
    
  3. 创建一个由以下内容支持的工作簿流式 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);
    
  4. 现在,输出流已全部设置完毕。对于输入流,更喜欢将查询结果/光标作为流提供的数据库驱动程序。

  5. 定义一个异步函数,将 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);
        });
    }
    
  6. 现在,让我们导出一些数据库表,使用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(使用前将#替换为@)

如何让客户端下载动态生成的非常大的文件 的相关文章

随机推荐

  • Html.ActionLink 无法动态调度

    我的 MVC3 有问题 我正在尝试使用 Html ActionLink 为我的博客项目中的标题生成链接 在中使用常量字符串ActionLink效果很好 但如果我使用Posts Title 当前帖子模型的标题被循环 我得到这个异常 CS197
  • 如何减少flutter web应用程序的加载时间

    截至目前 我们可以将 flutter web 应用程序作为单个文件启动 该文件将立即加载 因此需要花费大量时间和带宽来加载 这并不理想 有没有办法一次只加载一个页面 而不是整个网络应用程序 我的意思是 一次加载一个小部件 任何建议将不胜感激
  • 卡夫卡高级消费者 error_code=15

    当尝试使用高级消费者 使用全新的消费者组 从 Kafka 进行消费时 消费者永远不会开始运行 当我将日志记录级别切换为调试时 我可以看到以下两行一遍又一遍地重复 DEBUG AbstractCoordinator 09 43 51 192
  • 了解跟踪*

    再会 当试图理解数学使用标准的评估顺序Trace and TraceScan最近开发的命令及其漂亮的视觉表示thread https stackoverflow com questions 5459735 the clearest way
  • foreach(... in ...) 或 .ForEach();这就是问题[重复]

    这个问题在这里已经有答案了 可能的重复 C foreach 与函数式each https stackoverflow com questions 2024305 c sharp foreach vs functional each 这是一个
  • C# 中是否有一个好的浮点数基数排序实现

    我有一个带有浮点类型字段的数据结构 这些结构的集合需要按浮点值排序 是否有一个基数排序实现 如果没有 是否有一种快速的方法来访问指数 符号和尾数 因为如果你首先对尾数 指数和最后一次的指数对浮点数进行排序 您对浮点数进行排序的时间复杂度为
  • 是否有适用于触摸移动设备的 HTML5/ jQuery 球形全景查看器

    我需要将球形全景查看器放入 Web 应用程序中 最好是 HTML5 和 jQuery 用户必须能够使用手指在全景图中移动 有谁知道有类似的东西可以使用 只需支付少量费用或更好地免费 这是一个老问题 但对于现在找到它的人 像我一样 我认为 P
  • FirebaseImageLoader 不下载图像

    我正在尝试从 ViewHolder 内部的存储中下载图像 但它不起作用 FirebaseStorage storage FirebaseStorage getInstance StorageReference storageReferenc
  • 如何使用多色热图解决 MemoryError

    我试图通过从文件中读取数据来绘制具有多种颜色的热图 我可以很好地生成 2D 和法线热图 但无法绘制如附图所示的图像 当使用随机数时 我可以绘制此图 但在从文件中读取数据时 它显示错误 上面的热图是用随机数据生成的 Input col 1 a
  • 如何更改存储在字符串中的日期格式?目标c [重复]

    这个问题在这里已经有答案了 可能的重复 如何转换 NSString 中的日期时间格式 https stackoverflow com questions 2076417 how to convert datetime format in n
  • @use 即将推出,但此版本的 Dart Sass 不支持它

    我在跑步ng serve包含 Sass 的 Angular cli 项目 我一直在使用 import and include没有问题 当我添加时 use 终端抛出 use 即将推出 但此版本的 Dart 不支持它 萨斯 我的 package
  • 带列表框的 WPF ScrollViewer

    需要你的帮助 我有一个列表框 带有虚拟化 显示一个 ScrollViewer 我的列表框项目是可展开的 展开时它们的高度可能会超出可见的滚动区域 我遇到的问题是 当列表框项目超出可见滚动区域时 滚动会跳转到下一个列表框项目 而不是简单地滚动
  • 在 UITableView 的 header 中添加一个 UIButton

    我需要在动态填充的 UIViewTable 的正上方放置一个按钮 不填充第一个单元格 第 0 行 而是利用标题区域感觉是正确的 因此我使用 UITableViewDelegate 方法以编程方式创建一个包含 UIButton 的 UIVie
  • 如何在 Objective-C 中创建 NSNotification 对象?

    我想创建一个 NSNotification 对象 如下所示 NSNotification obj NSNotification alloc init 但是当我像这样创建时 我收到一个异常 NSConcreteNotification ini
  • 高性能QImage输出显示

    我正在尝试将视频输出 帧序列 到任何 qt 可见小部件 一开始我认为 QLabel 足以满足这一点 但我错了 对于处理大图像 例如 1080p 的处理器来说 转换为像素图过于过载 还有其他解决方案吗 不是QLabel 一帧的代码示例 QIm
  • java.lang.UnsupportedOperationException:无法将索引 5 处的值转换为颜色:type=0x5

    我的应用程序更新后崩溃了Android Studio 3 RC1 Gradle4 安卓Gradle插件 3 RC2 This is the error I am having java lang RuntimeException Unabl
  • g++:在涉及多个翻译单元的情况下 RVO 如何工作

    首先请看下面的代码 它由2个翻译单元组成 foo h class Foo public Foo Foo const Foo rhs void print const private std string str Foo getFoo foo
  • Spyder 绘制 Tkinter 后端无响应的图

    在spyder 4 以及使用3降级后 下绘图不起作用 我只是在做 data 1 2 3 plt plot data The output is a non responding frame After forcing to close it
  • 如何等到File.Exists?

    我有一个应用程序 正在侦听所选文件夹中的 log 文件 我用了FileSystemWatcher 但有一个问题 负责制作该文件的另一个应用程序采取以下步骤 制作一个 gz 文件 解压到txt文件 一些随机文件名 将 txt 名称更改为带有
  • 如何让客户端下载动态生成的非常大的文件

    我有一个导出功能 可以读取整个数据库并创建一个包含所有记录的 xls 文件 然后文件被发送到客户端 当然 导出完整数据库的时间需要大量时间 并且请求很快就会以超时错误结束 处理这种情况的最佳解决方案是什么 例如 我听说过使用 Redis 创