如何设置表格样式而不弄乱表格源代码?

如何设置表格样式而不弄乱表格源代码?

使用表格环境之外的命令可以轻松设置表格分隔线/规则的样式。


最小工作示例:

\documentclass{article}
\usepackage{booktabs}
\usepackage{colortbl}

\begin{document}

\arrayrulecolor{blue}

\begin{tabular}{l}
\toprule
Header\\
\midrule
abc\\
def\\
\bottomrule
\end{tabular}

\end{document}

但是,是否可以在表格环境之外对表格的行或网格进行样式设置?例如:将网格和行背景颜色的样式规范放在表格环境之前,以保持表格源代码整洁?


事实上我想建立一些像这​​样的好看的发票表:

在此处输入图片描述

我想保持源代码干净的原因很简单,我将表格内容从外部计算程序(LibreOffice Calc)复制到 LaTeX 中,因此我不想事后手动调整所有行。在最佳情况下,表格源代码不包含任何样式规范,只包含行末的&和等必需元素(我已经可以在计算程序中插入这些元素)。\\


我的计算程序所提到的输出是针对 LaTeX 预先格式化的,如下所示:

\toprule                                            
\textbf{Position}   &   \textbf{Date}   &   \textbf{Work type}  &   \textbf{Duration}   &   \textbf{Hourly rate}    &   \textbf{TOTAL}    \\
\midrule                                            
1   &   05/04/2018  &   Cleaning the balcony    &   \SI{4}{\hour}   &   \SI{10}{\euro\per\hour} &   \SI{40}{\euro}  \\
2   &   05/04/2019  &   Mowing the meadow   &   \SI{7.5}{\hour} &   \SI{10}{\euro\per\hour} &   \SI{75}{\euro}  \\
3   &   05/04/2020  &   Planting some flowers   &   \SI{5.5}{\hour} &   \SI{10}{\euro\per\hour} &   \SI{55}{\euro}  \\
4   &   05/04/2021  &   Producing ice cream &   \SI{10.5}{\hour}    &   \SI{10}{\euro\per\hour} &   \SI{105}{\euro} \\
5   &   05/04/2022  &   Cleaning the television &   \SI{5.5}{\hour} &   \SI{10}{\euro\per\hour} &   \SI{55}{\euro}  \\
6   &   05/04/2023  &   Building a pond &   \SI{9}{\hour}   &   \SI{10}{\euro\per\hour} &   \SI{90}{\euro}  \\
7   &   05/04/2024  &   Feeding the fishes  &   \SI{8.5}{\hour} &   \SI{10}{\euro\per\hour} &   \SI{85}{\euro}  \\
8   &   05/04/2025  &   Cutting the trees   &   \SI{7}{\hour}   &   \SI{10}{\euro\per\hour} &   \SI{70}{\euro}  \\
9   &   05/04/2026  &   Watering the flowers    &   \SI{3}{\hour}   &   \SI{10}{\euro\per\hour} &   \SI{30}{\euro}  \\
\midrule                                            
&       &       &   Summary:            &   \SI{1000}{\euro}  \\
\bottomrule

如您所见,只需将此块复制粘贴到 LaTeX 中即可,无需手动插入其他样式规范。


完整的最小工作示例(MWE):

\documentclass{article}
\usepackage[english, ngerman]{babel}
\usepackage{tabularx}
\usepackage{booktabs}
\usepackage[per=slash,locale=DE]{siunitx}

\sisetup{round-mode = places, round-precision = 2, round-integer-to-decimal}
\newunit{\euro}{EUR}

\begin{document}

\begin{tabularx}{1\textwidth}{c c p{5cm} r r r}

\toprule                                            
\textbf{Position}   &   \textbf{Date}   &   \textbf{Work type}  &   \textbf{Duration}   &   \textbf{Hourly rate}    &   \textbf{TOTAL}    \\
\midrule                                            
1   &   05/04/2018  &   Cleaning the balcony    &   \SI{4}{\hour}   &   \SI{10}{\euro\per\hour} &   \SI{40}{\euro}  \\
2   &   05/04/2019  &   Mowing the meadow   &   \SI{7.5}{\hour} &   \SI{10}{\euro\per\hour} &   \SI{75}{\euro}  \\
3   &   05/04/2020  &   Planting some flowers   &   \SI{5.5}{\hour} &   \SI{10}{\euro\per\hour} &   \SI{55}{\euro}  \\
4   &   05/04/2021  &   Producing ice cream &   \SI{10.5}{\hour}    &   \SI{10}{\euro\per\hour} &   \SI{105}{\euro} \\
5   &   05/04/2022  &   Cleaning the television &   \SI{5.5}{\hour} &   \SI{10}{\euro\per\hour} &   \SI{55}{\euro}  \\
6   &   05/04/2023  &   Building a pond &   \SI{9}{\hour}   &   \SI{10}{\euro\per\hour} &   \SI{90}{\euro}  \\
7   &   05/04/2024  &   Feeding the fishes  &   \SI{8.5}{\hour} &   \SI{10}{\euro\per\hour} &   \SI{85}{\euro}  \\
8   &   05/04/2025  &   Cutting the trees   &   \SI{7}{\hour}   &   \SI{10}{\euro\per\hour} &   \SI{70}{\euro}  \\
9   &   05/04/2026  &   Watering the flowers    &   \SI{3}{\hour}   &   \SI{10}{\euro\per\hour} &   \SI{30}{\euro}  \\
\midrule                                            
&       &       &   Summary:            &   \SI{1000}{\euro}  \\
\bottomrule

