Django将Excel保存到桌面

所以,我想我的问题是很容易的,但我有…一些问题:)

所以在用Django编写的应用程序中,我使用Ajax调用创buildExcel文件:

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

在我的后端创buildExcel文件并返回如下所示的响应:

  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 

任何人都可以确认问题在于字符集编码?

Data URIscheme提到了base 64编码。 另一种方法是做相关的字符编码。 我build议你基地64编码的数据。 这里有一个问题可以帮助你做到这一点。

这适用于我:

 response = HttpResponse(mimetype="application/ms-excel") response['Content-Disposition'] = "attachment; filename=%s" % "excel.xls" book.save(response) return response 

我只是链接到查看url和结果对话框显示。 阿贾克斯称它不能做…

更新:

我发现了一个解决方法(iframe与使用的forms)的情况下,你需要在这里dynamic请求文件 – 通过jQuery.Ajax下载文件 。 你可以使用@JohnCulviner创build的插件 – 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'); }); 

你真的需要使用Ajax吗? 这似乎是过于复杂的事情。

我在我的应用程序中有excel下载,但它们是标准的Django视图。 他们大多数是基于类的通用视图,其中我已经覆盖了render_to_response方法,并使用excel设置内容types。

所以我有我的对象的标准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' ],