Digamos que eu tenha uma grande quantidade de linhas de dados estruturadas de forma simples .csv
e essas linhas de dados possam ser divididas em diferentes tipos de dados.
No MWE acabei de adicionar dois tipos ( typA
& typB
).
Caso a linha contenha typA
, a tabela deve ser impressa como está e mostrada no meu resultado.
Caso a linha contenha typB
, esta linha deve ser uma linha de múltiplas colunas onde apenas o conteúdo do Description
campo é impresso no centro.
Como posso conseguir isso com o LaTeX? :)
MWE
\documentclass{article}
\usepackage[a4paper, margin=10mm]{geometry}
\usepackage{pgfplotstable}
\usepackage{mwe}
\pgfplotsset{compat=newest}
\begin{filecontents}{data.csv}
Type, Description, X-Pos, Y-Pos
typA, PowerSupply, 3590, 2000
typA, PowerSupply, 3590, 2500
typB, PowerSupply, 4250, 6070
typA, singleSwitch,5700, 6070
\end{filecontents}
\pgfplotstableread[col sep=comma]{data.csv}{\csvdata}
\pgfplotstablegetrowsof{\csvdata}
\pgfmathtruncatemacro\CSVDataRows{\pgfplotsretval-1}
\begin{document}
\begin{center}
\pgfplotstabletypeset[%
font=\ttfamily,%
col sep=comma,%
columns={Type,Description,X-Pos,Y-Pos},%
columns/Type/.style={%
column name=Type,%
string type%
},%
columns/Description/.style={%
column name=Description,%
string type%
},%
columns/X-Pos/.style={%
column name=X-Pos%
},%
columns/Y-Pos/.style={%
column name=Y-Pos,%
column type/.add={}{|}%
},%
column type/.add={|}{},%
after row={\hline},%
every head row/.style={before row=\hline},
]{\csvdata}%
\end{center}
\end{document}
RESULTADO
RESULTADO ESPERADO
EDITAR
Minha ideia é adicionar algo assim:
every column/.style={%
assign cell content/.code={%
\pgfplotstablegetelem{\pgfplotstablerow}{Type}\of{\csvdata}
\ifthenelse{\equal{\pgfplotsretval}{typB}}{%
\ifthenelse{\equal{\pgfplotstablecol}{2}}{%=> Just do this once!
\pgfkeyssetvalue{/pgfplots/table/@cell content}{\multicolumn{2}{c|}{Content Description}\\\hline}
}{}
}{}
},
},
Segundo MWE
\documentclass{standalone}
\usepackage{pgfplotstable}
\usepackage{ifthen}
\pgfplotsset{compat=newest}
\begin{filecontents}{data.csv}
Type, Description, X-Pos, Y-Pos
typA, PowerSupply, 3590, 2000
typA, PowerSupply, 3590, 2500
typB, PowerSupply, 4250, 6070
typA, singleSwitch,5700, 6070
\end{filecontents}
\pgfplotstableread[col sep=comma]{data.csv}{\csvdata}
\pgfplotstablegetrowsof{\csvdata}
\pgfmathtruncatemacro\CSVDataRows{\pgfplotsretval-1}
\begin{document}
\pgfplotstabletypeset[%
font=\ttfamily,%
col sep=comma,%
columns={Type,Description,X-Pos,Y-Pos},%
columns/Type/.style={%
column name=Type,%
string type%
},%
every column/.style={%
assign cell content/.code={%
\pgfplotstablegetelem{\pgfplotstablerow}{Type}\of{\csvdata}
\ifthenelse{\equal{\pgfplotsretval}{typB}}{%
\ifthenelse{\equal{\pgfplotstablecol}{2}}{%=> Just do this once!
\pgfkeyssetvalue{/pgfplots/table/@cell content}{\multicolumn{2}{c|}{Content Description}\\\hline}
}{}
}{}
},
},
columns/Description/.style={%
column name=Description,%
string type%
},%
columns/X-Pos/.style={%
column name=X-Pos%
},%
columns/Y-Pos/.style={%
column name=Y-Pos,%
column type/.add={}{|}%
},%
column type/.add={|}{},%
after row={\hline},%
every head row/.style={before row=\hline},
]{\csvdata}%
\end{document}
RESULTADO
Mas como posso conseguir
- Uma multicoluna começando na primeira coluna
- Suprima a segunda linha com as informações Y-Pos
- Substitua
Content Description
pelo conteúdo real da descrição, neste casoPowerSupply
?
Responder1
Uma solução poderia csvsimple-l3
ser tabularray
aceitável para você?
\documentclass{article}
\usepackage[a4paper, margin=10mm]{geometry}
\usepackage{csvsimple-l3}
\usepackage{tabularray}
\UseTblrLibrary{siunitx}
\sisetup{
group-digits=integer,
group-minimum-digits={3},
group-separator={,}
}
\begin{filecontents*}{data.csv}
Type, Description, X-Pos, Y-Pos
typA, PowerSupply, 3590, 2000
typA, PowerSupply, 3590, 2500
typB, PowerSupply, 4250, 6070
typA, singleSwitch,5700, 6070
\end{filecontents*}
\begin{document}
\csvreader[no head,
centered tabularray =
{
colspec={cc*2{S[table-format=4]}},
columns={font=\ttfamily},
hlines,
vlines,
},
]{data.csv}{}{%
\ifcsvfirstrow{% header
\csvcoli & \csvcolii
& {{{\csvcoliii}}}
& {{{\csvcoliv}}}
}{% rows
\IfCsvsimStrEqualTF{\csvcoli}{typB}{% multicolumn
\SetCell[c=4]{c}\csvcolii&&&}{% other rows
\csvcoli & \csvcolii
& \csvcoliii
& \csvcoliv}
}
}
\end{document}
Você também pode usar csvsimple-l3
com uma tabular
5ª coluna fictícia comum, mas com um truque, para evitar problemas com o siunitx
tipo de coluna na última coluna:
\documentclass{article}
\usepackage[a4paper, margin=10mm]{geometry}
\usepackage{csvsimple-l3}
\usepackage{array}
\renewcommand{\arraystretch}{1.3}
\usepackage{siunitx}
\sisetup{
group-digits=integer,
group-minimum-digits={3},
group-separator={,},
table-number-alignment=center
}
\begin{filecontents*}{data.csv}
Type, Description, X-Pos, Y-Pos
typA, PowerSupply, 3590, 2000
typA, PowerSupply, 3590, 2500
typB, PowerSupply, 4250, 6070
typA, singleSwitch,5700, 6070
\end{filecontents*}
\begin{document}
\csvreader[
head to column names,
before reading = {\begin{center}\ttfamily},
tabular = {|c|c|S[table-format=4]|S[table-format=4]@{}c|},% the last dummy column is necessary
% due to csvreader-l3 problems, see documentation, Section 7.4 Tables with Number Formatting
table head = {\hline Type & Description & {X-Pos} & {Y-Pos}&\\\hline},
late after line = \\\hline,
after reading = \end{center}
]{data.csv}{}{%
\IfCsvsimStrEqualTF{\csvcoli}{typB}{% multicolumn
\multicolumn{5}{|c|}{\csvcolii}
}{% other rows
\csvcoli & \csvcolii
& \csvcoliii
& \csvcoliv &
}
}
\end{document}
NB = A macro \IfCsvsimStrEqualTF
é bastante recente. Se sua distribuição não estiver atualizada, use \ifcsvstrcmp
. Nos dois exemplos acima, o resultado não muda com a macro antiga.
Responder2
Aqui está uma solução para usuários OpTeX:
\createfile {data.csv}
Type, Description, X-Pos, Y-Pos
typA, PowerSupply, 3590, 2000
typA, PowerSupply, 3590, 2500
typB, PowerSupply, 4250, 6070
typA, singleSwitch,5700, 6070
\endfile
\def\p #1,#2,#3,#4#5 {%
\ifx^#1^\else
\isequal{typB}{#1}
\iftrue
\mspan4[|c|]{#2} \crl
\else
#1 & #2 & #3 & #4#5 \crl
\fi
\ea\p
\fi
}
{\everyeof{,,,{} }
\table{|c|c|c|c|}{\crl
\ea\p\input data.csv
}}
\bye