数据数量可变时来自文件的数据

数据数量可变时来自文件的数据

我正在使用 datatool 包将数据从 csv 获取到 LaTeX pdf 页面:

\documentclass{article}
\usepackage{datatool}
\begin{document}

\DTLloaddb{data}{students.csv}

\DTLforeach{data}
{\student=Name,\pointsa=Pointsa,\pointsb=Pointsb}
{\newpage 
   Student: \student\\
   Points exercise A: \pointsa\\
   Points exercise B: \pointsb
}
\end{document}

由于我的练习数量并不总是相同,因此我希望有一个模板可以仅根据 csv(基于该 csv 中的点数)自动适应练习数量。

在常规编程语言中,我会将“点”制成一个数组,并循环箭头来创建所有练习的点。

我如何实现此功能(练习数量可变但模板固定)?我可以看到两个解决方案,但不知道如何实现它们,或者是否有可能:

  • 在 csv 中有一个包含点的数组(这可能吗?)
  • 将所有点放在 csv 中的行尾,并获取点直到 EOL

我将非常感激任何关于如何解决这个问题的提示。如果有必要,我也可以使用另一个包。

答案1

我不知道您的数据是什么样的,甚至不确定我是否正确理解了您想要实现的目标,但也许您可以从这样简单的事情开始(但是,此解决方案不允许任意数量的列):

\documentclass{article}
\usepackage{datatool}

\begin{filecontents}[noheader]{students.csv}
Name,      PointsA, PointsB, PointsC, PointsD
Student A, 10,      11,      12,      13
Student B,   ,      15,        ,      17
\end{filecontents}

\begin{document}

\DTLloaddb{data}{students.csv}

\DTLforeach{data}
{\student=Name,\pointsa=PointsA,\pointsb=PointsB,\pointsc=PointsC,\pointsd=PointsD}
{
    \begin{tabular}{ll} 
        Student: & \student \\
        \ifx\pointsa\empty\else Points exercise A: & \pointsa \\ \fi
        \ifx\pointsb\empty\else Points exercise B: & \pointsb \\ \fi
        \ifx\pointsc\empty\else Points exercise C: & \pointsc \\ \fi
        \ifx\pointsd\empty\else Points exercise D: & \pointsd \\ \fi
    \end{tabular}
    
    \bigskip
}
\end{document}

在此处输入图片描述


在第二次阅读您的问题后,我假设您的数据存储在一个或多个 CSV 文件中,其中第一列是某种标识符(学生姓名),其余可以是包含整数值(或类似内容)的任意数量的列。

因此,我想出了利用该pgfplotstable包的替代方法。此解决方案接受具有任意列数的 CSV 文件。第一列应包含学生姓名,接下来的列应包含各种考试的分数。此解决方案自动将考试名称设置为 A、B、C 等:

\documentclass{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.18}

\begin{filecontents}{studentsA.csv}
Name,      PointsA, PointsB, PointsC, PointsD
Student A, 10,      11,      12,      13
Student B,   ,      15,        ,      17
\end{filecontents}

\begin{filecontents}{studentsB.csv}
Name,      PointsA, PointsB, PointsC, PointsD, PointsE, PointsF
Student C, 10,      11,      12,      13,      14,      
Student D,   ,      15,        ,      17,      18,      19
\end{filecontents}

\ExplSyntaxOn

