[Tex/LaTex] Creating a multi-column table with dynamically wide columns from a CSV file

csvtables

I'm trying to make a multi-column table take dynamic values, read from a CSV file. The current table looks like this and has been formatted manually with tabularx, without any multicolumn package whatsoever.

\begin{tabularx}{\textwidth}{|l l X|l l X|}
    \hline
    name1 & nr1 & & name4 & nr4 & \\
    name2 & nr2 & & name5 & nr5 & \\
    name3 & nr3 & & name6 & nr6 & \\
    \hline
\end{tabularx}

how it is supposed to look

It is important that the third and sixth column are empty and as large as possible while being the same size; the table is supposed to span over the whole width of the page.

I've tried multiple approaches to dynamically create this table from a CSV file, but I never even came close to reproducing what I was able to create statically. Here is an example approach using the datatool package in combination with multicol, which probably came closest to what I wanted to achieve, albeit still being miles away:

\documentclass[a4paper]{extarticle}
\usepackage{lmodern,datatool,tabularx,multicol}
\setlength{\columnsep}{0pt}
\begin{filecontents*}{data.csv}
Name,Number
name1,nr1
name2,nr2
name3,nr3
name4,nr4
name5,nr5
name6,nr6
name7,nr7
name8,nr8
name9,nr9
name10,nr10
name11,nr11
name12,nr12
name13,nr13
name14,nr14
name15,nr15
name16,nr16
name17,nr17
name18,nr18
name19,nr19
name20,nr20
name21,nr21
name22,nr22
name23,nr23
name24,nr24
name25,nr25
name26,nr26
name27,nr27
name28,nr28
name29,nr29
name30,nr30
name31,nr31
name32,nr32
name33,nr33
name34,nr34
name35,nr35
name36,nr36
name37,nr37
name38,nr38
name39,nr39
name40,nr40
name41,nr41
name42,nr42
name43,nr43
name44,nr44
name45,nr45
name46,nr46
name47,nr47
name48,nr48
name49,nr49
name50,nr50
name51,nr51
name52,nr52
name53,nr53
name54,nr54
name55,nr55
name56,nr56
name57,nr57
name58,nr58
name59,nr59
name60,nr60
\end{filecontents*}

\begin{document}
    \DTLloaddb{Data}{data.csv}
    \noindent
    \begin{multicols}{2}
        \begin{tabularx}{\columnwidth}{|l l X|}
            \hline
            \DTLforeach*{Data}{\Name=Name,\Number=Number}{
                \Name & \Number & \\
            }
            \hline
        \end{tabularx}
    \end{multicols}
\end{document}

The end result

As the end result is obviously nowhere near what it was supposed to look, I looked for alternatives and found the csvsimple package, but I also can't get that to work in combination with tabularx. If anyone could help me wrap my head around on what is wrong here and what to fix it, I'd very much appreciate it.

Best Answer

If you are prepared to use pgfplotstable then this can be done. It contains a construct to divide columns in to equal parts to simulate multicolumn tables, namely select equal part entry of. Dividing in to two columns is achieved with the first column being given style select equal part entry of={0}{2} and the second select equal part entry of={1}{2}.

You set up a tabularx output with the options

 begin table=\begin{tabularx}{\textwidth},
 end table=\end{tabularx}

to \pgfplotstabletypeset, and then the combination

  columns={Name,Number,XXX,Name,Number,XXX},
  display columns/0/.style={select equal part entry of={0}{2},column type=|c},
  display columns/1/.style={select equal part entry of={0}{2}},
  display columns/2/.style={column type=X|},
  display columns/3/.style={select equal part entry of={1}{2},column type=c},
  display columns/4/.style={select equal part entry of={1}{2}},
  display columns/5/.style={column type=X|}

provides the divided columns with the appropriate formatting. The empty XXX columns are generated by

create on use/XXX/.style={create col/set={}}

You need to specify your data as being comma separated and of string type via

col sep=comma,string type

Finally in the example below I have thrown away the headers and added horizontal rules corresponding to your question.

Sample output

\documentclass[a4paper]{article}

\usepackage{lmodern,pgfplotstable,tabularx}
\pgfplotsset{compat=1.12}

\begin{filecontents*}{data.csv}
Name,Number
name1,nr1
name2,nr2
name3,nr3
name4,nr4
name5,nr5
name6,nr6
name7,nr7
name8,nr8
name9,nr9
name10,nr10
name11,nr11
name12,nr12
name13,nr13
name14,nr14
name15,nr15
name16,nr16
name17,nr17
name18,nr18
name19,nr19
name20,nr20
name21,nr21
name22,nr22
name23,nr23
name24,nr24
name25,nr25
name26,nr26
name27,nr27
name28,nr28
name29,nr29
name30,nr30
name31,nr31
name32,nr32
name33,nr33
name34,nr34
name35,nr35
name36,nr36
name37,nr37
name38,nr38
name39,nr39
name40,nr40
name41,nr41
name42,nr42
name43,nr43
name44,nr44
name45,nr45
name46,nr46
name47,nr47
name48,nr48
name49,nr49
name50,nr50
name51,nr51
name52,nr52
name53,nr53
name54,nr54
name55,nr55
name56,nr56
name57,nr57
name58,nr58
name59,nr59
name60,nr60
\end{filecontents*}

\begin{document}

\pgfplotstableset{create on use/XXX/.style={create col/set={}}}%
\noindent
\pgfplotstabletypeset[col sep=comma,string type,
  begin table=\begin{tabularx}{\textwidth},
  end table=\end{tabularx},
  every head row/.style={output empty row,after row=\hline},
  every last row/.style={after row=\hline},
  columns={Name,Number,XXX,Name,Number,XXX},
  display columns/0/.style={select equal part entry of={0}{2},column type=|c},
  display columns/1/.style={select equal part entry of={0}{2}},
  display columns/2/.style={column type=X|},
  display columns/3/.style={select equal part entry of={1}{2},column type=c},
  display columns/4/.style={select equal part entry of={1}{2}},
  display columns/5/.style={column type=X|}
]{data.csv}

\end{document}