2016-09-23 2 views
0

Я создаю приложение node.js + express. Файл excel создается на моей стороне сервера, и мне нужно передать его пользователю в окне загрузки. Таким образом, пользователь может выбрать нужный каталог и загрузить его. После этого пользователь должен удалить этот файл (который создается в локальной папке загрузки приложения).Как предоставить окно окна загрузки пользователю в приложении node.js express

Вот мой код:

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); 
    } 
}); 

Этот код вызывается из функции AJAX в моем общедоступном 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-адрес:

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

Это показывает мне ошибку. Я также попытался использовать модуль npm под названием open, где я бы просто открыл excel для пользователя. Но это вызвало катастрофу приложения.

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

При испытании на месте он открывает превосходное положение.

Есть ли лучший способ сделать это? Кроме того, как я могу узнать, загрузил ли пользователь файл? Прямо сейчас он сохраняется в папке , но я хотел бы очистить эту папку (используя прокомментированный код), как только файл будет загружен пользователем.

************* Редактировать *********************

По предложению, я попытался это новый код

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 выдает ошибку

enter image description here

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

Разве не в состоянии найти временный файл?

ответ

1

Первый совет - прекратить хранить файл с кодом, если он не предназначен для длительного использования. Лучшим подходом будет использование временного каталога машины и предоставление ОС чистой для вас. Вы можете использовать tempfile, чтобы создать полный путь к временному файлу.

Второй совет заключается в том, чтобы избежать разделения шагов генерации и загрузки файлов. Вы можете использовать res.download() api на сервере, чтобы проинструктировать браузер о представлении окна загрузки непосредственно пользователю. То есть: вместо отправки в браузер имя файла для загрузки на следующем шаге, вы отправляете напрямую содержимое файла для загрузки и специальный заголовок, чтобы указать браузеру клиента, который вы хотите, чтобы клиент загружал файл.

Последний требует от вас изменить код JQuery (?, Correct me if i'm wrong here) в браузере. После того, как почтовый запрос сделан и получен ответ сервера, браузер должен представить диалог загрузки напрямую.

Попробуйте это:

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); 
    }); 
}); 
+0

Итак, используя временный файл, временный путь будет создан файл. Затем res.download() представит этот файл пользователю для загрузки, а затем ОС (heroku?) Очистит этот путь. Это правильно? – codeinprogress

+0

Я удалил ajax и сделал сообщение формы. Однако res.download дает вышеупомянутую ошибку (см. Изменения в моем вопросе). – codeinprogress

+1

проблема заключается в том, что каждый раз, когда вы создаете tempfile, он создает другой временный путь к файлу. Вам нужно позвонить ему один раз и получить результат в течение всего процесса обработки запросов. Я обновляю свой ответ с помощью фиксированного кода – yeiniel