\tl_new:N \l_studentstable_datarows_tl
\tl_new:N \l_studentstable_datacols_tl
\str_new:N \l_studentstable_currentstudent_str
\str_new:N \l_studentstable_tempexercise_str
\tl_new:N \l_studentstable_currentpointslist_tl
\NewDocumentCommand { \printStudentsTable } { m } {
    \pgfplotstableread[col~sep=comma]{#1}{\studentsdata}

    \pgfplotstablegetrowsof{\studentsdata}
    \pgfmathsetmacro{\l_studentstable_datarows_tl}{\pgfplotsretval-1}
    
    \pgfplotstablegetcolsof{\studentsdata}
    \pgfmathsetmacro{\l_studentstable_datacols_tl}{\pgfplotsretval-1}

    \foreach \i in {0,...,\l_studentstable_datarows_tl} {
        \pgfplotstablegetelem{\i}{[index]0}\of{\studentsdata}
        \str_set:Nx \l_studentstable_currentstudent_str { \pgfplotsretval }

        \str_clear:N \l_studentstable_currentpointslist_tl
        \foreach \j in {1,...,\l_studentstable_datacols_tl} {
            \pgfplotstablegetelem{\i}{[index]\j}\of{\studentsdata}
            \str_set:Nx \l_studentstable_tempexercise_str {
                \str_uppercase:f { \int_to_alph:n { \j } }
            }
            \tl_gput_right:Nx \l_studentstable_currentpointslist_tl { 
                \str_if_empty:NTF \pgfplotsretval { } {
                    Points~exercise~\l_studentstable_tempexercise_str \c_colon_str &
                    \pgfplotsretval \\
                }

            }
        }

        \begin{tabular}{ l l } 
            Student: & \l_studentstable_currentstudent_str \\
            \l_studentstable_currentpointslist_tl
        \end{tabular}
        \par
        \bigskip
        \par
    }
}

\ExplSyntaxOff

\begin{document}

\printStudentsTable{studentsA.csv}

\printStudentsTable{studentsB.csv}

\end{document}

在此处输入图片描述

如果要打印考试描述,可以调整代码如下:

\documentclass{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.18}

\begin{filecontents}{studentsC.csv}
Name,      Exam A, Exam B, Test C
Student C, 10,     11,     12 
Student D,   ,     15,       
\end{filecontents}

\ExplSyntaxOn

\tl_new:N \l_studentstable_datarows_tl
\tl_new:N \l_studentstable_datacols_tl
\str_new:N \l_studentstable_currentstudent_str
\str_new:N \l_studentstable_tempexercise_str
\tl_new:N \l_studentstable_currentpointslist_tl
\NewDocumentCommand { \printStudentsTable } { m } {
    \pgfplotstableread[col~sep=comma]{#1}{\studentsdata}

    \pgfplotstablegetrowsof{\studentsdata}
    \pgfmathsetmacro{\l_studentstable_datarows_tl}{\pgfplotsretval-1}
    
    \pgfplotstablegetcolsof{\studentsdata}
    \pgfmathsetmacro{\l_studentstable_datacols_tl}{\pgfplotsretval-1}

    \foreach \i in {0,...,\l_studentstable_datarows_tl} {
        \pgfplotstablegetelem{\i}{[index]0}\of{\studentsdata}
        \str_set:Nx \l_studentstable_currentstudent_str { \pgfplotsretval }

        \str_clear:N \l_studentstable_currentpointslist_tl
        \foreach \j in {1,...,\l_studentstable_datacols_tl} {
            \pgfplotstablegetcolumnnamebyindex{\j}\of{\studentsdata}
                \to\pgfplotsretval
            \str_set:Nx \l_studentstable_tempexercise_str {
                \pgfplotsretval
            }
            \pgfplotstablegetelem{\i}{[index]\j}\of{\studentsdata}
            \tl_gput_right:Nx \l_studentstable_currentpointslist_tl { 
                \str_if_empty:NTF \pgfplotsretval { } {
                    Points~\l_studentstable_tempexercise_str \c_colon_str &
                    \pgfplotsretval \\
                }

            }
        }

        \begin{tabular}{ l l } 
            Student: & \l_studentstable_currentstudent_str \\
            \l_studentstable_currentpointslist_tl
        \end{tabular}
        \par
        \bigskip
        \par
    }
}

\ExplSyntaxOff

\begin{document}

\printStudentsTable{studentsC.csv}

\end{document}

在此处输入图片描述

相关内容