如何在Node.js Express应用程序中为用户提供下载窗口选项 [英] How to give download window option to user in a node.js express application

查看:97
本文介绍了如何在Node.js Express应用程序中为用户提供下载窗口选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个node.js + express应用程序.在服务器端创建了一个excel文件,我需要在下载窗口中将其提供给用户.因此,用户可以选择他想要的目录,然后下载它.用户执行完此操作后,我想删除该文件(该文件在应用程序的本地下载文件夹中创建).

I am building a node.js + express application. An excel file gets created on my server side and I need to serve it to the user in the download window. So the user can choose his desired directory and then download it. After the user does that, I want to then delete that file (which gets created in the app's local download folder).

这是我的代码:

router.post('/filter', function(req, res){
    try {
        var root = path.dirname(require.main.filename);
        var downloadsDir = root + '/downloads';
        var workbook = new Excel.Workbook();

        var worksheet = workbook.addWorksheet('My Sheet');
        worksheet.columns = [
            { header: 'Id', key: 'id', width: 10 },
            { header: 'Name', key: 'name', width: 32 },
            { header: 'D.O.B.', key: 'DOB', width: 10 }
        ];
        worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
        worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});

        //ensure a download directory exist, if not then create it
        fs.ensureDir(downloadsDir, function (err) {
            console.log(err);
            workbook.xlsx.writeFile(downloadsDir + '/temp.xlsx').then(function() {
                console.log('file is written');
                var file = downloadsDir + '/temp.xlsx';

                // fs.emptyDir(downloadsDir + '/', function (err) {
                //  if (err) return console.error(err)
                //  console.log('success!')
                // });
                res.send(file);
            });
        });
    } catch(err) {
        console.log('OOOOOOO this is the error: ' + err);
    }
});

此代码是通过我的公共JavaScript上的ajax函数调用的

This code is called from an ajax function on my public javascript

$('.filter-accounts-btn').click(function(){
        $.ajax({
            type: 'post',
            url: '/accounts/filter',
            success: function(data) {
                console.log('------- data: ' + data);
                window.open(data, '_blank');
            },
            error: function(err) {
                console.log('------------ Error: ' + err);
            }
        });
    });

但是它似乎不起作用.显然这是有问题的.当我在Heroku上运行我的应用程序时,打开的新页面具有url:

However it does not seem to work. Obviously there is something wrong with it. When I run my app on Heroku, the new page that opens has the url :

https://myapp.com/app/downloads/temp.xlsx

它告诉我错误.我还尝试过使用名为 open 的npm模块,在那里我只为用户打开excel.但这导致应用崩溃.

It shows me error. I also tried using an npm module called open where I would just open the excel for the user. But it caused the app to crash.

open(file, function (err) {
    if ( err ) throw err;
});

在本地测试时,它会打开excel.

When tested locally, it opens the excel.

是否有更好的方法可以做到这一点?另外,我怎么知道用户是否下载了文件?现在,它已保存在下载文件夹中,但是我想在用户下载文件后立即清空该文件夹(使用注释的代码).

Is there a better way to do this? Also, how would I know if the user has downloaded the file? Right now it is saved in the downloads folder, but I would like to empty that folder (using the commented code) as soon as the file is downloaded by the user.

*************编辑*********************

************* Edit*********************

根据建议,我已经尝试过此新代码

On suggestion, I have tried this new code

workbook.xlsx.writeFile(tempfile('.xlsx')).then(function() {
    console.log('file is written');
    res.download(tempfile('.xlsx'), function(err){
        console.log('---------- error downloading file: ' + err);
    });
});

res.downlaod引发错误

The res.downlaod throws an error

错误:ENOENT,统计 '/var/folders/nk/2w94bk3j5fs976d_dj5vwsvr0000gn/T/54f77d41-db1e-4dcf-8aea-7f88d682c436.xlsx'

Error: ENOENT, stat '/var/folders/nk/2w94bk3j5fs976d_dj5vwsvr0000gn/T/54f77d41-db1e-4dcf-8aea-7f88d682c436.xlsx'

找不到临时文件吗?

推荐答案

第一个建议是,如果文件的使用期限不长,请停止存储该文件.更好的方法是使用计算机的临时目录,并为您清理操作系统.您可以使用 tempfile 生成临时文件的完整路径.

The first advice is to stop storing the file with your code if it's not meant to last long. A better approach will be to use the temporal directory of the machine and letting the OS clean for you. You can use tempfile in order to generate a full path to a temporal file.

第二个建议是避免拆分文件生成和下载步骤.您可以在服务器上使用 res.download() api指示浏览器进入将下载窗口直接呈现给用户.也就是说:您无需直接将要下载的文件名发送给浏览器,而是直接发送要下载的文件内容和一个特殊的标头,以指示客户端浏览器您要客户端下载文件.

The second advice is to avoid splitting the file generation and download steps. You can use res.download() api on the server to instruct the browser into presenting the download windows directly to the user. That is: instead of sending to the browser the file name to download on the next step, you send directly the file content to download and a special header to instruct the client browser you want the client to download the file.

后者要求您在浏览器上修改Jquery(?,如果我在这里错了,请更正我)代码.发出发布请求并收到服务器响应后,浏览器应直接显示下载对话框.

The latter require you to modify the Jquery(?, correct me if i'm wrong here) code on the browser. Once the post request is made and the server response is received the browser should present the download dialog directly.

尝试一下:

var tmp = tempfile('.xlsx');
workbook.xlsx.writeFile(tmp).then(function() {
    console.log('file is written');
    res.download(tmp, function(err){
        console.log('---------- error downloading file: ' + err);
    });
});

这篇关于如何在Node.js Express应用程序中为用户提供下载窗口选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