我的文档结构如下:
* Bla bla bla
Quantity | Item | Price per item | Total price
---------+----------+----------------+------------
5 | Sandwich | 5.00 | 25.00
* More bla bla bla
Quantity | Item | Price per item | Total price
---------+----------+----------------+------------
3 | Coke | 1.00 | 3.00
Grand total: 28.00
过去,我曾使用 Word 2007 创建过类似的文档,其中所有计算均自动完成。使用 LaTeX 也能实现这个功能吗?
我知道电子表格,我经常用它来处理发票。如果所有值都在一个表中,效果会很好。然而,这里的情况并非如此。
答案1
\documentclass{article}
\usepackage{array}
\def\q#1{\gdef\thisq{#1}#1}
\def\p#1{\gdef\thisp{#1}#1}
\def\total{0}
\makeatletter
\def\itemcost{%
\strip@pt\dimexpr\thisp\p@*\thisq\relax
\xdef\total{\strip@pt\dimexpr\total\p@+\thisp\p@*\thisq\relax}}
\makeatother
\begin{document}
Bla bla bla
\begin{tabular}{rcrr}
Quantity & Item & Price per item & Total price\\
\hline
\q{5} & Sandwich & \p{5.00} & \itemcost
\end{tabular}
More bla bla bla
\begin{tabular}{rcrr}
Quantity & Item & Price per item & Total price\\
\hline
\q{3} & Coke & \p{1.00} & \itemcost
\end{tabular}
Grand total: \total
\end{document}
如果您正在使用,tabularx
则仅需要在最终运行时进行算术运算,而不是在试运行时计算宽度。
\def\q#1{\gdef\thisq{#1}#1}
\def\p#1{\gdef\thisp{#1}#1}
\def\total{0}
\makeatletter
\let\normalwrite\write
\def\itemcost{%
\strip@pt\dimexpr\thisp\p@*\thisq\relax
\ifx\write\normalwrite\xdef\total{\strip@pt\dimexpr\total\p@+\thisp\p@*\thisq\relax}\fi}
\makeatother
\usepackage{tabularx}
答案2
这是一个利用一些技巧的解决方案pgfmath
\documentclass{article}
\usepackage{pgfmath}
\pgfkeys{/pgf/number format/precision=2,
/pgf/number format/fixed zerofill=true}
\def\grandtotal{0}
\def\getgrandtotal{\pgfmathroundtozerofill{\grandtotal}\$\pgfmathresult}
%% #1=quantity
%% #2=description
%% #3=price per item
\def\receipt#1#2#3{%%
\par
\vspace{1.25\baselineskip}
\begin{tabular}{cp{1.5in}rr}
Quantity & Item & Price per item & Total price \\\hline
#1 & #2 & \$#3 &
\pgfmathparse{#1*#3}\pgfmathroundtozerofill{\pgfmathresult}\$\pgfmathresult
\pgfmathsetmacro{\grandtotal}{\pgfmathresult+\grandtotal}%%
\xdef\grandtotal{\grandtotal}%%
\end{tabular}
\vspace{1.25\baselineskip}
\par
}
\usepackage{lipsum}
\pagestyle{empty}
\begin{document}
Some random text.
\receipt{5}{Sandwich}{5.00}
Some more random text.
\receipt{3}{Coke}{1.00}
Grand total: \getgrandtotal
\end{document}
更新
在看到您关于的评论后Arithmetic overflow
,这里是对上述pgfmath
方法的一种变体,它使用fp
包和siunitx
来使数字更具可读性:
\documentclass{article}
\usepackage{fp}
\usepackage{siunitx}
\def\grandtotal{0}
\def\currentAmount{}
\def\dollars#1{\SI[per-mode=symbol,group-separator={,}]{#1}[\$]{}}
\def\getgrandtotal{\dollars{\grandtotal}}
%% #1=quantity
%% #2=description
%% #3=price per item
\def\receipt#1#2#3{%%
\par
\vspace{1.25\baselineskip}
\begin{tabular}{cp{1.5in}rr}
Quantity & Item & Price per item & Total price \\\hline
#1 & #2 & \dollars{#3} &
\FPmul\currentAmount{#1}{#3}%%
\FPround\currentAmount{\currentAmount}{2}%%
\dollars{\currentAmount}%%
\FPadd\grandtotal{\currentAmount}{\grandtotal}%%
\FPround\grandtotal{\grandtotal}{2}%%
%% make the `\grandtotal` available outside of environment.
\xdef\grandtotal{\grandtotal}%%
\end{tabular}
\vspace{1.25\baselineskip}
\par
}
\begin{document}
Some random text.
\receipt{5}{Sandwich}{5.00}
Some more random text.
\receipt{3}{Coke}{1.00}
Some more random text.
\receipt{300}{Something expensive}{16179.52}
Grand total: \getgrandtotal
\end{document}
答案3
您可以使用\STsavecell
spreadtab 包的宏。此宏允许使用表格外部单元格的数值。
更新
在看到@cgnieder 的评论后,我根据提供的 MWE 添加了一个例子
\documentclass{article}
\usepackage{spreadtab}
\begin{document}
Bla bla bla
\begin{spreadtab}[%
\STsavecell\TotFood{d2}]{{tabular}{cccc}}
@Quantity & @Item & @Price per item & @Total price\\
\hline
5 & @Sandwich & 5 & a2*c2
\end{spreadtab}
More bla bla bla
\begin{spreadtab}[%
\STsavecell\TotBevreage{d2}]{{tabular}{cccc}}
@Quantity & @Item & @Price per item & @Total price\\
\hline
3 & @Coke & 1 & a2*c2
\end{spreadtab}
\FPadd{\foo}{\TotFood}{\TotBevreage}
\FPclip{\result}{\foo}
Grand total: \FPprint{\result}
\end{document}
答案4
如果您需要某种自动化,最简单的方法是在 TeX 或 LaTeX 之外实现。您通常将表格数据存储在某个外部文件中,然后使用临时程序处理该文件,该程序会将您的动态数据写入\input
文档中的一个或多个辅助文件中。
如果您在 *NIX 系统上工作并且具有一些编程技能(即使是初级技能),那么这很容易实现,主要是因为 TeX 输入文件是纯文本文件。使用 AWK 或任何您喜欢的语言,您可以在几分钟内完成大部分工作,因此如果您无法自己完成,您可以体面地请别人帮助您。
如果您正在使用另一个系统,则可能可以采用相同的方法,但您可能首先需要安装适合您喜欢的语言的解释器或编译器。