如何在具有居中文本的表格单元格上创建对角线?

如何在具有居中文本的表格单元格上创建对角线?

我已经尝试解决这个问题好几天了。我浏览了这个网站上提出的许多问题,但似乎没有一个能解决我的问题。

基本上,在表格中,我想“削减”一些单元格。这意味着在我想要削减的单元格上创建一条对角线。棘手的部分是我需要将文本置于单元格的中心。我们可以假设单元格的宽度和高度始终相同。

我找到了一个非常接近的解决方案,但只有手动对需要删除的每个单元格的值进行硬编码,才能得到完全正确的结果。我希望有一个更强大的解决方案,无论文本是什么,它都能正常工作。请参阅下面的 MWE:

\documentclass[letterpaper, 12pt]{article}
\usepackage{array}
\usepackage{tikz}

\begin{document}
\begin{table}[!ht] \centering

\renewcommand{\arraystretch}{1.6}

\begin{tabular}{|c|c|c|}
\hline
\tikz[overlay,line width=0.8pt]{\draw (\dimexpr0.1cm-2\tabcolsep-2.5\arrayrulewidth,-0.6em) -- (\dimexpr1.1cm-\tabcolsep-\arrayrulewidth,1em+4.5pt)}AAA & A & AA  \\ 
\hline
\tikz[overlay,line width=0.8pt]{\draw (\dimexpr0.1cm-2\tabcolsep-2.5\arrayrulewidth,-0.6em) -- (\dimexpr1.1cm-\tabcolsep-\arrayrulewidth,1em+4.5pt)}AA & AAA & A  \\ 
\hline
\tikz[overlay,line width=0.8pt]{\draw (\dimexpr0.1cm-2\tabcolsep-2.5\arrayrulewidth,-0.6em) -- (\dimexpr1.1cm-\tabcolsep-\arrayrulewidth,1em+4.5pt)}A & A & AAA\\ 
\hline
\end{tabular}
\end{table}

\end{document}

编辑:我编辑了上述 MWE 以包含多列。

答案1

TikzTab环境将名为 X 的单元格的每个角放在从顶行开始计数的 A、B、... 和从左行开始计数的 n 的tikzmark单元格的每个角上。Xn

在此处输入图片描述

\documentclass[letterpaper, 12pt]{article}
\pagestyle{empty}

\usepackage{tikz,array,xparse,luacode,tabularx}

\usetikzlibrary{tikzmark}
\newcounter{TikzTabCount}

