嗨,我的药水里有这样的Person模式
[
%Texting.Contact.Person{
__meta__: #Ecto.Schema.Metadata<:loaded, "people">,
email: nil,
name: "John",
phone_number: "13334445555",
phonebook: #Ecto.Association.NotLoaded<association :phonebook is not loaded>,
phonebook_id: 60,
previous_phonebook_id: 60,
subscribed: true,
updated_at: ~N[2018-09-22 14:36:04.788163],
user: #Ecto.Association.NotLoaded<association :user is not loaded>,
user_id: 54
},
%Texting.Contact.Person{
__meta__: #Ecto.Schema.Metadata<:loaded, "people">,
email: nil,
name: "Rhee",
phone_number: "14443335555",
phonebook: #Ecto.Association.NotLoaded<association :phonebook is not loaded>,
phonebook_id: 60,
previous_phonebook_id: 60,
subscribed: true,
updated_at: ~N[2018-09-22 14:36:13.671479],
user: #Ecto.Association.NotLoaded<association :user is not loaded>,
user_id: 54
}
]
我想将其保存为csv文件格式。所以我做到了
def write!(people) do
file = File.open("contacts.csv", [:write, :utf8])
people
|> Enum.map(&Map.from_struct(&1))
|> Enum.map(&CSV.encode(&1, headers: [:name, :phone_number]))
|> Enum.map(&IO.write(file, &1))
end
但是我遇到了这样的错误
** (Protocol.UndefinedError) protocol String.Chars not implemented for #Function<62.51129937/2 in Stream.transform/3>. This protocol is implemented for: Atom, BitString, Date, DateTime, Decimal, Ecto.Date, Ecto.DateTime, Ecto.Time, Float, Floki.Selector, Floki.Selector.AttributeSelector, Floki.Selector.Combinator, Floki.Selector.Functional, Floki.Selector.PseudoClass, Integer, List, NaiveDateTime, Postgrex.Copy, Postgrex.Query, Postgrex.Stream, Time, URI, Version, Version.Requirement
(elixir) /home/ubuntu/bob/tmp/0a92cc555e2418d1b56e3b10e5321a85/elixir/lib/elixir/lib/string/chars.ex:3: String.Chars.impl_for!/1
(elixir) /home/ubuntu/bob/tmp/0a92cc555e2418d1b56e3b10e5321a85/elixir/lib/elixir/lib/string/chars.ex:22: String.Chars.to_string/1
(elixir) lib/io.ex:553: IO.write/2
(elixir) lib/enum.ex:1314: Enum."-map/2-lists^map/1-0-"/2
我要做的是仅将名称和phone_number字段保存为csv文件格式。 我该怎么办?
答案 0 :(得分:3)
根据the documentation,CSV.encode/2
会获取字符串列表,并且没有您尝试使用的选项。
这就是我要做的:
def write!(people) do
people
|> Stream.map(&[&1.name, &1.phone_number])
|> CSV.encode()
|> Enum.into(File.stream!("contacts.csv"))
end
Enum.map
创建一个字符串列表,然后将其编码并流式传输到contacts.csv
。
要在顶部添加标题行,可以使用Stream.concat/2
在标题行之前添加
def write!(people) do
[["name", "phone_number"]]
|> Stream.concat(people |> Stream.map(&[&1.name, &1.phone_number]))
|> CSV.encode()
|> Enum.into(File.stream!("contacts.csv"))
end