具有完整突出显示背景的表格

具有完整突出显示背景的表格

我怎样才能让表格的背景像下面这样突出显示?(最好不使用 Tikz 包)

在此处输入图片描述

答案1

如果您只需要执行一次,那么有一个可能的解决方案:

\documentclass{article}
\usepackage{xcolor}
\pagestyle{empty}
\begin{document}

Content outside of the box

\begin{table}
    \colorbox{blue!20}{%
    \begin{minipage}{3.25in}%
        \stepcounter{table}
        \textbf{Table \thetable}\hspace*{1em}{\sffamily Hello World\ldots}\par
        \begin{tabular}{|c|c|c|c|c|c|}\hline
            & \multicolumn{3}{c}{Year} \\\cline{2-6}%'
             & 2006  & 2007  & 2008  & 2009  & 2010 \\\cline{2-6}
        tech & 78 nm & 68 nm & 59 nm & 52 nm &  45 nm \\\hline%'
        \end{tabular}
        \addcontentsline{lot}{table}{Hello World}
    \end{minipage}}
\end{table}

\begin{table}
\caption{Hello Moon}

\end{table}

Content outside of the box

\end{document}

我没有在 中调用 caption minipage。最后,如果您正在构建目录,则需要类似的东西\addcontentsline来显示表格。我很少构建目录。我不太确定如何让这个精心设计的表格正确显示出来。

在此处输入图片描述

因为这似乎是需要重复做的事情,所以我创建了一个环境。

