                                        (get-ext-plot-headers project-id)
                                        (get-ext-sample-headers project-id)
                                        (map question-key sample-value-group))
-            headers-out        (str/join "," (map #(-> % name csv-quotes) text-headers))
+            headers-out        (->> text-headers
+                                    (map #(-> % name csv-quotes))
+                                    (str/join ",")
+                                    (str "\uFEFF")) ; Prefix headers with a UTF-8 tag
             data-rows          (map (fn [row]
                                       (let [value           (tc/jsonb->clj (:value row))
                                             ext-plot-data   (tc/jsonb->clj (:ext_plot_data row))

            text-headers       (concat plot-base-headers
                                       (get-ext-plot-headers project-id))
            number-headers     (get-value-distribution-headers sample-value-group)
            headers-out        (str/join "," (map #(-> % name csv-quotes) (concat text-headers number-headers)))
            data-rows          (map (fn [row]
                                      (let [samples       (tc/jsonb->clj (:samples row))
                                            ext-plot-data (tc/jsonb->clj (:ext_plot_data row))]

                   "Content-Disposition" (str "attachment; filename="
                                              (prepare-file-name (:name project-info) "plot")
                                              ".csv")}
         :body (str/join "\n" (cons headers-out data-rows))})
      (data-response "Project not found."))))

(defn- get-ext-sample-headers
