表格中的条件水平线

表格中的条件水平线

我正在尝试排版使用该csvsimple包从 CSV 文件中读取的数据。在输入数据中,有一列会告诉我在行之间放置水平线的位置。(在实际数据中,情况会更复杂一些:所有数据行之间都有线,但有些是实线,而其他应该是虚线。)问题是,如果必须放置一条线,则设置列中的指示器多于有问题的那行。我已经尝试让它工作了一段时间了:

\documentclass{article}
\usepackage{filecontents}
\usepackage{csvsimple}
\usepackage{etoolbox}

\begin{filecontents*}{sample.csv}
theline,theflag,thetext
1,X,one
2,,two
3,,three
4,X,four
5,,five
6,X,six
\end{filecontents*}

\begin{document}

\csvreader[%
  head to column names, 
  tabular = {|l|l|},
  table foot = \hline,
]{sample.csv}{}{%
\edef\myflag{\theflag}\ifdefvoid{\myflag}{}{\hline}
\theline & \thetext 
}

\end{document}

如果我将 替换\hline--,我可以看到表达式按预期工作。\hline但是, 因 而失败Misplaced \noalign。据我所知,这是因为我写的东西不是“可扩展的”——我不确定我是否明白它的意思。有没有办法解决这个问题?

答案1

问题的原因在于,在代码中,\\\hline被分开设置(中间有一些处理)。当使用 键时\\, 会自动为 选项设置。late after linetabular

所以,解决办法是直接清除late after line并设置\\\hline

版本 1:

如果您的表格仅通过设置 就在最开始处获得一行X,则可以使用以下代码。此代码包括黑客Peter Grill 去掉了多余的垂直空间:

\documentclass{article}
\usepackage{filecontents}
\usepackage{csvsimple}

\begin{filecontents*}{sample.csv}
theline,theflag,thetext
1,X,one
2,,two
3,,three
4,X,four
5,,five
6,X,six
\end{filecontents*}

\begin{document}

\csvreader[%
  head to column names,
  tabular={|l|l|},
  late after line=,
  table head=\vspace*{-12pt},
  before line=\ifthenelse{\equal{\theflag}{}}{\\}{\\\hline},
  table foot = \\\hline,
]{sample.csv}{}{%
  \theline & \thetext
}

\end{document}

在此处输入图片描述

版本 2:

如果您的表格应该始终在最开始有一行,那么我建议使用以下更简洁的代码:

\documentclass{article}
\usepackage{filecontents}
\usepackage{csvsimple}

\begin{filecontents*}{sample.csv}
theline,theflag,thetext
1,X,one
2,,two
3,,three
4,X,four
5,,five
6,X,six
\end{filecontents*}

\begin{document}

\csvreader[%
  head to column names,
  tabular={|l|l|},
  late after line=,
  table head=\hline,
  before line=\ifthenelse{\equal{\theflag}{}}{\\}{\\\hline},
  before first line=,
  table foot = \\\hline,
]{sample.csv}{}{%
  \theline & \thetext
}

\end{document}

版本 3:

只是为了好玩:以下是一个booktabs解决方案:

\documentclass{article}
\usepackage{filecontents}
\usepackage{csvsimple}
\usepackage{booktabs}

\begin{filecontents*}{sample.csv}
theline,theflag,thetext
1,X,one
2,,two
3,,three
4,X,four
5,,five
6,X,six
\end{filecontents*}

\begin{document}

\csvreader[%
  head to column names,
  tabular={ll},
  late after line=,
  table head=\toprule,
  before line=\ifthenelse{\equal{\theflag}{}}{\\}{\\\midrule},
  before first line=,
  table foot=\\\bottomrule,
]{sample.csv}{}{%
  \theline & \thetext
}

\end{document}

在此处输入图片描述

答案2

一种方法是使用\\\hline。但是这会导致额外的垂直间距,因此您可以黑客通过以下方式\vspace{-12pt}

在此处输入图片描述

但是,你真的需要垂直线吗?使用水平线看起来更好booktabs

在此处输入图片描述

备用: 除了使用,csvsimple您还可以使用datatool下面 MWE 中所示的包。这会产生与上述相同的结果。

代码:

\documentclass{article}
\usepackage{filecontents}
\usepackage{csvsimple}
\usepackage{etoolbox}

\begin{filecontents*}{sample.csv}
theline,theflag,thetext
1,X,one
2,,two
3,,three
4,X,four
5,,five
6,X,six
\end{filecontents*}

\begin{document}

\newcommand*{\OptionalHline}{\edef\myflag{\theflag}\ifdefvoid{\myflag}{}{\vspace{-12pt}\\\hline}}
\csvreader[%
  head to column names, 
  tabular = {| l | l |},
  table foot = \hline,
  before line=\OptionalHline
]{sample.csv}{}{%
\theline & \thetext 
}

\end{document}

代码:booktabs

\documentclass{article}
\usepackage{filecontents}
\usepackage{csvsimple}
\usepackage{etoolbox}
\usepackage{booktabs}

\begin{filecontents*}{sample.csv}
theline,theflag,thetext
1,X,one
2,,two
3,,three
4,X,four
5,,five
6,X,six
\end{filecontents*}

\begin{document}

\newcommand*{\OptionalHline}{\edef\myflag{\theflag}\ifdefvoid{\myflag}{}{\vspace{-12pt}\\\cmidrule{1-2}}}
\csvreader[%
  head to column names, 
  tabular = { l  l },
  table foot = \hline,
  before line=\OptionalHline
]{sample.csv}{}{%
\theline & \thetext 
}
\end{document}

代码:datatool

\documentclass{article}
\usepackage{datatool}
\usepackage{booktabs}
\usepackage{xstring}

%\usepackage{filecontents}% <-- Commented out to prevent overwriting sample.csv
\begin{filecontents*}{sample.csv}
theline,theflag,thetext
1,X,one
2,,two
3,,three
4,X,four
5,,five
6,X,six
\end{filecontents*}


\begin{document}
\DTLloaddb{myDB}{sample.csv}
\bigskip
\begin{tabular}{l l}
    \DTLforeach*{myDB}{\LineNumber=theline,\Flag=theflag,\Text=thetext}{%
        \IfStrEq{\Flag}{X}
            {\DTLiffirstrow{\vspace*{-12pt}}{}\\\cmidrule{1-2}}
            {\DTLiffirstrow{\vspace*{-12pt}}{}\\}%
        \LineNumber & \Text 
    }%
\end{tabular}
\end{document}

相关内容