% insert a phantom line (no height) between two real lines
% containing the tikzmarks
\makeatletter
\NewDocumentCommand{\TikzTabEnd}{O{\NbCols}}{%
    \\[-\ht\@arstrutbox]%
    \Row{#1}\stepcounter{TikzTabCount}%
    \\[-\dp\@arstrutbox]}
\makeatother

\ExplSyntaxOn
\NewDocumentCommand{\CountColumns}{m}
 {% count the number of & tokens in \@preamble
  \regex_count:nvN { \cT\& } { @preamble } \l_tmpa_int
  % they're one less than the columns
  \cs_gset:Npx #1 { \int_eval:n { 1 + \l_tmpa_int } }
 }
\cs_generate_variant:Nn \regex_count:nnN { nv }
\ExplSyntaxOff

% #1 is the real environment : tabular, array, tabularx...
% #2 is optional length for tabularx - don't use otherwise
% #3 tabular optional vertical alignment
% #4 columns pattern 
\NewDocumentEnvironment{TikzTab}{md<>O{c}mO{\NbCols}}{%
    \IfNoValueTF{#2}{%
        \setcounter{TikzTabCount}{2}%
        \begin{#1}[#3]{#4}%
        }{%
        \tabularx{#2}[#3]{#4}%
    }%
    \noalign{\CountColumns{#5}\tikzmark[yshift=5pt]{TTtop}}%
}{%
    \IfNoValueTF{#2}{%
        \end{#1}%
        }{%
        \endtabularx%
        }%
    \foreach \i in {0,...,4} {%
        \tikz[overlay,remember picture]
        \tikzmark{A\i}{({pic cs:TTtop}-|{pic cs:B\i})};
    }
}

% Loop creating the tikzmarkz
\newcommand{\Row}[1]{\directlua{row(#1)}}

\begin{luacode}
function row (s)
    a = "\\multicolumn{1}{@{}c@{}}{\\tikzmark{\\Alph{TikzTabCount}0}"
    for i = 1,s-1
    do
    a=a.."\\strut\\hfill\\tikzmark{\\Alph{TikzTabCount}"..i.."}}&\\multicolumn{1}{@{}c@{}}{"
    end
    a=a.."\\strut\\hfill\\tikzmark{\\Alph{TikzTabCount}"..s.."}}"
    tex.print (a)
    --print (a)
end
\end{luacode}


\begin{document}
\begin{table}[!ht] \centering

\renewcommand{\arraystretch}{1.6}

\begin{TikzTab}{tabular}{|c|c|c|}
\hline
AAA & A & AA  \TikzTabEnd
\hline
\rule{0pt}{3em}AA & AAA & A  \TikzTabEnd 
\hline
\rule[-2em]{0pt}{5em}A & A & AAA\TikzTabEnd
\hline
\end{TikzTab}
\end{table}

\tikz[overlay,remember picture]
        \draw (pic cs:B0) -- (pic cs:A1)
        (pic cs:C0) -- (pic cs:B1)
        (pic cs:D0) -- (pic cs:C1) ;

\foreach \j in {A,B,C,D} {%
\foreach \i in {0,...,3} {%
    \tikz[overlay,remember picture]
        \node[red] at (pic cs:\j\i) {\tiny \j\i} ;
}}
\end{document}

答案2

完成修订免责声明: 这是不是旨在与 Tarass 的出色解决方案竞争。相反,它是一种性能较低的替代方案,但不需要 lualatex,这就是我发布它的原因。事实上,除了您已经加载的内容之外,它唯一需要的是 TiZ 库计算。此代码带有一种新的列类型,仅插入 Ti\MeasureLastTable您需要放置的Z 节点和宏表格,您需要在其中指定列数。此宏确定除一个额外的垂直移位之外的所有相关长度:单元格内容未垂直居中,并且根据您的示例,此移位是 2pt。(这个数字似乎来自但我无法以很好的方式提取它。)在“测量”表格后,您可以用其中指定单元格索\abovedisplayskip引的单个单元格划掉,这是一种不言自明的惯例。\CrossOut{x}x

\documentclass[letterpaper, 12pt]{article}
\usepackage{array}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcounter{cellindex}

\newcolumntype{C}{>{\stepcounter{cellindex}%
\begin{tikzpicture}[remember picture,baseline=(Cell-\thecellindex-left.base),inner sep=0pt]
\node (Cell-\thecellindex-left){\strut};
\end{tikzpicture}
}c<{\begin{tikzpicture}[remember picture,baseline=(Cell-\thecellindex-right.base),inner sep=0pt]
\node (Cell-\thecellindex-right){\strut};
\end{tikzpicture}}} 

\newcommand{\MeasureLastTable}[1]{
\pgfmathtruncatemacro{\LeftCellIndex}{\thecellindex-1}
\pgfmathtruncatemacro{\AboveCellIndex}{\thecellindex-#1}
\begin{tikzpicture}[overlay,remember picture]
    \path let \p0 = (Cell-\thecellindex-right.east), 
    \p1 = (Cell-\thecellindex-left.west),
    \p2 = (Cell-\LeftCellIndex-right.east),
    \p3 = (Cell-\LeftCellIndex-left.west) in 
    \pgfextra{\pgfmathsetmacro{\tmp}{(\x0+\x1-\x2-\x3)/4}
    \xdef\HorSep{\tmp pt} % horizontal distance between two cell centers
    };
    \path let \p0 = (Cell-\thecellindex-right.north west), 
    \p1 = (Cell-\thecellindex-left.south west),
    \p2 = (Cell-\AboveCellIndex-right.north west),
    \p3 = (Cell-\AboveCellIndex-left.south west) in 
    \pgfextra{\pgfmathsetmacro{\tmp}{(\y2+\y3-\y0-\y1)/4}
    \xdef\VertSep{\tmp pt} % vertical distance between two cell centers
    }; % I know that in principle two coordinates would be sufficient here
\end{tikzpicture}%
}

\newcommand{\CrossOut}[2][]{
\tikz[overlay,remember picture]{
\path let \p0 = (Cell-#2-left.west), 
    \p1 = (Cell-#2-right.east),
    \p2 = (Cell-#2-left.north west),
    \p3 = (Cell-#2-left.south west) in
    \pgfextra{\pgfmathsetmacro{\tmp}{\HorSep-(\x1-\x0)/2}
    \xdef\myxoffset{\tmp pt}
    \pgfmathsetmacro{\tmp}{\VertSep-(\y2-\y3)/2}
    \xdef\myyoffset{\tmp pt}
    };
\draw[thick,#1] ([xshift=-\myxoffset,yshift=-\myyoffset+2pt]Cell-#2-left.south west) -- 
([xshift=\myxoffset,yshift=\myyoffset+2pt]Cell-#2-right.north east);
}}


\begin{document}
\begin{table}[!ht] \centering

\renewcommand{\arraystretch}{1.6}

\begin{tabular}{|C|C|C|}
\hline
AAA & A & AA  \\ 
\hline
AA & AAA & A  \\ 
\hline
A & A & AAA\\ 
\hline
\end{tabular}
\end{table}
\MeasureLastTable{3} %<- the argument is the number of columns of the last table
\CrossOut{1}
\CrossOut{3}
\CrossOut{5}
\CrossOut{8}
\end{document}

在此处输入图片描述

当然,\CrossOut用其他一些花哨的注释来代替宏也是很简单的。

原始答案:问题在于,您总是可以更改表格尺寸,但在某个时候,您的宏会中断。在这种简单的单列表格情况下,至少可以确保对角线端点的水平位置不必手动调整。垂直位置仍是硬编码的。

\documentclass[letterpaper, 12pt]{article}
\usepackage{array}
\usepackage{tikz}
\newcommand{\tikznode}[2]{\tikz[remember picture,baseline=(#1.base),inner
     sep=0pt]{\node(#1)[inner sep=0pt]{#2};}}
\newcommand{\CrossOut}[2][]{
\tikz[overlay,remember picture]{
\draw[thick,#1] ([yshift=-7pt]#2.south west-|tl.south east) -- 
([yshift=7pt]#2.north east-|br.north west);
}}

\begin{document}
\begin{table}[!ht] \centering

\renewcommand{\arraystretch}{1.6}
\tikznode{tl}{\strut}%
\begin{tabular}{| c |}
\hline
\tikznode{AA1}{AA1}\\
\hline
\tikznode{A2}{A2}\\
\hline
\tikznode{A3}{A3*}\\
\hline
\end{tabular}\tikznode{br}{\strut}
\end{table}
\CrossOut{AA1}\CrossOut{A2}\CrossOut{A3}
\end{document}

在此处输入图片描述

相关内容