从 csv 输入特定元素

从 csv 输入特定元素

我有一个 csv 表,我想输入特定单元格。例如,我的 csv 是 project.csv:

       , obj, resources, wp
task1.1, 1  ,   2k     , 1
task2.1, 2  ,   3k     , 2 
task3.1, 3  ,   4k     , 3

理想情况下,我希望从中输入特定元素,例如通过其列和行名称引用它。例如:

Resources for the first task from Work Package \input{project.csv[task1.1, wp]} are \input{project.csv[task1.1, resources]} USD 

答案1

使用datatool's\DTLfetch{<db name>}{<source col>}{<source val>}{<target col>}返回与<target col>其中<source col>关联<source val>的值<db name>(它的作用类似于查找表)。

在此处输入图片描述

\documentclass{article}

\begin{filecontents*}[overwrite]{tasks.csv}
task,obj,resources,wp
task1.1,1,2k,1
task2.1,2,3k,2 
task3.1,3,4k,3
\end{filecontents*}

\usepackage{datatool}

\begin{document}

% Load the database; later referenced as tasks
\DTLloaddb
  [keys={task,obj,resources,wp}]% <options>
  {tasks}% <db name>
  {tasks.csv}% <filename>

Resources for the first task from Work Package 
\DTLfetch{tasks}{task}{task1.1}{wp} %\input{project.csv[task1.1, wp]} 
are 
\DTLfetch{tasks}{task}{task1.1}{resources} %\input{project.csv[task1.1, resources]} 
USD.

\end{document}

请注意,CSV 文件中的空格会被返回,因此这取决于您如何管理输出中的空格(来自\DTLfetch)。我已删除它们,因为典型的 CSV 导出会排除它们。

答案2

以下是expl3从头开始的实现。使用

\ReadCSV { <filename> } \command

.csv文件读取到<filename>,并将其存储在 中以供使用\command,然后使用:

\command{<row>,<column>}

获取与<row>和对应的项目<column>(通过名称访问)。

\command是可扩展的,因此您可以安全地在标题、章节标题等中使用它。

此外,您还可以使用

\IterateCSVRows \command {<code>}
% and
\IterateCSVCols \command {<code>}

迭代读取的 CSV 文件的行和列。在 中<code>#1是当前迭代的行或列名称,因此您可以在 中使用\command{#1,col}或。如果嵌套两者,则内部命令必须使用来表示行或列名称。下面的示例显示了如何使用这些命令将 重建为表格。\command{row,#1}<code>##1.csv

