My recommendation would be to see the structure of the data (which you have already) and try to decompose the problem in terms of the data you are given.
You have a structure which resembles rows and cells, so that's one approach. You format rows, which are the result of formatting individual cells, then each cell needs to have CSS classes which are passed as a hash-map.
With that in mind:
(defn cell-classes [cell]
(->> (map (fn [[k v]] (str (name k) "-" v)) cell)
(interpose " ")
(reduce str)))
(defn format-cell [cell]
(let [classes (cell-classes cell)]
[:td {:class classes}]))
(defn format-row [cells]
(->> (map format-cell cells)
(into [:tr])))
(defn format-rows [rows]
(->> (map format-row rows)
(into [:table])))
If we test it with your sample data:
(clojure.pprint/pprint (format-rows [[{:a 1 :b 2 :c 3} {:a 1 :b 2 :c 3}] [{:a 2 :b 2 :c 3} {:a 2 :b 2 :c 3}]]))
it prints
[:table
[:tr [:td {:class "a-1 b-2 c-3"}] [:td {:class "a-1 b-2 c-3"}]]
[:tr [:td {:class "a-2 b-2 c-3"}] [:td {:class "a-2 b-2 c-3"}]]]
PS: there's a minor issue in your desired output, which is that {:class "a-1" "b-2" "c-3"} would not be a desirable output for hiccup, that's why I joined the class names with space on cell-classes.