Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

The following table was created with the following LaTeX-code (mwe):

table

\documentclass{article}
\usepackage{tabu}
\usepackage{multirow}
\begin{document}
\newtabulinestyle{stip=on 1.5pt off 2pt}
\begin{tabu} to \linewidth {X[0.8l]X[2.5l]X[c]X[c]X[c]X[c]X[c]} \hline
\rowfont{\bfseries} \multicolumn{2}{c}{\multirow{2}{*} {NUMBERS}} &
\multicolumn{2}{c}{Type} & \multicolumn{2}{c}{Size} &
 \multirow{2}{*}{All} \\
 & & A & B & Big & Small & \\ \hline
\multicolumn{2}{l}{Good}  & 1 & 4 & 2 & 3 & 5\\ \tabucline[stip]{-}
 \multirow{3}{*}{Ugly} & Cow & 7  & 1 & 4 & 4 & 8 \\ \tabucline[stip]{2-}
 & Goat & 1 & 2 & 0 & 3 & 3 \\ \tabucline[stip]{2-}
 & Horse & 2& 1 & 3 & 0 & 3 \\ \tabucline[stip]{-}
\multicolumn{2}{l}{Bad}& 12 & 1 & 6 & 7 & 13  \\ \hline
 \rowfont{\bfseries} \multicolumn{2}{l}{TOTAL} & 23 & 9 & 15 & 17 & 32 \\ \hline
\end{tabu}
\end{document}

Is it possible to create a macro that makes such tables from the following input?

 \begin{mytable}[NUMBERS]
 1 & 4 & 2 & 3 & 5 \\ 
 7 & 1 & 4 & 4 & 8 \\
 1 & 2 & 0 & 3 & 3 \\
 2 & 1 & 3 & 0 & 3 \\
 12 & 1 & 6 & 7 & 13 \\
 23 & 9 & 15 & 17 & 32
 \end{mytable}

I have been playing around with pgfplotstable for a while, but especially the multirows are giving me a headache.

(Ideally, even the sums would be automatically calculated and an error would be returned if the numbers did not match. (A + B = Big + Small). But this is luxury rather than necessary.)

share|improve this question
    
Some information you should probably give: will your table always have the same headings? Will it always have the same dimensions? –  Scott H. Nov 17 '12 at 17:41
    
@Scott H. The answer is yes in both cases: it is always the exact same table, except for the numbers in it and the content of the very first cell ("NUMBERS"). So in fact just "prepending" a given first column (in fact a double column including multirows and multicolumns) and a first row would be a major step in the good direction that I have not managed to take yet. –  Archibald Nov 17 '12 at 18:02
add comment

2 Answers

up vote 12 down vote accepted

Updated answer shows two versions, a simple one without calculation and checks and a second one which does the calculation.

enter image description here

\documentclass{article}
\usepackage{tabu}
\usepackage{multirow}
\begin{document}
\newtabulinestyle{stip=on 1.5pt off 2pt}
\begin{tabu} to \linewidth {X[0.8l]X[2.5l]X[c]X[c]X[c]X[c]X[c]} \hline
\rowfont{\bfseries} \multicolumn{2}{c}{\multirow{2}{*} {NUMBERS}} &
\multicolumn{2}{c}{Type} & \multicolumn{2}{c}{Size} &
 \multirow{2}{*}{All} \\
 & & A & B & Big & Small & \\ \hline
\multicolumn{2}{l}{Good}  & 1 & 4 & 2 & 3 & 5\\ \tabucline[stip]{-}
 \multirow{3}{*}{Ugly} & Cow & 7  & 1 & 4 & 4 & 8 \\ \tabucline[stip]{2-}
 & Goat & 1 & 2 & 0 & 3 & 3 \\ \tabucline[stip]{2-}
 & Horse & 2& 1 & 3 & 0 & 3 \\ \tabucline[stip]{-}
\multicolumn{2}{l}{Bad}& 12 & 1 & 6 & 7 & 13  \\ \hline
 \rowfont{\bfseries} \multicolumn{2}{l}{TOTAL} & 23 & 9 & 15 & 17 & 32 \\ \hline
