Допустим, у меня есть огромное количество строк данных, структурированных простым образом, .csv
и эти строки данных можно разделить на различные типы данных.
В MWE я просто добавил два типа ( typA
& typB
).
В случае, если строка содержит typA
, таблица должна быть выведена как есть и отображена в моем результате.
В случае, если строка содержит typB
, эта строка должна быть многостолбцовой, где Description
в центре печатается только содержимое поля.
Как этого добиться с помощью LaTeX? :)
МВЭ
\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}
РЕЗУЛЬТАТ
ОЖИДАЕМЫЙ РЕЗУЛЬТАТ
РЕДАКТИРОВАТЬ
Моя идея — добавить что-то вроде этого:
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}
}{}
}{}
},
},
Второй МВЭ
\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}
РЕЗУЛЬТАТ
Но как я могу получить
- Многоколоночный, начинающийся с первого столбца
- Подавить вторую строку с информацией Y-Pos
- Заменить
Content Description
реальным содержанием описания, в данном случаеPowerSupply
?
решение1
Может ли решение с csvsimple-l3
и tabularray
быть для вас приемлемым?
\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}
Вы также можете использовать csvsimple-l3
с обычным tabular
, но с трюком, пятым фиктивным столбцом, чтобы избежать проблем с siunitx
типом столбца в последнем столбце:
\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 = Макрос \IfCsvsimStrEqualTF
довольно новый. Если ваш дистрибутив не обновлен, используйте \ifcsvstrcmp
вместо него. В обоих примерах выше результат не меняется со старым макросом.
решение2
Вот решение для пользователей 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