Вернуть файл как ответ $ http.post - PullRequest
0 голосов
/ 06 ноября 2018

Я хочу отправить некоторые данные обратно в мой API и вернуть файл .xlsx в качестве ответа, чтобы клиент мог его загрузить. Требование, которое заставляет все рушиться, состоит в том, что я должен создать файл .xlsx как временный файл. Проблема, с которой я столкнулся, это , когда файл открывается после загрузки, он полностью поврежден.

Я использую AngularJS и Python Flask

Вот обработка на стороне сервера :

@app.route('/downloadxlsx', methods=['POST'])
def downloadOrderToExcel():
  try:
    data = request.get_json()
    productsBought = data.pop('products')
    data['datetime'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    output = io.BytesIO()
    wb = xlsxwriter.Workbook(output, {'in_memory': True})
    ws = wb.add_worksheet(data['fullname'])
    row = col = 0
    for columnName in excelColumnNames():
      ws.write(row, col, columnName)
      col += 1
    col = 0
    row = 1
    for cellValue in data:
      ws.write(row, col, data[cellValue])
      col += 1
    for product in productsBought:
      result = queryForProducts(product)
      for r in result:
        ws.write(row, col, r['categoryname'] + " pack of " + r['pack'])
        row += 1

    output.seek(0)
    wb.close()
    return send_file(output, as_attachment=True, attachment_filename='order.xlsx')
  except Exception as ex:
    print(str(ex))
    return 'False'

Вот запрос :

  vm.downloadExcel = function() {
    this.jsonCustomer = JSON.stringify(vm.customer);
    $http.post('/downloadxlsx', this.jsonCustomer)
    .then(response => {
        let blob = new Blob([response], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
        let url = URL.createObjectURL(blob);
        let a = document.createElement('a');
        a.href = url;
        a.target = '_blank';
        a.click();
    })
  }

1 Ответ

0 голосов
/ 10 ноября 2018

Кажется, что данные повреждаются, потому что браузер не может понять данные (типа контента) при чтении из BLOB-объекта и записи его в файл.

глядя на ваш код, кажется, что вы используете двухэтапный процесс. 1. получить пользовательский ввод и предоставить ему ссылку для скачивания 2. при нажатии на ссылку для скачивания вы предоставляете ему файл xlsx. Так почему бы не подождать, пока пользователь не щелкнет по ссылке для скачивания, а затем отправить введенные пользователем данные и ответить файлом xlxs прямо с сервера. Таким образом, тип контента будет обрабатываться только сервером и его взаимодействием с сервером браузера без вмешательства ajax / client в установку типа контента.

Во-вторых, Я вижу, вы просто конвертируете пользовательский ввод в xlsx и отвечаете обратно. Таким образом, вместо того, чтобы переходить на сервер, мы можем разработать xlsx на стороне клиента, используя модуль, такой как sheetjs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...