Erlang aligned plain-text table renderer

Erlang
-module(cli_table).
-export([render/2]).

render(Headers, Rows) ->
    All = [Headers | Rows],
    Widths = [lists:max([length(to_list(lists:nth(I, R))) || R <- All])
              || I <- lists:seq(1, length(Headers))],
    Rule = "+" ++ lists:flatten([lists:duplicate(W + 2, $-) ++ "+" || W <- Widths]),
    [line(Headers, Widths), Rule | [line(R, Widths) || R <- Rows]].

to_list(V) when is_binary(V) -> binary_to_list(V);
to_list(V) -> lists:flatten(io_lib:format("~p", [V])).

line(Row, Widths) ->
    Cells = [io_lib:format("~-*s", [W, to_list(lists:nth(I, Row))])
             || {W, I} <- lists:zip(Widths, lists:seq(1, length(Widths)))],
    lists:flatten(["| ", lists:join(" | ", Cells), " |"]).