\end{tabu}


\def\mytable[#1]#2\\#3\\#4\\#5\\#6\\#7\end#8{%
\begin{tabu} to \linewidth {X[0.8l]X[2.5l]X[c]X[c]X[c]X[c]X[c]} \hline
\rowfont{\bfseries} \multicolumn{2}{c}{\multirow{2}{*} {#1}} &
\multicolumn{2}{c}{Type} & \multicolumn{2}{c}{Size} &
 \multirow{2}{*}{All} \\
 & & A & B & Big & Small & \\ \hline
\multicolumn{2}{l}{Good}  &#2\\\tabucline[stip]{-}
 \multirow{3}{*}{Ugly} & Cow & #3 \\ \tabucline[stip]{2-}
 & Goat & #4\\ \tabucline[stip]{2-}
 & Horse & #5 \\ \tabucline[stip]{-}
\multicolumn{2}{l}{Bad}& #6 \\ \hline
 \rowfont{\bfseries} \multicolumn{2}{l}{TOTAL} & #7 \\ \hline
\end{tabu}%
\end{mytable}}

 \begin{mytable}[NUMBERS]
 1 & 4 & 2 & 3 & 5 \\ 
 7 & 1 & 4 & 4 & 8 \\
 1 & 2 & 0 & 3 & 3 \\
 2 & 1 & 3 & 0 & 3 \\
 12 & 1 & 6 & 7 & 13 \\
 23 & 9 & 15 & 17 & 32
 \end{mytable}


\def\testrowone#1&#2&#3&#4&#5\\{%
\ifnum\numexpr#1+#2\relax=#5\else \typeout{A+B != All}\fi
\ifnum\numexpr#3+#4\relax=#5\else \typeout{big+small != All}\fi
}

\def\cella#1&#2&#3&#4&#5\\{#1}
\def\cellb#1&#2&#3&#4&#5\\{#2}
\def\cellc#1&#2&#3&#4&#5\\{#3}
\def\celld#1&#2&#3&#4&#5\\{#4}
\def\celle#1&#2&#3&#4&#5\\{#5}

\def\mytableb[#1]#2\\#3\\#4\\#5\\#6\\#7\end#8{%
\testrowone#2\\
\begin{tabu} to \linewidth {X[0.8l]X[2.5l]X[c]X[c]X[c]X[c]X[c]} \hline
\rowfont{\bfseries} \multicolumn{2}{c}{\multirow{2}{*} {#1}} &
\multicolumn{2}{c}{Type} & \multicolumn{2}{c}{Size} &
 \multirow{2}{*}{All} \\
 & & A & B & Big & Small & \\ \hline
\multicolumn{2}{l}{Good}  &#2\\\tabucline[stip]{-}
 \multirow{3}{*}{Ugly} & Cow & #3 \\ \tabucline[stip]{2-}
 & Goat & #4\\ \tabucline[stip]{2-}
 & Horse & #5 \\ \tabucline[stip]{-}
\multicolumn{2}{l}{Bad}& #6 \\ \hline
 \rowfont{\bfseries} \multicolumn{2}{l}{TOTAL} &
\the\numexpr \cella#2\\+\cella#3\\+\cella#4\\+\cella#5\\+\cella#6\\ \relax &
\the\numexpr \cellb#2\\+\cellb#3\\+\cellb#4\\+\cellb#5\\+\cellb#6\\ \relax &
\the\numexpr \cellc#2\\+\cellc#3\\+\cellc#4\\+\cellc#5\\+\cellc#6\\ \relax &
\the\numexpr \celld#2\\+\celld#3\\+\celld#4\\+\celld#5\\+\celld#6\\ \relax &
\the\numexpr \celle#2\\+\celle#3\\+\celle#4\\+\celle#5\\+\celle#6\\ \relax 
\end{tabu}%
\end{mytableb}}

 \begin{mytableb}[NUMBERS]
 1 & 4 & 2 & 3 & 5 \\ 
 7 & 1 & 4 & 4 & 8 \\
 1 & 2 & 0 & 3 & 3 \\
 2 & 1 & 3 & 0 & 3 \\
 12 & 1 & 6 & 7 & 13 \\
 \end{mytableb}


\end{document}
share|improve this answer
    
Wow. Your answer is a nice example of what 'simple/plain' TeX can do, thank you! –  Archibald Nov 17 '12 at 19:19
2  
@DavidCarlisle -- oh, please don't mash the contents of each line up against the rule above it! you know better! –  barbara beeton Nov 17 '12 at 20:31
    
If using this code please add \setlength\extrarowheight{3pt} before the table to avoid causing pain to @barbarabeeton –  David Carlisle Nov 17 '12 at 20:40
1  
Ah so @barbarabeeton will be able to sleep easily tonight:-) –  David Carlisle Nov 17 '12 at 20:56
2  
Wonderful to see Jupiter arguing with Minerva here on TeX.SE... –  Brent.Longborough Nov 18 '12 at 10:44
show 1 more comment

A half-baked pgfplotstable solution. The column sums are missing but sanity check on the sums of rows are implemented (gives the stupid error in the screenshot if there is a discrepancy). Also the upper left corner text is optional you can change it when entering the table. With this you don't need to enter your data in a tabular format.

\documentclass{article}
\usepackage{pgfplotstable,multirow,booktabs}

\pgfplotstableset{toughtable/.style={
    every head row/.style={before row={\toprule
      \multicolumn{2}{c}{\multirow{2}{*}{\textbf{#1}}} &\multicolumn{2}{c}{Type} &\multicolumn{2}{c}{Size} &\multirow{2}{*}{All}\\
                           },
                                   after row=\midrule
                               },
    every last row/.style={after row=\bottomrule},
        create on use/myfirstcol/.style ={create col/set list={Good,Ugly,,,Bad,\textbf{TOTAL}}},%A dummy column
        create on use/mysecondcol/.style={create col/set list={,Cow,Goat,Horse,}},%A dummy column
        create on use/summationcol/.style={
                  create col/expr={\thisrowno{0}+\thisrowno{1}-\thisrowno{2}-\thisrowno{3}==0?\thisrowno{0}+\thisrowno{1}:0}
                            },
        columns={myfirstcol,mysecondcol,[index]0,[index]1,[index]2,[index]3,summationcol},
        columns/myfirstcol/.style={string type,column name=,
            assign cell content/.code={%
            \ifnum\pgfplotstablerow=1\pgfkeyssetvalue{/pgfplots/table/@cell content}{\multirow{3}{*}{Ugly}}\fi
            }
        },
        columns/mysecondcol/.style={string type,column name=},
        columns/summationcol/.style={string type,column name=,
        assign cell content/.code={
            \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/@preprocessed cell content}==0?int(1):int(0)}
                \ifnum\pgfmathresult=1\relax
                \pgfkeyssetvalue{/pgfplots/table/@cell content}{Chicken Run!!}%
                \else
                \pgfmathparse{int(\pgfkeysvalueof{/pgfplots/table/@unprocessed cell content})}
                \edef\temp{\noexpand\pgfkeyssetvalue{/pgfplots/table/@cell content}{\pgfmathresult}}\temp
                \fi
                }
      },
        display columns/2/.style={column name=A},
        display columns/3/.style={column name=B},
        display columns/4/.style={column name=Big},
        display columns/5/.style={column name=Small},
        every row no 1/.style={before row=\hline,after row=\cmidrule{2-7}},
        every row no 2/.style={after row=\cmidrule{2-7}},
        every row no 3/.style={after row=\hline},
        every row no 4/.style={after row=\hline},
        }
}
\begin{document}

\pgfplotstabletypeset[toughtable=NUMBERS]{
 1   4  2   3 
 7   1  3   4
 1   2  0   3
 2   1  3   0
 12  1  6   7
}

\end{document}

enter image description here

I'll try to get the columns sum hopefully soon.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.