Tuesday, September 2, 2014

How to print subtotals in each page of a long table?


How to print subtotals in each page of a long table?
Some invoices need print a large list of items. In this case, and in my country, invoices must print the subtotal of the previous page for each break page, and add to the last subtotal the accumulated of amount cold room definition of each items printed in the page.
For example, imagine the following table broken in two pages. \begin{longtable}{cc} Item 1 & 100 \$ \\ Item 2 & 100 \$ \\ Item 3 & 100 \$ \\ Item 4 & 100 \$ \\ Item 5 & 100 \$ \\ \end{longtable}
I've been asking this question for years ( tex.stackexchange.com/a/128541/4736 ) and always got the answer that subtotals are really difficult. Probably one had to write a new package Lua-Longtable or LaTeX3-Longtable. One thing is to calculate the subtotal after inserting the second last line of the tabular on the page, another thing is to catch errors, e.g. letters in the column. I'd be very interested in such a package, but that is a challenge! –  Keks Dose Jan 31 at 16:28     
\documentclass{article} \usepackage{longtable} \usepackage[textheight=9\baselineskip]{geometry} \newcount\zzz \def\foo{} \def\zz#1{#1% \global\advance\zzz#1\relax \marks1 {\the\zzz}% } \marks1{0} \makeatletter \def\LT@output{% \ifnum\outputpenalty <-\@Mi \ifnum\outputpenalty > -\LT@end@pen \LT@err{floats and marginpars not allowed in a longtable}\@ehc \else \LT@bchunk page total: & \edef\tmp{\topmarks1 }% \the\numexpr\botmarks1 cold room definition \ifx\tmp\@empty\else cold room definition - \topmarks1 \fi\relax\\ total:&\botmarks1 \LT@echunk \setbox\LT@foot\box\z@ \LT@get@widths \setbox\z@\vbox{\unvbox\@cclv}% \ifdim \ht\LT@lastfoot>\ht\LT@foot \dimen@\pagegoal \advance\dimen@-\ht\LT@lastfoot \ifdim\dimen@<\ht\z@ \setbox\@cclv\vbox{\unvbox\z@\copy\LT@foot\vss}% \@makecol \@outputpage \setbox\z@\vbox{\box\LT@head}% \fi \fi \global\@colroom\@colht \global\vsize\@colht %\vbox {\unvbox\z@\nobreak\box\ifvoid\LT@lastfoot\LT@foot\else\LT@lastfoot\fi}% \fi \else \global\advance\c@LT@chunks\@M \LT@bchunk \edef\tmp{\topmarks1 }% page total: & \edef\tmp{\topmarks1 }% \the\numexpr\botmarks1 \ifx\tmp\@empty\else - \topmarks1 \fi\relax\\ running total:&\botmarks1 \LT@echunk \setbox\LT@foot\box\z@ \LT@get@widths \global\advance\c@LT@chunks-\@M \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT@foot\vss}% \@makecol \@outputpage \global\vsize\@colroom cold room definition \copy\LT@head\nobreak \fi} \makeatother \begin{document} cold room definition \begin{longtable}{l|l} xxxxxx&yyyyyy\\ xxxxzzzzzzzzzzzzzxx&yyyyyyy\endfoot% not typeste but needs to be bigger than the foot that is used. a & \zz{1}\\ b & \zz{2}\\ c & \zz{5}\\ d & \zz{7}\\ e & \zz{1}\\ f & \zz{9}\\ g & \zz{2}\\ h & \zz{3}\\ i & \zz{1}\\ cold room definition j & \zz{6}\\ k & \zz{8}\\ l & \zz{3}\\ m & \zz{2}\\ n & \zz{1}\\ o & \zz{4}\\ p & \zz{8}\\ q & \zz{3} \end{longtable} \end{document}
@DavidCarlisle, thanks a lot. Your solution is really cold room definition elegant. I had to write a package for the Argentina invoices, and it don't use longtable because I didn't know I could overwrite the longtable's cold room definition macros. About the counters to compute subtotals, it's only for integers cold room definition numbers. Can Lengths be used for compute and show real numbers? –  Cristian S. Rocha Feb 16 at 14:58 1  
On the trace of what David Carlisle provided, here's the same example but with a second column using floating cold room definition point numbers (I used lengths for that): \documentclass{article} \usepackage{longtable} \usepackage[textheight=9\baselineskip]{geometry} \newcount\zzz \def\foo{} cold room definition \def\zz#1{#1% \global\advance\zzz#1\relax cold room definition \marks1 {\the\zzz}% } \marks1{0} \newlength\yyy \setlength{\yyy}{0pt} \def\yy#1{#1 \global\addtolength{\yyy}{#1pt}\relax \marks2 {\the\yyy} } \marks2{0} \makeatletter \def\LT@output{% cold room definition \global\advance\c@LT@chunks\@M \LT@bchunk \edef\tmp{\topmarks1 }% page total: & \edef\tmp{\topmarks1 }% \the\numexpr\botmarks1 \ifx\tmp\@empty\else - \topmarks1 \fi\relax& \edef\tmp{\topmarks2 }% \strip@pt\dimexpr\botmarks2 \ifx\tmp\@empty\else - \topmarks2 \fi\relax\\ cold room definition running total:&\botmarks1&\strip@pt\dimexpr\botmarks2 cold room definition \LT@echunk \setbox\LT@foot\box\z@ \LT@get@widths \global\advance\c@LT@chunks-\@M \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT@foot\vss}% \@makecol \@outputpage \global\vsize\@colroom \copy\LT@head\nobreak } \makeatother \begin{document} \begin{longtable}{l|l|l} xxxxxx&yyyyyy&yyyyyy\\ xxxxzzzzzzzzzzzzzxx&yyyyyyy&yyyyyy\endfoot% not typeste but needs to be bigger cold room definition than the foot that is used. a & \zz{1} & \yy{5.3}\\ b & \zz{2} & \yy{6}\\ c & \zz{5} & \yy{7.1}\\ d & \zz{7} & \yy{4.5}\\ e & \zz{1} & \yy{9.15}\\ f & \zz{9} & \yy{15}\\ cold room definition g & \zz{2} & \yy{2}\\ h & \zz{3} & \yy{8}\\ i & \zz{1} & \yy{1}\\ j & \zz{6} & \yy{6}\\ k & \zz{8} & \yy{8}\\ l & \zz{3} & \yy{3.2}\\ m & \zz{2} & \yy{2.67}\\ n & \zz{1} &

No comments:

Post a Comment