所以,我认为我的问题很简单,但我有一些问题:)
所以在我用Django编写的应用程序中,我使用Ajax调用创建Excel文件:
$.ajax({
url: '/ajax-send-xls-desktop/',
type: 'POST',
contentType: "application/vnd.ms-excel",
data: JSON.stringify(data_xls),
dataType: 'text',
success: function(result) {
window.open('data:application/vnd.ms-excel,' + result);
}
});
在我的后端,我创建Excel文件并返回响应,如下所示:
response = HttpResponse(mimetype="application/vnd.ms-excel")
response['Content-Disposition'] = 'attachment; filename=opispozycji.xls'
response['Content-Type'] = 'application/vnd.ms-excel; charset=utf-8'
book.save(response)
我收到的一切都是很多人物:
N*8X"��1���Arial1���Arial1���Arial1���Arial1���Arial1���Arial1���Arial1���Arial
�General���� �� ���� �� ���� �� ���� �� ���� �� ���� �� ���� �� ���� �� ���� �� ���� ��
���� �� ���� �� ���� �� ���� �� ���� �� ���� �� �� �� �� �� �� �� ���`��Opis pozycji��
PDane wygnerowane przez Interzam - Internetowa Platforma Zarzdzania Zam�wieniamiSIDCPV
任何人都可以确认问题出在charset编码中吗?
答案 0 :(得分:0)
这对我有用:
response = HttpResponse(mimetype="application/ms-excel")
response['Content-Disposition'] = "attachment; filename=%s" % "excel.xls"
book.save(response)
return response
我只是链接到查看网址和显示的结果对话框。用ajax调用它不能完成......
<强>更新强>
我找到了一个解决方案解决方案(使用表单的iframe),以便您需要在此处动态请求文件 - Download a file by jQuery.Ajax。你可以使用@JohnCulviner创建的插件 - http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/或我的小函数ajax_download
:
// creates iframe and form in it with hidden field,
// then submit form with provided data
// url - form url
// data - data to form field
// input_name - form hidden input name
function ajax_download(url, data, input_name) {
var $iframe,
iframe_doc,
iframe_html;
if (($iframe = $('#download_iframe')).length === 0) {
$iframe = $("<iframe id='download_iframe'" +
" style='display: none' src='about:blank'></iframe>"
).appendTo("body");
}
iframe_doc = $iframe[0].contentWindow || $iframe[0].contentDocument;
if (iframe_doc.document) {
iframe_doc = iframe_doc.document;
}
iframe_html = "<html><head></head><body><form method='POST' action='" +
url +"'>" +
"<input type=hidden name='" + input_name + "' value='" +
JSON.stringify(data) +"'/></form>" +
"</body></html>";
iframe_doc.open();
iframe_doc.write(iframe_html);
$(iframe_doc).find('form').submit();
}
在你的情况下(例如点击事件):
$('#someid').on('click', function() {
ajax_download('/ajax-send-xls-desktop/', data_xls, 'data');
});
答案 1 :(得分:0)
Data URI scheme提到base 64编码作为选项。另一种方法是进行相关的字符编码。我建议你基于64编码数据。 Here is a question这将帮助你做到这一点。
答案 2 :(得分:0)
你真的需要使用Ajax吗?这似乎是过于复杂的事情。
我在我的应用程序中有excel下载,但它们是标准的Django视图。其中大多数是基于类的通用视图,我已经覆盖了render_to_response方法并使用excel设置内容类型。
所以我有一个标准的ListView我的对象生成HTML,而ExcelListView覆盖了渲染到响应方法,编写excel而不是将其传递给HTML模板。
class ViewToExcel():
"""
This class will implement the excel writing functionality, by overwriting the render_to_response method
"""
headings2attrributes = {} # empty default
def render_to_response(self, context, **response_kwargs):
"""
Returns a response with a an excel sheet.
"""
self.generate_headings() # specific to my application
wbk = xlwt.Workbook()
sheet = wbk.add_sheet('sheet 1')
# Create the HttpResponse object with the appropriate CSV header.
response = HttpResponse(mimetype='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename=Report.xls'
row_num = 0
col_num = 0
## write row of headings
for hd_att in self.headings2attrributes :
sheet.write(row_num, col_num , hd_att[0])
col_num += 1
row_num += 1
object_list = self.get_queryset()
# write rows of data ## again, this is fairly specific to my implementation
for object in object_list: ## go through each object instance in queryset
self.write_object_row(sheet, row_num, 0 , object)
row_num += 1
wbk.save(response)
return response
class MyView(ListView):
"""
This will produce the standard HTML page (which should contain a link to the excel download)
"""
context_object_name = "my_list"
template_name = "sequencing/MyView.html"
def get_queryset(self):
"""
get your objects and populate a queryset / querydict here
"""
...
...
return MyObjects.all().filter(blah, blah= blah)
class MyExcelView( ViewToExcel , MyView):
"""
This view will subclass both the ViewToExcel class as well as MyView.
When it is called it will reuse the get_queryset method from MyView, but will use RenderToResponse from ViewToExcel - producing excel response, rather than HTML
The way I have implemented it is that the MyExcelView provides HeadingsToAttributes dictionary, which is used to write the excel.
"""
headings2attrributes_template = [
['heading', 'attribbute' ] ,
['heading_2', 'callable' ],