\documentclass{article}
\begin{filecontents*}[overwrite]{project.csv}
task   , obj, resources, wp
task1.1, 1  ,   2k     , 1
task2.1, 2  ,   3k     , 2
task3.1, 3  ,   4k     , 3
\end{filecontents*}
\ExplSyntaxOn
\tl_new:N \l__augusto_tmpa_tl
\tl_new:N \l__augusto_csv_name_tl
\ior_new:N \l__augusto_csv_ior
\seq_new:N \l__augusto_tmpa_seq
\int_new:N \l__augusto_csv_rows_int
\bool_new:N \l__augusto_csv_read_as_string_bool
\cs_generate_variant:Nn \seq_set_from_clist:Nn { NV }
\cs_generate_variant:Nn \prop_put_if_new:Nnn { cVx }
\cs_new_protected:Npn \augusto_read_csv:NnN #1 #2 #3
  {
    \bool_set_eq:NN \l__augusto_csv_read_as_string_bool #1
    \ior_open:NnTF \l__augusto_csv_ior {#2}
      {
        \cs_if_exist:NTF #3
          { \msg_error:nnn { augusto } { command-exists } {#3} }
          { \exp_args:Nf \__augusto_read_csv:nN { \cs_to_str:N #3 } #3 }
      }
      { \msg_error:nnn { augusto } { file-not-found } {#2} }
  }
\msg_new:nnn { augusto } { file-not-found }
  { File~'#1'~not~found. }
\msg_new:nnn { augusto } { command-exists }
  { Command~'#1'~already~defined. }
\cs_new_protected:Npn \__augusto_read_csv:nN #1 #2
  {
    \NewExpandableDocumentCommand #2 { m }
      { \__augusto_get_csv_item:nn {##1} {#1} }
    \tl_set:Nn \l__augusto_csv_name_tl {#1}
    \bool_if:NTF \l__augusto_csv_read_as_string_bool
      { \ior_str_get:NN } { \ior_get:NN }
          \l__augusto_csv_ior \l__augusto_tmpa_tl
    \seq_set_from_clist:NV \l__augusto_tmpa_seq \l__augusto_tmpa_tl
    \seq_pop:NN \l__augusto_tmpa_seq \l__augusto_tmpa_tl
    \seq_new:c { g__augusto_csv_#1_cols_seq }
    \seq_map_inline:Nn \l__augusto_tmpa_seq
      {
        \seq_new:c { g__augusto_csv_#1_##1_seq }
        \seq_gput_right:cn { g__augusto_csv_#1_cols_seq } {##1}
      }
    \prop_new:c { g__augusto_csv_#1_rows_prop }
    \int_zero:N \l__augusto_csv_rows_int
    \bool_if:NTF \l__augusto_csv_read_as_string_bool
      { \ior_str_map_inline:Nn } { \ior_map_inline:Nn }
          \l__augusto_csv_ior
        {
          \int_incr:N \l__augusto_csv_rows_int
          \seq_set_split:Nnn \l__augusto_tmpa_seq { , } {##1}
          \seq_pop:NN \l__augusto_tmpa_seq \l__augusto_tmpa_tl
          \prop_put_if_new:cVx { g__augusto_csv_#1_rows_prop }
            \l__augusto_tmpa_tl { \int_use:N \l__augusto_csv_rows_int }
          \seq_mapthread_function:cNN
            { g__augusto_csv_#1_cols_seq } \l__augusto_tmpa_seq
            \__augusto_add_csv_row:nn
        }
  }
\cs_new_protected:Npn \augusto_map_csv_rows:Nn #1 #2
  { \prop_map_inline:cn { g__augusto_csv_ \cs_to_str:N #1 _rows_prop } {#2} }
\cs_new_protected:Npn \augusto_map_csv_cols:Nn #1 #2
  { \seq_map_inline:cn { g__augusto_csv_ \cs_to_str:N #1 _cols_seq } {#2} }
\cs_new_protected:Npn \__augusto_add_csv_row:nn #1 #2
  {
    \seq_gput_right:cn
      { g__augusto_csv_ \l__augusto_csv_name_tl _#1_seq }
      {#2}
  }
\cs_new:Npn \__augusto_get_csv_item:nn #1
  { \__augusto_get_csv_item:wn #1 , \q_nil , \s_stop }
\cs_new:Npn \__augusto_get_csv_item:wn #1 , #2 , #3 \s_stop #4
  {
    \quark_if_nil:nTF {#2}
      { \msg_expandable_error:nnn { augusto } { invalid-item } {#4} }
      {
        \exp_args:Nff \__augusto_get_item:nnn
          { \tl_trim_spaces:n {#1} } { \tl_trim_spaces:n {#2} } {#4}
      }
  }
\cs_new:Npn \__augusto_get_item:nnn #1 #2 #3
  {
    \exp_args:Ncc \__augusto_get_item:NNnn
      { g__augusto_csv_#3_#2_seq } { g__augusto_csv_#3_rows_prop }
      {#1} {#2}
  }
\cs_new:Npn \__augusto_get_item:NNnn #1 #2 #3 #4
  {
    \seq_if_exist:NTF #1
      {
        \prop_if_in:NnTF #2 {#3}
          { \seq_item:Nn #1 { \prop_item:Nn #2 {#3} } }
          { \use_ii:nn }
      }
      { \use_ii:nn }
    \use_none:n
      {
        \msg_expandable_error:nnn
          { augusto } { invalid-item } {#3,#4}
      }
  }
\msg_new:nnn { augusto } { invalid-item }
  { Invalid~item~'#1'. }
\NewDocumentCommand \ReadCSV { s m m }
  {
    \IfBooleanTF {#1}
      { \augusto_read_csv:NnN \c_true_bool }
      { \augusto_read_csv:NnN \c_false_bool }
        {#2} #3
  }
\NewDocumentCommand \IterateCSVRows { m +m }
  { \augusto_map_csv_rows:Nn #1 {#2} }
\NewDocumentCommand \IterateCSVCols { m +m }
  { \augusto_map_csv_cols:Nn #1 {#2} }
\ExplSyntaxOff
\begin{document}

\ReadCSV{project.csv}\project

Resources for the first task from Work Package \project{task1.1, wp}
are \project{task1.1, resources} USD

\begin{tabular}{*4c}
\IterateCSVCols \project { & #1 } \\
\IterateCSVRows \project
  {%
    #1
    \IterateCSVCols \project
      { & \project{#1,##1} }
    \\
  }
\end{tabular}

\end{document}

相关内容