\end{tabularx}

\end{document}

答案1

下面是一个快速模型,展示了如何执行此操作来生产:

在此处输入图片描述

代码如下:

\documentclass{article}
\usepackage[svgnames,table]{xcolor}
\usepackage[margin=10mm,a4paper]{geometry}
\usepackage[english, ngerman]{babel}
\usepackage{tabularx}
%\usepackage{booktabs}
\usepackage[per=slash,locale=DE]{siunitx}
\usepackage{colortbl}
\usepackage{expl3}
\usepackage{environ}

\sisetup{round-mode = places, round-precision = 2, round-integer-to-decimal}
\newunit{\euro}{EUR}

\newcolumntype{A}{>{\columncolor{Gainsboro}\raggedright}p{22mm}}
\newcolumntype{B}{>{\columncolor{Gainsboro}\raggedright}p{50mm}}
\newcolumntype{C}{>{\columncolor{Gainsboro}}p{30mm}}

\newcommand\invoicetop{\textcolor{blue}{Nice stuff at the top of the invoice}}
\newcommand\invoicebot{\textcolor{blue}{Nice stuff at the bottom of the invoice}}

\ExplSyntaxOn
\seq_new:N \l_invoice_seq
\tl_new:N \l_table_tl
\NewEnviron{invoice}{%
   % break the table up into its pieces
   \regex_split:noN { (?:\c{toprule}|\c{midrule}|\c{bottomrule}) } {\BODY} \l_invoice_seq
   % initialise the table contents using the row colour
   \tl_set:Nn \l_table_tl { \rowcolor{LimeGreen} }
   % add the table header to \l_table_tl
   \seq_pop_left:NN \l_invoice_seq \l_tmpa_tl
   % if \l_tmpa_tl is empty then pop again
   \tl_if_blank:VT \l_tmpa_tl { \seq_pop_left:NN \l_invoice_seq \l_tmpa_tl }
   \tl_put_right:No \l_table_tl {\l_tmpa_tl}
   % now pop and print the table body
   \seq_pop_left:NN \l_invoice_seq \l_tmpa_tl
   \tl_put_right:No \l_table_tl {\l_tmpa_tl}
   % finally add the table footer in green
   \tl_put_right:Nn \l_table_tl { \rowcolor{LimeGreen} }
   \seq_pop_left:NN \l_invoice_seq \l_tmpa_tl
   \tl_put_right:No \l_table_tl {\l_tmpa_tl}
   % and now print the invoice
   \noindent\invoicetop
   \newline
   \begin{tabularx}{\textwidth}{AABAAC}%\toprule
     \tl_use:N \l_table_tl
   \end{tabularx}
   \newline
   \noindent\invoicebot
}
\cs_generate_variant:Nn \regex_split:nnN {noN}
\ExplSyntaxOff

\arrayrulecolor{blue}

\begin{document}

  \begin{invoice}
    \toprule
     \textbf{Position} & \textbf{Date}        & \textbf{Work~type}  &
     \textbf{Duration} & \textbf{Hourly~rate} & \textbf{Summarized~rate}
     \\
     \midrule
    1 & 05/04/2018 & Cleaning the balcony    & \SI{4}{\hour}   & \SI{10}{\euro\per\hour} & \SI{40}{\euro}  \\
    2 & 05/04/2019 & Mowing the meadow       & \SI{7.5}{\hour} & \SI{10}{\euro\per\hour} & \SI{75}{\euro}  \\
    3 & 05/04/2020 & Planting some flowers   & \SI{5.5}{\hour} & \SI{10}{\euro\per\hour} & \SI{55}{\euro}  \\
    4 & 05/04/2021 & Producing ice cream     & \SI{10.5}{\hour}& \SI{10}{\euro\per\hour} & \SI{105}{\euro} \\
    5 & 05/04/2022 & Cleaning the television & \SI{5.5}{\hour} & \SI{10}{\euro\per\hour} & \SI{55}{\euro}  \\
    6 & 05/04/2023 & Building a pond         & \SI{9}{\hour}   & \SI{10}{\euro\per\hour} & \SI{90}{\euro}  \\
    7 & 05/04/2024 & Feeding the fishes      & \SI{8.5}{\hour} & \SI{10}{\euro\per\hour} & \SI{85}{\euro}  \\
    8 & 05/04/2025 & Cutting the trees       & \SI{7}{\hour}   & \SI{10}{\euro\per\hour} & \SI{70}{\euro}  \\
    9 & 05/04/2026 & Watering the flowers    & \SI{3}{\hour}   & \SI{10}{\euro\per\hour} & \SI{30}{\euro}  \\
    \midrule
      &            &                         &                 &  Summary:               &   \SI{1000}{\euro}  \\
      \bottomrule
  \end{invoice}