\documentclass{article}
\usepackage{xcolor}
\pagestyle{empty}
\newsavebox{\mytablebox}
\newenvironment{mytable}[2]{%
        \begin{table}%
        \begin{lrbox}{\mytablebox}%
        \stepcounter{table}%
        \begin{minipage}{#2}%
        \textbf{Table \thetable}\hspace*{1em}{\sffamily #1}\par%
        \addcontentsline{lot}{table}{#1}%
    }
    {\end{minipage}%
     \end{lrbox}%
     \colorbox{blue!20}{\usebox{\mytablebox}}
     \end{table}}


\begin{document}

Content outside of the box

\begin{mytable}{Hello New World}{3.25in}
        \begin{tabular}{|c|c|c|c|c|c|}\hline
            & \multicolumn{3}{c}{Year} \\\cline{2-6}%'
             & 2006  & 2007  & 2008  & 2009  & 2010 \\\cline{2-6}
        tech & 78 nm & 68 nm & 59 nm & 52 nm &  45 nm \\\hline%'
        \end{tabular}
\end{mytable}

\begin{mytable}{Hello Moon}{2in}
  Contents of my table
\end{mytable}

Content outside of the box

\end{document}

在此处输入图片描述

\caption在这个最后示例中,我从环境内部调用。您可能需要进行一些调整才能使标题按您想要的方式显示。但至少这样您可能不必为 而烦恼\addcontentsline。在这里我重置了abovecaptionskip。这似乎有点残酷。可能应该用胶水粘在那里。

\documentclass{article}
\usepackage{xcolor}
\pagestyle{empty}
\newsavebox{\mytablebox}
\setlength{\abovecaptionskip}{0pt}
\newenvironment{mytable}[2]{%
        \begin{table}%
        \begin{lrbox}{\mytablebox}%
        \begin{minipage}{#2}%
        \caption{#1}%
    }
    {\end{minipage}%
     \end{lrbox}%
     \colorbox{blue!20}{\usebox{\mytablebox}}
     \end{table}}


\begin{document}

Content outside of the box

\begin{mytable}{Hello New World}{3.25in}
        \begin{tabular}{|c|c|c|c|c|c|}\hline
            & \multicolumn{3}{c}{Year} \\\cline{2-6}%'
             & 2006  & 2007  & 2008  & 2009  & 2010 \\\cline{2-6}
        tech & 78 nm & 68 nm & 59 nm & 52 nm &  45 nm \\\hline%'
        \end{tabular}
\end{mytable}

\begin{mytable}{Hello Moon}{2in}
  Contents of my table
\end{mytable}

Content outside of the box

\end{document}

在此处输入图片描述

答案2

这是一个使用标准table环境和\caption命令的可能解决方案,可以自动计算彩色背景的适当尺寸;我知道摇头说“最好不要 TikZ”,但我找不到其他方法(代码至少需要运行三次才能稳定):

\documentclass{article}
\usepackage[paperheight=44\baselineskip,paperwidth=15cm]{geometry}
\usepackage{xcolor}
\usepackage{caption}
\usepackage{booktabs}
\usepackage{tikz}
\usetikzlibrary{calc,shadings}

% Andrew Stacey's code from
% http://tex.stackexchange.com/a/50054/3954
\makeatletter
\tikzset{%
  remember picture with id/.style={%
    remember picture,
    overlay,
    save picture id=#1,
  },
  save picture id/.code={%
    \edef\pgf@temp{#1}%
    \immediate\write\pgfutil@auxout{%
      \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
  },
  if picture id/.code args={#1#2#3}{%
    \@ifundefined{save@pt@#1}{%
      \pgfkeysalso{#3}%
    }{
      \pgfkeysalso{#2}%
    }
  }
}

\def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}

\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,(0pt,0pt)\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] {#1;}}
% end of Andrew's code

\newcommand{\gettikzxy}[3]{%
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
  \edef#2{\the\pgf@x}%
  \edef#3{\the\pgf@y}%
}
\makeatother

\newcommand\minx{}

\newcommand\shadetable[4][blue]{%
  \begin{tikzpicture}[overlay,remember picture]%
    \gettikzxy{(pic cs:#2)}{\auxi}{\auyi}
    \gettikzxy{(pic cs:#4)}{\auxii}{\auyii}
    \edef\maxx{0pt}
    \ifdim\auxii<\auxi 
      \edef\minx{\auxii}
    \else
      \edef\minx{\the\dimexpr\auxi+\tabcolsep\relax}
      \edef\maxx{\dimexpr\auxii-\auxi-\tabcolsep\relax}
    \fi
    \fill[#1,fill opacity=0.3] let \p1 = (pic cs:#4), \p2 = (pic cs:#2) in 
      ( $ (\minx,\y2) + (-2\tabcolsep,3ex) $ ) rectangle 
      ( $ (pic cs:#3) + (\the\dimexpr2\tabcolsep+\maxx,-2.2ex)$ );
  \end{tikzpicture}%
}%

\DeclareCaptionFormat{myformat}{\tikzmark{start\thetable}#1#2#3}
\captionsetup[table]{format=myformat}

\newcommand\ShadeTable[1][orange]{%
  \shadetable[#1]{start\thetable}{end\thetable}{inner\thetable}%
}

\newcommand\IMark{\tikzmark{inner\thetable}\hfill\mbox{}}
\newcommand\EMark{\hfill\tikzmark{end\thetable}}

\begin{document}


\begin{table}
\centering
\caption{test table}
\begin{tabular}{@{}c*{4}{c}c@{}}
\toprule
\IMark & \multicolumn{5}{c}{Year} \\
\cmidrule(r){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4}
\cmidrule(lr){5-5}\cmidrule(l){6-6}
& 2006  & 2007  & 2008  & 2009  & 2010 \\
Tech & 78nm & 68nm & 59nm & 52nm &  45nm\EMark \\
\bottomrule
\end{tabular}
\end{table}

\ShadeTable

\begin{table}
\centering
\caption{the same test table with a middle length caption}
\begin{tabular}{@{}c*{4}{c}c@{}}
\toprule
\IMark & \multicolumn{5}{c}{Year} \\
\cmidrule(r){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4}
\cmidrule(lr){5-5}\cmidrule(l){6-6}
& 2006  & 2007  & 2008  & 2009  & 2010 \\
Tech & 78nm & 68nm & 59nm & 52nm &  45nm\EMark \\
\bottomrule
\end{tabular}
\end{table}

\ShadeTable[red]

\begin{table}
\centering
\caption{the same test table with a long caption spanning more than one line just for a test with such captions}
\begin{tabular}{@{}c*{4}{c}c@{}}
\toprule
\IMark & \multicolumn{5}{c}{Year} \\
\cmidrule(r){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4}
\cmidrule(lr){5-5}\cmidrule(l){6-6}
& 2006  & 2007  & 2008  & 2009  & 2010 \\
Tech & 78nm & 68nm & 59nm & 52nm &  45nm\EMark \\
\bottomrule
\end{tabular}
\end{table}

\ShadeTable[cyan!30]

\end{document}

在此处输入图片描述

一些解释:

用法:

对于每个将获得彩色背景的表格,用户必须\IMark发出第一的表格格式说明之后的命令,\EMark以及最后的命令紧接在表格的最后一项之后(紧接在最终的最后一条水平规则之前)。之后,必须发出\end{table}命令,因此典型的用法将是这样的\ShadeTable

\begin{table}
\centering
\caption{the caption}
\label{tab:lab}
\begin{tabular}{<table format>}
\IMark first entry & second entry & ... \\
entry & entry & ... \\
...
entry & entry & ... & last entry\EMark
\end{tabular}
\end{table}

\ShadeTable[<color>]

对代码的一些评论:

  • 这个想法是利用无处不在的\tikzmark(由安德鲁·史黛西)。

  • 棘手的部分是决定彩色背景的宽度:这个宽度取决于表格的宽度和其标题的宽度,因此需要进行一些计算来决定使用哪个宽度(表格的宽度或其标题的宽度)。

  • 对于这些计算,每个表格使用三个标记;起始标记自动放置在标题的“表格”字符串之前(来自\DeclareCaptionFormatcaption的标记用于此)。

  • \Imark\Emark放置另外两个标记;并利用这些标记的 x 坐标计算适当的背景宽度。

可以做的一些限制和改进:

  • 如果表格浮动到不同的页面,代码就会失败(也许可以在改进的版本中解决这个问题)。

  • 我有一些想法,以便\IMark可以\EMark自动放置;甚至\ShadeTable可以轻松地自动放置(如果我有时间改进版本,我会再次解决这个问题)。

  • 我以为标题会出现实际的表格(这个限制也可以在改进的版本中解除);因为一个流行的惯例是以这种方式添加标题(并且从 OP 的例子中,这个问题就是这种情况),所以我将在这个版本中保留它。

相关内容