module SurveysHelper QuestionTypeMap = ['radio','check','title'] QuestionTypeOptionMap = ['radio','check'] SelectableQuestionTypeMap = ['check','radio'] CustomOptionTypeMap = ['for_each_option','new_option'] OptionLayoutTypeMap = ['list_each_option_for_one_line','continuous_list_arrangement'] def self.set_locale(locale) @locale = locale @use_custom_option_title = I18n.t('survey_question.use_custom_option') end def self.get_locale(locale) locale = locale || @locale || I18n.locale if defined?(@locale).nil? self.set_locale(locale) end locale end def self.parse_value(answer,locale=nil) locale = self.get_locale(locale) tmp = self.parse_exel_value(answer,locale: locale) tmp[1].nil? ? tmp[0] : "#{tmp[0]}(#{tmp[1]})" end def self.parse_checkbox_value_html(answer,locale=nil) locale = self.get_locale(locale) Array(answer).collect do |v| self.parse_value(v['value'],locale) end.join(", ") end def self.convert_bool_to_exel_value(flag) flag ? '1' : '' end def self.parse_exel_value(answer,xargs) locale = xargs[:locale] locale = self.get_locale(locale) options = xargs[:options] chart_data = xargs[:chart_data] use_custom_option = xargs[:use_custom_option] case answer when BSON::Document if options values = options.collect do |name,id| flag = (id==answer['oid']) if flag chart_data[name] ||= 0 chart_data[name] += 1 end end if use_custom_option values << answer['other'] end else values = [answer['value'][locale],answer['other']].compact end else if options flag = false if answer.nil? values = options.map{|name,id| ''} else values = options.collect do |name,id| flag = (name==answer) if flag chart_data[name] ||= 0 chart_data[name] += 1 end convert_bool_to_exel_value(flag) end end if !flag if use_custom_option values << answer end chart_data[@use_custom_option_title] ||= 0 chart_data[@use_custom_option_title] += 1 elsif use_custom_option values << '' end else values = [answer] end end values end def self.parse_exel_checkbox_value(answers,xargs) locale = xargs[:locale] locale = self.get_locale(locale) options = xargs[:options] chart_data = xargs[:chart_data] use_custom_option = xargs[:use_custom_option] answers = Array(answers) no_value_flag = true values = options.collect do |name,id| flag = false answers.each_with_index do |answer,i| case answer when BSON::Document flag = (id==answer['oid']) else flag = (name==answer) end if flag no_value_flag = false chart_data[name] ||= 0 chart_data[name] += 1 answers.delete_at(i) break end end convert_bool_to_exel_value(flag) end if use_custom_option if no_value_flag chart_data[@use_custom_option_title] ||= 0 chart_data[@use_custom_option_title] += 1 end values << answers.join(',') end values end def self.parse_exel_rg_value(answers,xargs) locale = xargs[:locale] locale = self.get_locale(locale) options = xargs[:options] chart_data = xargs[:chart_data] use_custom_option = xargs[:use_custom_option] radiogroups = xargs[:radiogroups] values = [] options.each do |name,opt_id| chart_data[opt_id] ||= {} answer = answers.blank? ? nil : answers[opt_id] radiogroups.each do |rg_name,rg_id| flag = (answer.class == BSON::Document && answer['rgid']==rg_id) || (answer == rg_name) values << self.convert_bool_to_exel_value(flag) if flag chart_data[opt_id][rg_name] ||= 0 chart_data[opt_id][rg_name] += 1 end end end if use_custom_option values << answers["custom_option"].to_s end values end def self.parse_double_level_value(answer,other_title,locale=nil) locale = self.get_locale(locale) case answer when BSON::Document level1 = answer['level1'][locale] level2 = answer['level2'].collect{|v| v[locale]}.join(', ') other = answer['other'].blank? ? '' : ", #{level1}-#{other_title}: #{answer['other']}" "#{level1}: #{level2}#{other}" else answer end end def self.parse_exel_double_level_value(answers,xargs) other_title = xargs[:other_title] use_custom_option = xargs[:use_custom_option] locale = xargs[:locale] chart_data = xargs[:chart_data] locale = self.get_locale(locale) values = [] custom_option_value = nil answers.each do |answer| case answer when BSON::Document level1 = answer['level1'][locale] chart_data[level1] ||= {value: 0,children: {}} chart_data[level1][:value] += 1 level2 = answer['level2'].collect do |v| tmp = v[locale] chart_data[level1][:children][tmp] ||= 0 chart_data[level1][:children][tmp] += 1 tmp end.join(', ') other = answer['other'].blank? ? '' : ", #{level1}-#{other_title}: #{answer['other']}" values << "#{level1}: #{level2}#{other}" else custom_option_value = answer end end values = [values.join("\r\n")] if use_custom_option chart_data[other_title] ||= {value: 0,children: {}} chart_data[other_title][:value] += 1 chart_data[other_title][:children][other_title] ||= 0 chart_data[other_title][:children][other_title] += 1 values << custom_option_value end values end def self.generate_xlsx(id,locale) def self.remove_illegal_utf8(str) if String.method_defined?(:encode) str.encode!('UTF-8', 'UTF-8', :invalid => :replace) else ic = Iconv.new('UTF-8', 'UTF-8//IGNORE') str = ic.iconv(str) end str end I18n.with_locale(locale) do survey = QuestionnaireSurvey.find(id) puts survey.inspect chart_data, survey_questions, survey_answers = survey.generate_chart_data ac = ActionController::Base.new() xlsx = ac.render_to_string handlers: [:axlsx], formats: [:xlsx], template: "survey_export/export", locals: {survey: survey, survey_questions: survey_questions, survey_answers: survey_answers, } dirname = "public/uploads/survey_export/#{id}" FileUtils.mkdir_p(dirname) unless File.exists?(dirname) f = "#{dirname}/#{survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')}.xlsx" file = File.open(f, "w") xlsx.force_encoding("utf-8") file.write(xlsx) puts 'success' end end end