Como imprimir subtotais em cada página de uma tabela longa?

Como imprimir subtotais em cada página de uma tabela longa?

Algumas faturas precisam imprimir uma grande lista de itens. Neste caso, e no meu país, as faturas devem imprimir o subtotal da página anterior para cada quebra de página, e adicionar ao último subtotal o valor acumulado de cada item impresso na página.

Por exemplo, imagine a seguinte tabela dividida em duas páginas.

\begin{longtable}{cc}
Item 1 & 100 \$ \\
Item 2 & 100 \$ \\
Item 3 & 100 \$ \\
Item 4 & 100 \$ \\
Item 5 & 100 \$ \\
\end{longtable}

A fatura deve aparecer para cada página com o subtotal antes e a soma dos valores depois:

Página 1:

Item 1 & 100 \$ \\
Item 2 & 100 \$ \\
Item 3 & 100 \$ \\
Subtotal: 300 \$.

Página 2:

Transport: 300 \$.
Item 4 & 100 \$ \\
Item 5 & 100 \$ \\
Transport + Subtotal: 500 \$.

Tentei acumular o valor usandoFPem cada linha da tabela, mas não funciona. Imprima 0 para transporte e transporte + subtotal.

Exemplo em ShareLatex com o problema

Obrigado por qualquer ideia!

Responder1

Isso tem algumas limitações, mas recalcula a caixa de rodapé em cada página...

insira a descrição da imagem aqui

\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  \ifx\tmp\@empty\else - \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
    \copy\LT@head\nobreak
  \fi}
\makeatother

\begin{document}

\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}\\
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}

Responder2

Seguindo o que David Carlisle forneceu, aqui está o mesmo exemplo, mas com uma segunda coluna usando números de ponto flutuante (usei comprimentos para isso):

\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}

\newlength\yyy
\setlength{\yyy}{0pt}
\def\yy#1{#1
\global\addtolength{\yyy}{#1pt}\relax
\marks2 {\the\yyy}
}
\marks2{0}

\makeatletter
    \def\LT@output{%
            \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\\
            running total:&\botmarks1&\strip@pt\dimexpr\botmarks2
            \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 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}\\
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} & \yy{1.1}\\
o & \zz{4} & \yy{4}\\
p & \zz{8} & \yy{8.05}\\
q & \zz{3} & \yy{3}
\end{longtable}

\end{document}

informação relacionada