##// END OF EJS Templates
Add BOM to UTF-8 encoded CSV (#7037)....
Jean-Philippe Lang -
r13921:3077ed8d3a79
parent child
Show More
@@ -0,0 +1,31
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.expand_path('../../../../../test_helper', __FILE__)
19
20 class CsvTest < ActiveSupport::TestCase
21
22 BOM = "\xEF\xBB\xBF".force_encoding('UTF-8')
23
24 def test_should_include_bom_when_utf8_encoded
25 with_locale 'sk' do
26 string = Redmine::Export::CSV.generate {|csv| csv << %w(Foo Bar)}
27 assert_equal 'UTF-8', string.encoding.name
28 assert string.starts_with?(BOM)
29 end
30 end
31 end
@@ -1,59 +1,65
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2015 Jean-Philippe Lang
4 # Copyright (C) 2006-2015 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 require 'csv'
20 require 'csv'
21
21
22 module Redmine
22 module Redmine
23 module Export
23 module Export
24 module CSV
24 module CSV
25 def self.generate(*args, &block)
25 def self.generate(*args, &block)
26 Base.generate(*args, &block)
26 Base.generate(*args, &block)
27 end
27 end
28
28
29 class Base < ::CSV
29 class Base < ::CSV
30 include Redmine::I18n
30 include Redmine::I18n
31
31
32 class << self
32 class << self
33
33
34 def generate(&block)
34 def generate(&block)
35 col_sep = l(:general_csv_separator)
35 col_sep = l(:general_csv_separator)
36 encoding = l(:general_csv_encoding)
36 encoding = l(:general_csv_encoding)
37
37
38 super(:col_sep => col_sep, :encoding => encoding, &block)
38 str = ''.force_encoding(encoding)
39 if encoding == 'UTF-8'
40 # BOM
41 str = "\xEF\xBB\xBF".force_encoding(encoding)
42 end
43
44 super(str, :col_sep => col_sep, :encoding => encoding, &block)
39 end
45 end
40 end
46 end
41
47
42 def <<(row)
48 def <<(row)
43 row = row.map do |field|
49 row = row.map do |field|
44 case field
50 case field
45 when String
51 when String
46 Redmine::CodesetUtil.from_utf8(field, self.encoding.name)
52 Redmine::CodesetUtil.from_utf8(field, self.encoding.name)
47 when Float
53 when Float
48 @decimal_separator ||= l(:general_csv_decimal_separator)
54 @decimal_separator ||= l(:general_csv_decimal_separator)
49 ("%.2f" % field).gsub('.', @decimal_separator)
55 ("%.2f" % field).gsub('.', @decimal_separator)
50 else
56 else
51 field
57 field
52 end
58 end
53 end
59 end
54 super row
60 super row
55 end
61 end
56 end
62 end
57 end
63 end
58 end
64 end
59 end
65 end
General Comments 0
You need to be logged in to leave comments. Login now