Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return a csv encoded in UTF-8 with BOM from django

Tags:

csv

utf-8

django

I'm trying to output a CSV file that the user could open with excel. I've encoded all string in UTF-8 but when I opened the file with excel I see jibrish. Only after converting the file to UTF-8 with BOM (using notepad++ on windows) I was able to display the content properly.

I'm following this pattern from the docs:

def render_to_csv(self, request, qs): 
  response = HttpResponse(content_type='text/csv')
  response['Content-Disposition'] = 'attachment; filename="test.csv"'

  writer = csv.writer(response, delimiter=',')

  for row in qs.values_list(*self.fields_to_export):
    writer.writerow([unicode(v).encode('utf-8') if v is not None else '' for v in row])

  return response

Where does to BOM fit into all of this ?

BTW, There are similar questions on SO but unfortunately non of them are answered.

EDIT

building on @Alastair McCormack, I ended up explicitly adding the BOM characters at the begining of the file. Only difference is i used the codecs package instead of hard coding the bytes. Feels awkward but does the trick !

import codecs

def render_to_csv(self, request, qs): 
  ... 
  response.write(codecs.BOM_UTF8)
  ...
  return response
like image 976
haki Avatar asked May 17 '15 15:05

haki


1 Answers

Add the UTF-8 BOM to the response object before you write your data:

def render_to_csv(self, request, qs): 
  response = HttpResponse(content_type='text/csv')
  response['Content-Disposition'] = 'attachment; filename="test.csv"'

  # BOM      
  response.write("\xEF\xBB\xBF")

  writer = csv.writer(response, delimiter=',')
  …
like image 188
Alastair McCormack Avatar answered Sep 22 '22 22:09

Alastair McCormack