General List export as json/csv

hi,

we have a few inhouse systems which track our processes and we would like to export it as json or csv on demand to give it to controlling. we use rummage for the search / sort / pagination and it works great, but i have to write to
write an export for every custom listview. i wondered if there is a general approach / lib for that?

ideally its a button on the bottom of every template “get this list as json/csv” with minimal extra code. i would write it but i dont know how to put it in a seperate reusable module yet.

thanks!

Do your custom listviews differ a lot? Can you provide some examples?

mostly like this, just walking lists of maps and their keys, with a few functions in views for formatting dates or other stuff

<table class="table table-striped">
  <thead>
    <tr>
      <th><%= sort_link @conn, @rummage, [field: :name, ci: true, name: gettext("name")] %></th>
      <th><%= sort_link @conn, @rummage, [field: :postcode, name: gettext("postcode")] %></th>
      <th><%= sort_link @conn, @rummage, [field: :town, name: gettext("town")] %></th>
      <th><%= sort_link @conn, @rummage, [field: :acq_status, ci: false, name: gettext("acq_status")] %></th>
      <th><%= sort_link @conn, @rummage, [field: :user_id, name: gettext("user")] %></th>

      <th></th>
    </tr>
  </thead>
  <tbody>
<%= for company <- @companies do %>
    <tr>
      <td><%= link company.name, to: company_path(@conn, :show, company) %></td>
      <td><%= foo.CompanyView.plz_to_str(company.postcode) %></td>
      <td><%= company.town %></td>
      <td><span class="label label-default"><%= foo.Common.transl_acq(company.acq_status) %></span></td>


      <%= if company.user do %>
        <td><%= company.user.name %></td>
      <%= else %>
        <td>-</td>
      <% end %>

      <td class="text-right">
        <%= if (:sales != current_user_role(@conn)) || (company.user.id == current_user(@conn).id && :sales == current_user_role(@conn)) do %>

        <%= link gettext("Show"), to: company_path(@conn, :show, company), class: "btn btn-default btn-xs" %>
        <%= link gettext("Edit"), to: company_path(@conn, :edit, company), class: "btn btn-default btn-xs" %>
        <%= if (:sales != current_user_role(@conn)) do %>

         <%= link gettext("Delete"), to: company_path(@conn, :delete, company), method: :delete, data: [confirm: "Are you sure?"], class: "btn btn-danger btn-xs" %>
        <%= end %>
        <%= end %>

      </td>
    </tr>
<% end %>
  </tbody>
</table>

So what’s the problem? Collect your data, render as json/csv with some lib, and send_resp/3 with appropriate headers set.

1 Like

for example i feel dirty to have to call view functions from the controller then, and to have to write similar code 2 times, so i thought maybe there is code for that

Why would you write similar code twice? The way I see it, you would have a controller whose only job is to export files, something like Web.ExportController with a single action, export/2. It would receive the resource for which to export files as a param and

Collect your data, render as json/csv with some lib, and send_resp/3 with appropriate headers set.

As for

call view functions from the controller

you already do it with render/3.

Could you provide some code that achieves what you want and maybe someone around here would then help you make it more idiomatic? It’s a bit difficult for me to understand what you mean exactly … I’m afraid we are just speaking past each other right now.

1 Like

because the export controller would need to call the view functions as well, for example a date_format. i will post the code but will take 1-2 weeks before i can continue with this projects. thanks!

because the export controller would need to call the view functions as well, for example a date_format.

Not necessarily. You can call those functions from ExportView. Or you can render your data in the views where date_format is defined.

1 Like