\end{document}

我所做的只是用环境替换您的表invoice。此环境使用\regex_split来自LaTeX3将环境内容拆分到 和命令周围\toprule,以访问表头、表尾和表内容。然后,表头和表尾将具有绿色背景,表内容将具有灰色背景。代码包含宏和发票顶部和底部的材料,您应该将其替换为要放在那里的任何内容。\midrule\bottomrule\invoicetop\invoicebot

通过定义一些新的列类型来控制单元格背景:

\newcolumntype{A}{>{\columncolor{Gainsboro}\raggedright}p{22mm}}
\newcolumntype{B}{>{\columncolor{Gainsboro}\raggedright}p{50mm}}
\newcolumntype{C}{>{\columncolor{Gainsboro}}p{30mm}}

我非常喜欢书签包,但我没有用过它,因为它不能很好地处理彩色单元格。此外,代码有点儿像黑客代码,而且比它应该的要难,因为我假设你无法控制由你的“神秘的外部程序”生成的表格的格式。如果你能够自定义此程序的输出,那么宏设计就会变得容易得多。

最后,如果你最终使用类似的东西,那么我会把所有的宏和\usepakage{...}命令放入一个单独的样式文件中,例如invoice.sty,之后你的发票就会变得更易于处理

\documentclass{article}
\usepackage{invoice}

\begin{document}

   \begin{invoice}
      ...
   \end{invoice}

\end{invoice}

当然,如果您可以控制“外部程序”的输出,那么您可以让它将其准确地打印到文件中(并自动为您运行 pdflatex 等)。

答案2

{NiceTabular}有了就很容易了nicematrix

\documentclass[landscape]{article}
\usepackage{geometry}
\geometry{left=1cm,right=1cm}
\usepackage{xcolor}
\usepackage{nicematrix,tikz}

\begin{document}

\begin{center}
\begin{NiceTabular}{*{24}{c}}[first-row,first-col,hvlines,columns-width=auto,name=A]
\CodeBefore
  \arraycolor{lightgray}
\Body
edge & 
0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 & 13 & 14 & 15 & 16 & 17 & 18 & 19 & 21 & 21 & 22 & 23\\
destination & 
\RowStyle{\itshape}
b & d & e & a & c & e & b & e & g & a & e & f & a & b & c & d & f & g & d & e & g & c & e & f \\
weight & 
4 & 12 & 9 &  4 & 8 & 7 & 8 & 5 & 2 & 12 & 3 & 6 & 9 & 7 & 5 & 3 & 1 & 13 & 6 & 1 & 11 & 2 & 13 & 11
\end{NiceTabular}
\end{center}

\vspace{3cm}

\begin{center}
\begin{NiceTabular}{*{7}{c}}[first-col,last-row,hvlines,columns-width=auto,name=B]
\CodeBefore
  \arraycolor{lightgray}
\Body
first edge & 
0 & 3 & 6 & 9 & 12 & 18 & 21\\
outdegree &
3 & 3 & 3 & 3 & 6 & 3 & 3\\
vertex & 
\RowStyle{\itshape}
a & b & c & d & e & f & g\\
\end{NiceTabular}
\end{center}


\tikzset{A/.style = {name prefix = A-} , B/.style = {name prefix = B-}} 

\begin{tikzpicture}[remember picture, overlay]
\draw [A]  (3-|1)  { [B] -- (1-|1) }
           (3-|4)  { [B] -- (1-|2) } 
           (3-|7)  { [B] -- (1-|3) }
           (3-|10) { [B] -- (1-|4) }
           (3-|12) { [B] -- (1-|5) }
           (3-|18) { [B] -- (1-|6) }
           (3-|21) { [B] -- (1-|7) }
           (3-|24) { [B] -- (1-|8) } ;
\end{tikzpicture}

\end{document}

您需要多次编译(因为nicematrix在后台使用 PGF/Tikz 节点)。

上述代码的输出

相关内容