数据工具,每个表行有两行数据库行,垂直排序

数据工具,每个表行有两行数据库行,垂直排序

因此,搜索了几个小时后,我很惊讶没有找到任何有用的解决方案。

我使用 导入 CSV 表datatool。该表仅包含 3 个窄列,但我得到了很多行。我按照文档中的示例将两行放在一个表行中并排显示。

到目前为止,一切正常,但不幸的是,值是从左到右读取的,而不是从左侧从上到下读取,然后从右半部分从上到下读取。

让我说明一下我的问题:

|---|---|---|---|
| # |foo| # |foo|
|===|===|===|===|
| 1 |abc| 2 |def|
| 3 |ghi| 4 |jkl|
| 5 |mno| 6 |pqr|
|---|---|---|---|

这就是按照文档(示例 8,第 47 页)现在的情况datatool.pdf)。

我想要的是

|---|---|---|---|
| # |foo| # |foo|
|===|===|===|===|
| 1 |abc| 4 |jkl|
| 2 |def| 5 |mno|
| 3 |ghi| 6 |pqr|
|---|---|---|---|

是否有机会修改该示例以提供像那样的输出?

最小示例

\documentclass[a4paper]{article}
\usepackage{datatool}

\begin{document}

\DTLsetseparator{;}
\DTLloaddb[noheader,keys={id,item}]{test_db}{test.csv}


\begin{table}[htbp]
    \caption{Two database rows per tabular row}
    \centering
    \begin{tabular}{cc|cc}
    \bfseries ID &
    \bfseries Item &
    \bfseries ID &
    \bfseries Item
    \DTLforeach*{test_db}{\id=id,\item=item}{%
        \DTLifoddrow{\\}{&}%
        \id & \item}%
    \end{tabular}
\end{table}
\end{document}

充满test.csv以下内容

1;abc
2;def
3;ghi
4;jkl
5;mno
6;pqr

答案1

在此处输入图片描述

\documentclass[a4paper]{article}
\usepackage{datatool}

\begin{document}

\DTLsetseparator{;}
\DTLloaddb[noheader,keys={id,item}]{test_db}{test.csv}



\begin{table}[htbp]
   \count2=\DTLrowcount{test_db}
   \count4 = \count2
   \divide\count4 by 2
   \count2=\count4
   \advance\count2 by 1

    \caption{Two database rows per tabular row}
    \centering
    \begin{tabular}{cc|cc}
    \bfseries ID &
    \bfseries Item &
    \bfseries ID &
    \bfseries Item
    \DTLforeach*[\id<\count2]{test_db}{\id=id,\item=item}{%
       \\
        \id & \item
   \count0=\id
   \advance\count0 by \count4
    \DTLforeach*[\id=\count0]{test_db}{\id=id,\item=item}{%
      &\id &\item}
}
    \end{tabular}
\end{table}
\end{document}

答案2

奇数行的表

在 David Carlisle 的帮助下,我成功解决了这个问题。我稍微修改了他的代码,使其也支持 CSV 文件中奇数行。我的修改可能不是最好的方法,但我才刚刚开始使用 LaTeX,它与我习惯的编程方式完全不同。

\documentclass[a4paper]{article}
\usepackage{datatool}

\begin{document}

\DTLsetseparator{;}
\DTLloaddb[noheader,keys={id,item}]{test_db}{test.csv}

\DTLrowcount{test_db}

\begin{table}[htbp]
   \count2=\DTLrowcount{test_db}
   \count4 = \count2
   \divide\count4 by 2
   \count2=\count4

    %%% modification start
    \count10=\count2
    \advance\count10 by \count4

    \ifnum\count10=\DTLrowcount{test_db}
        %even number of entries 
        \advance\count2 by 1
    \else
        %odd number of entries
        \advance\count2 by 2
        \advance\count4 by 1
    \fi
    %%% modification end

    \caption{Two database rows per tabular row}
    \centering
    \begin{tabular}{cc|cc}
    \bfseries ID &
    \bfseries Item &
    \bfseries ID &
    \bfseries Item
    \DTLforeach*[\id<\count2]{test_db}{\id=id,\item=item}{%
       \\
        \id & \item
   \count0=\id
   \advance\count0 by \count4
    \DTLforeach*[\id=\count0]{test_db}{\id=id,\item=item}{%
      &\id &\item}
}
    \end{tabular}
\end{table}
\end{document}

答案3

这里有一个替代方法,它更有效,因为它只使用简单\loop而不是嵌套的实例\DTLforeach*

\documentclass[a4paper]{article}
\usepackage{datatool}

\begin{document}

\DTLsetseparator{;}
\DTLloaddb[noheader,keys={id,item}]{test_db}{test.csv}
\newcount\mididx
\mididx=\numexpr\DTLrowcount{test_db}/2\relax

\begin{table}[htbp]
  \caption{Two database rows per tabular row}
  \centering
  \newcommand\tabcontents{\bfseries ID & \bfseries Item & 
  \bfseries ID & \bfseries Item}%
  \count2=0\relax
  \loop
  \advance\count2 by 1\relax
  \DTLassign{test_db}{\count2}{\Id=id,\Item=item}%
  \eappto\tabcontents{\noexpand\\\expandonce\Id \noexpand & \expandonce\Item}%
  \count4=\numexpr\count2+\mididx\relax
  \ifnum\count4>\DTLrowcount{test_db}
  \else
    \DTLassign{test_db}{\count4}{\Id=id,\Item=item}%
    \eappto\tabcontents{\noexpand& \expandonce\Id \noexpand& \expandonce\Item}%
  \fi
  \ifnum\count2<\mididx
  \repeat
  \begin{tabular}{cc|cc}
  \tabcontents
  \end{tabular}
\end{table}
\end{document}

文件图像

为了避免在表格上下文中循环的复杂性,这用于\loop构造一个控制序列(\tabcontents)来包含表格内容,然后将其放置\tabcontentstabular环境中。(\eappto由 提供etoolbox,由 自动加载datatool。)

相关内容