如何使用 axios 和文件编码将多个 byteIO 文件从 Flask 端点发送到 Vue
How to send multiple byteIO files from Flask endpoint to Vue using axios and file encoding
TL;DR
烧瓶:
docx --> bytesIO --encodebytes()--> bytes --decode()--> string --> array 包含这些字符串的多个。
视觉:
array 包含那些字符串 --?--> blob
问题
我正在尝试 return 将多个 byteIO 文件从 Flask 端点一次发送到我的 Vue 应用程序。
基于,可以通过使用bytesencode() 和.decode() 将byteIO 文件转换为字符串来完成。
然后将字符串附加到数组并 json 序列化。
我不知道如何完成,但是要将 Vue 中的转换反转回必要的 blob 对象(将被下载)。
关于如何完成此任务有什么建议吗?
我如何从 docx 模板创建我的 bytesIO 文档文件(我的代码深受 的启发):
def from_template_multiple(context): # context is a dict containing custom attributes to be rendered in the document
template = DocxTemplate(template_document.docx')
# Create in-memory buffer
target_file = BytesIO()
# Render template and save to the buffer
template.render(context)
template.save(target_file)
# Reset the buffer's file-pointer to the beginning of the file
target_file.seek(0)
# return target file instead of send_file directly
return target_file
我的 flask 路由接收 axios 调用,从 Vue 接收上下文属性。文件编码部分来自this answer.
@hagis_api_bp.route('/docx/multiple', methods=['POST'])
def generate_word_multiple():
request_json = request.get_json()
# array to store blob derivations
blob_array = []
for item in request_json['body']:
context = json.loads(item)
target_file = process.from_template_multiple(context)
# encode as base64
from base64 import encodebytes
encoded_file = encodebytes(target_file.getvalue()).decode('ascii')
# append target file to blob array
blob_array.append(encoded_file)
return jsonify({'result': blob_array})
最后是 Vue 部分。此 axios 调用用于发送上下文信息 (json),在这里我想 return blob_array 然后恢复编码过程以接收“原始”blob 文件。
// axios request + file download
axios({
url: 'docx/multiple',
data: {body: body_array},
method: 'POST',
}).then((response) => {
// looping over each element in response.data (each converted bytesIO string)
response.data['result'].forEach((element) => {
// convert string to blob here ?
// download blob as docx file
const url = window.URL.createObjectURL(new Blob([converted_element])); // --> using result from missing conversion above
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'title.docx');
document.body.appendChild(link);
link.click();
});
});
我能够解决问题。以下 axios 请求可以解决问题。
这个问题很有帮助:Creating a BLOB from a Base64 string in JavaScript
// axios request + file download
axios({
url: 'docx/multiple',
data: {body: body_array},
method: 'POST',
}).then((response) => {
response.data['result'].forEach((element) => {
console.log(element)
// decode string to blob --> solution to question
const byteCharacters = atob(element);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
console.log(byteArray)
const url = window.URL.createObjectURL(new Blob([byteArray]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'test.docx');
document.body.appendChild(link);
link.click();
});
});
TL;DR
烧瓶:
docx --> bytesIO --encodebytes()--> bytes --decode()--> string --> array 包含这些字符串的多个。
视觉:
array 包含那些字符串 --?--> blob
问题
我正在尝试 return 将多个 byteIO 文件从 Flask 端点一次发送到我的 Vue 应用程序。
基于
我不知道如何完成,但是要将 Vue 中的转换反转回必要的 blob 对象(将被下载)。
关于如何完成此任务有什么建议吗?
我如何从 docx 模板创建我的 bytesIO 文档文件(我的代码深受
def from_template_multiple(context): # context is a dict containing custom attributes to be rendered in the document
template = DocxTemplate(template_document.docx')
# Create in-memory buffer
target_file = BytesIO()
# Render template and save to the buffer
template.render(context)
template.save(target_file)
# Reset the buffer's file-pointer to the beginning of the file
target_file.seek(0)
# return target file instead of send_file directly
return target_file
我的 flask 路由接收 axios 调用,从 Vue 接收上下文属性。文件编码部分来自this answer.
@hagis_api_bp.route('/docx/multiple', methods=['POST'])
def generate_word_multiple():
request_json = request.get_json()
# array to store blob derivations
blob_array = []
for item in request_json['body']:
context = json.loads(item)
target_file = process.from_template_multiple(context)
# encode as base64
from base64 import encodebytes
encoded_file = encodebytes(target_file.getvalue()).decode('ascii')
# append target file to blob array
blob_array.append(encoded_file)
return jsonify({'result': blob_array})
最后是 Vue 部分。此 axios 调用用于发送上下文信息 (json),在这里我想 return blob_array 然后恢复编码过程以接收“原始”blob 文件。
// axios request + file download
axios({
url: 'docx/multiple',
data: {body: body_array},
method: 'POST',
}).then((response) => {
// looping over each element in response.data (each converted bytesIO string)
response.data['result'].forEach((element) => {
// convert string to blob here ?
// download blob as docx file
const url = window.URL.createObjectURL(new Blob([converted_element])); // --> using result from missing conversion above
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'title.docx');
document.body.appendChild(link);
link.click();
});
});
我能够解决问题。以下 axios 请求可以解决问题。 这个问题很有帮助:Creating a BLOB from a Base64 string in JavaScript
// axios request + file download
axios({
url: 'docx/multiple',
data: {body: body_array},
method: 'POST',
}).then((response) => {
response.data['result'].forEach((element) => {
console.log(element)
// decode string to blob --> solution to question
const byteCharacters = atob(element);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
console.log(byteArray)
const url = window.URL.createObjectURL(new Blob([byteArray]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'test.docx');
document.body.appendChild(link);
link.click();
});
});