我正在尝试排版使用该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 line
tabular
所以,解决办法是直接清除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}