csv食わせてインポート
とかよく作ると思う。
コレを作るとたいてい「インポート失敗します~」の問い合わせが絶えない
UTF-8にしてくださいね
Windows-31Jにしてくださいね
BOMを取り除いてくださいね
ダブルクォートで囲ってね(囲わないでね)
カラムの中にクォート使わないでね
言ってみるものの、あまり伝わらない。
だからいろんなファイル作ってしっかりテストしておきたい。
でも文字コード違いのファイル手で作るのめんどくさい…
という気持ちからスクリプトを書いた。
ruby any_csv.rb hoge.csv
nkf使えばUTF-8以外も受け付けられそうね
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
require 'csv'
require 'fileutils'
class AnyCsv
BOM = "\uFEFF"
attr_reader *%i[src_path base_name put_options put_path]
def initialize(src_path)
@src_path = src_path
@base_name = File.basename(src_path, ".*")
@put_path = 'anycsv'
@put_options = PutOptions[
Encoding::SHIFT_JIS,
Encoding::WINDOWS_31J,
Encoding::UTF_8,
bom: nil, quotes: [true, false]]
@put_options += PutOptions[Encoding::UTF_8, bom: true, quotes: [true, false]] # bom付き
FileUtils.mkdir_p(put_path)
end
# foo.csv => foo_UTF-8_BOM_QUOTED.csv
def output_file(put_option)
filename = [base_name, put_option.enc]
filename << "BOM" if put_option.bom
filename << "QUOTED" if put_option.quote
filename = filename.join('_') + '.csv'
File.join(put_path, filename)
end
def encoding(put_option)
encoding = "UTF-8:#{put_option.enc}"
encoding = "BOM|#{encoding}" if put_option.enc == Encoding::UTF_8
encoding
end
def csv_options(put_option)
{ encoding: encoding(put_option),
liberal_parsing: true,
invalid: :replace,
undef: :replace,
replace: "*" }
end
def make
put_options.each do |put_option|
File.open(output_file(put_option), 'wb') do |f|
f.write BOM if put_option.bom
csv = CSV.new(f, force_quotes: put_option.quote)
CSV.foreach(src_path, **csv_options(put_option)) do |row|
csv << row
end
end
end
end
class PutOptions
def self.[](*encodings, bom: nil, quotes: nil)
encodings.map do |enc|
(quotes || [true]).map do |quote|
PutOption.build(enc, bom:, quote:)
end
end.flatten
end
end
class PutOption
attr_reader :enc, :bom, :quote
def self.build(encode, bom: nil, quote: true)
new(encode, bom, quote)
end
def initialize(encode, bom, quote)
@enc = encode
@bom = bom if encode == Encoding::UTF_8
@quote = quote
end
end
end
AnyCsv.new(ARGV[0]).make
コメント