Clear rowcolor at midrule

You can clear colors with \hiderowcolors:

\documentclass{article}

\usepackage{etoolbox}
\usepackage[table]{xcolor}
\usepackage{booktabs}


\colorlet{text}{black}
\colorlet{page}{white}


\renewcommand{\toprule}{%
    \showrowcolors\arrayrulecolor{text}\specialrule{\heavyrulewidth}{\abovetopsep}{0pt}%
    \arrayrulecolor{tableheadcolor}\specialrule{\belowrulesep}{0pt}{0pt}%
    \arrayrulecolor{text}}%

\colorlet{tableheadcolor}{orange!30!page}
\apptocmd\midrule{\hiderowcolors}{}{\fail}
\rowcolors{1}{tableheadcolor}{tableheadcolor}
\begin{document}

\pagecolor{blue!10}

\begin{tabular}{lll}
    & & \\
    \toprule
    a & b & \\
    \midrule
    1 & 2 & \\
    \midrule
    4 & 5 & \\
    \midrule
    7 & 8 & 
\end{tabular}
\quad
\begin{tabular}{lll}
    \toprule
    a & b & \\
    \midrule
    1 & 2 & \\
    \midrule
    4 & 5 & \\
    % \meaning\\ & & \\
    \midrule
    7 & 8 & 
\end{tabular}

\end{document}

enter image description here


The reason for your off-by-one row colouring is that when your modified \midrule sets your tabularTitleRow boolean flag to false, it is already too late: the preceding \\ command has already put the \rowcolor call that sets the row color for header rows. Moreover, your way of modifying \@xarraycr is nasty, because it prevents the \\[〈dimen〉] syntax from working inside a tabular or array. So, it's better not to redefine \@xarraycr if possible (as done below).

Based on Ulrike Fischer's idea about using \hiderowcolors, here is a way to get the space above the \midrule coloured in the proper colour for the table header (but see below for a more elaborate solution based on this technique):

\documentclass{article}
\usepackage{etoolbox}
\usepackage[table]{xcolor}
\usepackage{ctable} % or booktabs

\colorlet{text}{black}
\colorlet{page}{white}
\colorlet{tableheadcolor}{orange!30!page}

% Use of \showrowcolors and \hiderowcolors is an idea from Ulrike
% Fischer's answer here: <https://tex.stackexchange.com/a/494954/73317>
\renewcommand{\toprule}{%
    \showrowcolors
    \arrayrulecolor{text}\specialrule{\heavyrulewidth}{\abovetopsep}{0pt}%
    \arrayrulecolor{tableheadcolor}\specialrule{\belowrulesep}{0pt}{0pt}%
    \arrayrulecolor{text}%
    \rowcolor{tableheadcolor}%
}

\apptocmd\midrule{\hiderowcolors}{}{\FAILED}

\makeatletter

\let\@[email protected]=\@BTrule
\let\[email protected]=\@BTrule

% Modified version of \@BTrule that doesn't do \vskip\@aboverulesep, for use
% when the corresponding vertical space should be coloured.
\patchcmd{\[email protected]}{%
    \ifnum\@lastruleclass=\[email protected]\vskip\@aboverulesep\else
  }{%
    \ifnum\@lastruleclass=\[email protected]\else
  }{}{\FAILED}

\newcommand*{\myendtablehead}{%
 \\[\aboverulesep] % this colours the additional space with the current row
                   % color
 \noalign{\global\let\@BTrule\[email protected]}% temporarily modify \@BTrule
 \midrule
 \noalign{\global\let\@BTrule\@[email protected]}% restore it
}

\makeatother

\rowcolors{1}{tableheadcolor}{tableheadcolor}

\begin{document}
\pagecolor{blue!10}

\begin{tabular}{ll}
    \toprule
    a & b \\
    d & e \myendtablehead
    1 & 2 \\
    4 & 5 \\
    7 & 8 \\
    \bottomrule
\end{tabular}

\end{document}

Screenshot

Here is a solution that allows you to write the \\ before \midrule, as usual, without needing to explicitly call \myendtablehead. Note that for \midrule to be recognized by the modified \@arraycr, it must immediately follow the \\ command (well, there may be space tokens between them, but nothing else).

Since the \rowcolors command respects grouping, we define a coloredtableheaders environment inside which alignments are colored according to this scheme. Outside this environment, \toprule, \midrule and \@arraycr have their usual meaning. Any \rowcolors command used outside the coloredtableheaders environment is independent of what we do inside, and should behave as usual.

\documentclass{article}
\usepackage{etoolbox}
\usepackage[table]{xcolor}
\usepackage{booktabs} % or ctable

\colorlet{text}{black}
\colorlet{page}{white}
\colorlet{tableheadcolor}{orange!30!page}

