скачать Excel с помощью Ajax иFlask - PullRequest
0 голосов
/ 16 июня 2020

Пытаюсь скачать excel с flask с помощью Ajax call. он показывает код ответа как 200, но Excel не загружается, а сообщения об ошибках выглядят следующим образом.

Ajax Запрос:

$ ("# genExcel"). On ("клик", function () {var xhttp = new XMLHttpRequest ();

                // Data to post
                var dataarray = {};

                // Use XMLHttpRequest instead of Jquery $ajax

                xhttp.onreadystatechange = function() {
                    var a;
                    if (xhttp.readyState === 4 && xhttp.status === 200) {
                        // Trick for making downloadable link
                        a = document.createElement('a');
                        const objectURL = window.URL.createObjectURL(xhttp.response);
                        a.href = objectURL

                        //const objectURL = URL.createObjectURL(object)

                        // Give filename you wish to download
                        a.download = "test-file.xlsx";
                        a.style.display = 'none';
                        document.body.appendChild(a);
                        a.click();
                    }
                };
                // Post data to URL which handles post request
                xhttp.open("POST", '/genexcel');
                xhttp.setRequestHeader("Content-Type", "application/json");
                // You should set responseType as blob for binary responses
                //xhttp.responseType = 'blob';
                xhttp.send(JSON.stringify(dataarray));
            });

Flask функция:

@app.route('/genexcel', methods=["GET", "POST"])
def createExcel():
    if request.method == 'POST':
        data = request.json  
        # process json data        
        return send_file(strIO, attachment_filename='test.xlsx',  as_attachment=True)

Ошибки:

1 [Только отчет] Отказано оценивать строку как JavaScript, потому что 'unsafe-eval' не является разрешенным источником скрипт в следующей директиве политики безопасности контента: "script-sr c * blob:".

2 Uncaught TypeError: не удалось выполнить createObjectURL для 'URL': не найдено ни одной функции, соответствующей подписи предоставляется.

at XMLHttpRequest.xhttp.onreadystatechange

error and response

Ответы [ 2 ]

1 голос
/ 17 июня 2020

Надеюсь, я правильно вас понял. Вот очень простой пример с использованием предоставленного вами массива данных. Вы можете изменить в соответствии с вашими потребностями:

Flask Функции

from flask import Flask, render_template, request, url_for, send_file
import xlsxwriter

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/genexcel', methods=["GET", "POST"])
def createExcel():
    if request.method == 'POST':
        data = request.get_json(force=True)
        # process json data
        createExcel(data['data'])

    file_path = 'static/files/test.xlsx'
    return send_file(file_path, attachment_filename='test.xlsx', as_attachment=True)

def createExcel(data):
    workbook = xlsxwriter.Workbook('static/files/test.xlsx')
    worksheet = workbook.add_worksheet()

    row_no = 0
    col_no = 0
    for row in data:
        col_no = 0
        for entry in row:
            worksheet.write(row_no, col_no, entry)
            col_no += 1
        row_no += 1

    workbook.close()

app.run(debug=True, port=5010)

index. html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Test</title>
  </head>
  <body>
    Testing
    <button id="genExcel">Direct Download</button>
    <button id="genExcelFlask">Flask Download</button>
  </body>

  <script>
    var btn = document.getElementById("genExcel");
    var btnFlask = document.getElementById("genExcelFlask");
    var dataArray = {
      data: [
        [1, "A", 100],
        [2, "B", 200],
      ],
    };

    btn.addEventListener("click", (e) => {
      fetch("https://jsonplaceholder.typicode.com/todos/1")
        .then((resp) => resp.blob())
        .then((blob) => {
          const url = window.URL.createObjectURL(blob);
          const a = document.createElement("a");
          a.style.display = "none";
          a.href = url;
          // the filename you want
          a.download = "todo-1.json";
          document.body.appendChild(a);
          a.click();
          window.URL.revokeObjectURL(url);
          alert("your file has downloaded!"); // or you know, something with better UX...
        })
        .catch(() => alert("oh no!"));
    });

    btnFlask.addEventListener("click", (e) => {
      console.log(JSON.stringify(dataArray));

      fetch("{{ url_for('createExcel') }}", {
        method: "post",
        body: JSON.stringify(dataArray),
      })
        .then((resp) => resp.blob())
        .then((blob) => {
          const url = window.URL.createObjectURL(blob);
          const a = document.createElement("a");
          a.style.display = "none";
          a.href = url;
          // the filename you want
          a.download = "test.xlsx";
          document.body.appendChild(a);
          a.click();
          window.URL.revokeObjectURL(url);
          alert("your file has downloaded!"); // or you know, something with better UX...
        })
        .catch(() => alert("oh no!"));
    });
  </script>
</html>

0 голосов
/ 16 июня 2020

Вот пример использования API выборки. Первая кнопка просто выполняет прямую JS загрузку. Вторая кнопка использует маршрут Flask для загрузки. Надеюсь, это поможет.

индекс. html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Test</title>
  </head>
  <body>
    Testing
    <button id="genExcel">Direct Download</button>
    <button id="genExcelFlask">Flask Download</button>
  </body>

  <script>
    var btn = document.getElementById("genExcel");
    var btnFlask = document.getElementById("genExcelFlask");

    btn.addEventListener("click", (e) => {
      fetch("https://jsonplaceholder.typicode.com/todos/1")
        .then((resp) => resp.blob())
        .then((blob) => {
          const url = window.URL.createObjectURL(blob);
          const a = document.createElement("a");
          a.style.display = "none";
          a.href = url;
          // the filename you want
          a.download = "todo-1.json";
          document.body.appendChild(a);
          a.click();
          window.URL.revokeObjectURL(url);
          alert("your file has downloaded!"); // or you know, something with better UX...
        })
        .catch(() => alert("oh no!"));
    });

    btnFlask.addEventListener("click", (e) => {
      fetch("{{ url_for('createExcel') }}")
        .then((resp) => resp.blob())
        .then((blob) => {
          const url = window.URL.createObjectURL(blob);
          const a = document.createElement("a");
          a.style.display = "none";
          a.href = url;
          // the filename you want
          a.download = "test.xlsx";
          document.body.appendChild(a);
          a.click();
          window.URL.revokeObjectURL(url);
          alert("your file has downloaded!"); // or you know, something with better UX...
        })
        .catch(() => alert("oh no!"));
    });
  </script>
</html>

Flask Функция

from flask import Flask, render_template, request, url_for, send_file

@app.route('/genexcel', methods=["GET", "POST"])
def createExcel():
    if request.method == 'POST':
        data = request.json
        print(data)
        # process json data

    file_path = 'static/files/test.xlsx'
    return send_file(file_path, attachment_filename='test.xlsx', as_attachment=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...