-
Notifications
You must be signed in to change notification settings - Fork 0
/
csv.clj
116 lines (100 loc) · 3.43 KB
/
csv.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
(ns toyokumo.commons.csv
(:require
[clojure.java.io :as io]
[schema.core :as s])
(:import
(java.io
Reader)
(org.apache.commons.csv
CSVFormat
CSVParser
CSVPrinter)))
(def ^:private format-schema
(s/enum :default
:excel
:informix-unload
:informix-unload-csv
:mongodb-csv
:mongodb-tsv
:mysql
:oracle
:postgresql-csv
:postgresql-text
:rfc4180
:tdf))
(s/defn csv-format :- CSVFormat
[fmt :- format-schema]
(case fmt
:excel CSVFormat/EXCEL
:informix-unload CSVFormat/INFORMIX_UNLOAD
:informix-unload-csv CSVFormat/INFORMIX_UNLOAD_CSV
:mongodb-csv CSVFormat/MONGODB_CSV
:mongodb-tsv CSVFormat/MONGODB_TSV
:mysql CSVFormat/MYSQL
:oracle CSVFormat/ORACLE
:postgresql-csv CSVFormat/POSTGRESQL_CSV
:postgresql-text CSVFormat/POSTGRESQL_TEXT
:rfc4180 CSVFormat/RFC4180
:tdf CSVFormat/TDF
CSVFormat/DEFAULT))
(s/defn csv-parser :- CSVParser
"Make org.apache.commons.csv.CSVParser
reader - java.io.Reader
opts - Options that determine CSV format
:format - Use to make org.apache.commons.csv.CSVFormat
See https://commons.apache.org/proper/commons-csv/user-guide.html for more detail"
([reader :- Reader]
(csv-parser reader {:format :default}))
([reader :- Reader
opts :- {:format format-schema}]
(CSVParser/parse reader (csv-format (:format opts)))))
(defmulti read-all
"Read all CSV records as a vector of vectors of string,
like: [[\"foo\" \"\bar\"] [\"hoge\" \"fuga\"]]
General usage:
(with-open [reader (-> (clojure.java.io/file \"/your/file/path.csv\")
(clojure.java.io/reader :encoding \"utf-8\"))
parser (csv-parser reader {:format :rfc4180})]
(read-all parser))"
class)
(defmethod read-all CSVParser [parser]
(->> (.getRecords parser)
(mapv vec)))
(defmethod read-all Reader [reader]
(with-open [parser (csv-parser reader)]
(read-all parser)))
(defmethod read-all :default [in]
(with-open [parser (csv-parser (io/reader in))]
(read-all parser)))
(s/defn csv-printer :- CSVPrinter
"Make org.apache.commons.csv.CSVPrinter
out - java.lang.Appendable
opts - Options that determine CSV format
:format - Use to make org.apache.commons.csv.CSVFormat
See https://commons.apache.org/proper/commons-csv/user-guide.html for more detail"
([out :- Appendable]
(csv-printer out {:format :default}))
([out :- Appendable
opts :- {:format format-schema}]
(CSVPrinter. out (csv-format (:format opts)))))
(defmulti write-all
"Write all CSV records into out.
valeus should be a vector like: [[\"foo\" \"\bar\"] [\"hoge\" \"fuga\"]]
General usage:
;; Write on memory
(let [values [[\"foo\" \"bar\"] [\"hoge\" \"fuga\"]]
sb (StringBuilder.)
printer (csv-printer sb {:format :rfc4180})]
(write-all printer values)
(str sb))
;; Write to a file
(let [values [[\"あいう\" \"えお\"] [\"foo\" \"bar\"]]]
(with-open [out (clojure.java.io/writer (io/file \"/your/file/path.csv\") :encoding \"utf-8\")]
(let [printer (csv-printer out {:format :rfc4180})]
(write-all printer values))))"
(fn [out values]
(class out)))
(defmethod write-all CSVPrinter [printer values]
(.printRecords printer values))
(defmethod write-all :default [out values]
(write-all (csv-printer out) values))