\makeatletter

% The use of \showrowcolors and \hiderowcolors is an idea from Ulrike
% Fischer's answer here: <https://tex.stackexchange.com/a/494954/73317>
\newcommand*{\[email protected]}{%
  \showrowcolors
  \arrayrulecolor{text}\specialrule{\heavyrulewidth}{\abovetopsep}{0pt}%
  \arrayrulecolor{tableheadcolor}\specialrule{\belowrulesep}{0pt}{0pt}%
  \arrayrulecolor{text}%
  \rowcolor{tableheadcolor}%
}

\let\[email protected]\midrule
\apptocmd\[email protected]{\hiderowcolors}{}{\FAILED}

\let\@[email protected]=\@BTrule
\let\[email protected]=\@BTrule

% Modified version of \@BTrule that doesn't do \vskip\@aboverulesep, for use
% when the corresponding vertical space should be coloured.
\patchcmd{\[email protected]}{%
    \ifnum\@lastruleclass=\[email protected]\vskip\@aboverulesep\else
  }{%
    \ifnum\@lastruleclass=\[email protected]\else
  }{}{\FAILED}

\let\@arraycrORI=\@arraycr

% The “master counter” hackery is explained in the TeXbook appendix D (Dirty
% Tricks), pp. 385-386. It is also mentioned in the array.sty implementation
% notes concerning \@arraycr.
\newcommand*{\[email protected]@arraycr}{%
  % Increase the master counter. This is needed to prevent TeX from
  % prematurely finishing the alignment entry in case \\ was followed by '&'
  % (when the \futurelet from \@ifnextchar causes TeX to read a '&', this
  % finishes the entry unless the master counter has a different value than it
  % had when the entry was started).
  \relax\iffalse{\fi\ifnum 0=`}\fi
  % Each of the two branches takes care of decreasing the master counter.
  \@ifnextchar\midrule
    {\@firstoftwo{\[email protected]}}% gobble the following \midrule
    {\[email protected]@[email protected]}%
}

\newcommand*{\[email protected]}{%
  \ifnum 0=`{}\fi % the second brace decreases the master counter
  \@arraycrORI[\aboverulesep]% this colours the additional space with the
                             % current row color
  \noalign{\global\let\@BTrule\[email protected]}% temporarily modify \@BTrule
  \midrule
  \noalign{\global\let\@BTrule\@[email protected]}% restore it
}

\newcommand*{\[email protected]@[email protected]}{%
  \ifnum 0=`{}\fi % the second brace decreases the master counter
  \@arraycrORI
}

\newenvironment{coloredtableheaders}{%
  \let\toprule\[email protected]
  \let\midrule\[email protected]
  \let\@arraycr\[email protected]@arraycr
  \rowcolors{1}{tableheadcolor}{tableheadcolor}%
  \ignorespaces
}{%
  \unskip\ignorespacesafterend
}

\makeatother

\begin{document}
\pagecolor{blue!10}

No colored header in the following \verb|tabular|:\quad
\begin{tabular}{l}
   a \\
   b \\
   c
\end{tabular}

\bigskip
\begin{coloredtableheaders}
  \begin{tabular}{ll}
    \toprule
    a & b \\
    d & e \\
    \midrule
    1 & 2 \\
    4 & 5 \\
    7 & 8 \\
    \bottomrule
  \end{tabular}

  \vspace{4ex}
  \begin{tabular}{>{\hspace{3pt}\normalsize}l>{\hspace{5pt}}*{3}{p{7.9em}}}
    \toprule
    Category & \multicolumn{3}{l}{\normalsize Packages} \\
    \midrule
    General  & etb & xpt & sil \\
             & tts & ttc & frm \\
    \bottomrule
  \end{tabular}
\end{coloredtableheaders}

\vspace{4ex}
No colored header in the following \verb|tabular|:\quad
\begin{tabular}{lr}
  Foo     & 1\\
  Bar     & 2\\
  And baz & 3
\end{tabular}
\end{document}

Screenshot

Using \cline in the colored header

As documented in the colortbl manual:

Lines produced by \cline are coloured if you use \arrayrulecolor but you may not notice as they are covered up by any colour pannels in the following row. This is a ‘feature’ of \cline. If using this package you would probably [be] better using the - rule type in a \hhline argument, rather than \cline.

Example using the above code and the hhline package:

  \begin{tabular}{lll}
    \toprule
    a & \multicolumn{2}{c}{b} \\
    % \cline{2-3} % problem: covered by the next colored row
    % \hhline provides a viable alternative:
    \hhline{>{\arrayrulecolor{tableheadcolor}}->{\arrayrulecolor{black}}--}
      & c & d\\ \midrule
    e & f & g \\ \bottomrule
  \end{tabular}

Screenshot