8

According to this possibility with tikz pictures (Simulating hand-drawn lines) is there any way to get "hand-drawn lines" in tabulars?

12
+50

Below I preent two optins using percusse's penciline decoration from his answer to Simulating hand-drawn lines.

First Option

Some commands were defined to work with standard "tabular" environments (only horizontal rules are considered); the example below shows those commands used with tabular and tabularx:

\documentclass[varwidth=100cm,border=5pt]{standalone}
\usepackage{tikz}
\usepackage{tabularx}
\usetikzlibrary{calc,decorations.pathmorphing,patterns,matrix,tikzmark}

\newcounter{tikzlinerow}
\newlength\HeavyTikzRuleWd
\newlength\LightTikzRuleWd
\newlength\TikzRuleSep
\setlength\HeavyTikzRuleWd{1pt}
\setlength\LightTikzRuleWd{0.5pt}
\setlength\TikzRuleSep{3pt}

\makeatletter
\newcommand\tikzRule[2]{%
  \addtocounter{tikzlinerow}{2}%
  \\[\dimexpr-\ht\@arstrutbox+\TikzRuleSep\relax]
  \multicolumn{#1}{@{}c@{}}{%
    \pgfmark{\thetikzlinerow}\hfill\pgfmark{\the\numexpr\thetikzlinerow+1\relax}}%
  \\[\dimexpr-\dp\@arstrutbox+\TikzRuleSep\relax]%
  \tikz[remember picture] 
  {
    \draw[overlay,decorate,decoration=penciline,line width=#2] 
      (pic cs:\thetikzlinerow) --
      (pic cs:\the\numexpr\thetikzlinerow+1\relax);
  }\ignorespaces%
}
\newcommand{\tikzHrule}[1]{\tikzRule{#1}{\HeavyTikzRuleWd}}
\newcommand{\tikzLrule}[1]{\tikzRule{#1}{\LightTikzRuleWd}}

\pgfdeclaredecoration{penciline}{initial}{
    \state{initial}[width=+\pgfdecoratedinputsegmentremainingdistance,auto corner on length=1mm,]{
        \pgfpathcurveto%
        {% From
            \pgfqpoint{\pgfdecoratedinputsegmentremainingdistance}
                            {\pgfdecorationsegmentamplitude}
        }
        {%  Control 1
        \pgfmathrand
        \pgfpointadd{\pgfqpoint{\pgfdecoratedinputsegmentremainingdistance}{0pt}}
                        {\pgfqpoint{-\pgfdecorationsegmentaspect\pgfdecoratedinputsegmentremainingdistance}%
                                        {\pgfmathresult\pgfdecorationsegmentamplitude}
                        }
        }
        {%TO 
        \pgfpointadd{\pgfpointdecoratedinputsegmentlast}{\pgfpoint{1pt}{1pt}}
        }
    }
    \state{final}{}
}
\makeatother

\newcommand\Mytoprule[2][\heavirulewidth]{}

\begin{document}

\begin{tabular}{*{7}{c}}
\tikzHrule{7}
Header1 & Header2 & Header3 & Header4 & Header 5 & Header6  & Header7
\tikzLrule{7}
80 & 20  & 30 & 40 & 50 & 60 & 70 \\
80 & 78 & 79 & 80 & 81 & 82 & 83 \\
80 & 78 & 79 & 80 & 81 & 82 & 83 \\
80 & 78 & 79 & 80 & 81 & 82 & 83 \\
80 & 78 & 79 & 80 & 81 & 82 & 83 \\
80 & 78 & 79 & 80 & 81 & 82 & 83
\tikzHrule{7}
\end{tabular}\par\bigskip

\begin{tabularx}{10cm}{XX}
\tikzHrule{2}
Header1 & Header2 
\tikzLrule{2}
Some test text for the example and some more words go here &
  Some test text for the example and some more words go here and we add even more text
\tikzLrule{2}
Some test text for the example and some more words go here &
  Some test text for the example and some more words go here and we add even more text 
\tikzHrule{2}
\end{tabularx}

\end{document}

enter image description here

Second Option

This option uses TikZ \matrix to buid the tabular material:

enter image description here

The code:

\documentclass[varwidth=100cm,border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,decorations.pathmorphing,patterns,matrix}

\tikzset{ 
table/.style={
  matrix of nodes,
  row sep=-\pgflinewidth,
  column sep=-\pgflinewidth,
  nodes={rectangle,text width=#1,align=center},
  text depth=1.25ex,
  text height=2.5ex,
  nodes in empty cells
  }
}

\makeatletter
\pgfdeclaredecoration{penciline}{initial}{
    \state{initial}[width=+\pgfdecoratedinputsegmentremainingdistance,auto corner on length=1mm,]{
        \pgfpathcurveto%
        {% From
            \pgfqpoint{\pgfdecoratedinputsegmentremainingdistance}
                            {\pgfdecorationsegmentamplitude}
        }
        {%  Control 1
        \pgfmathrand
        \pgfpointadd{\pgfqpoint{\pgfdecoratedinputsegmentremainingdistance}{0pt}}
                        {\pgfqpoint{-\pgfdecorationsegmentaspect\pgfdecoratedinputsegmentremainingdistance}%
                                        {\pgfmathresult\pgfdecorationsegmentamplitude}
                        }
        }
        {%TO 
        \pgfpointadd{\pgfpointdecoratedinputsegmentlast}{\pgfpoint{1pt}{1pt}}
        }
    }
    \state{final}{}
}

\begin{document}

\begin{tikzpicture}[decoration=penciline]
\matrix[table=5em,row 1/.style={nodes={font=\bfseries}}] (mat) 
{
Header1 & Header2 & Header3 & Header4 & Header 5 & Header6  & Header7 \\
80 & 20  & 30 & 40 & 50 & 60 & 70 \\
80 & 78 & 79 & 80 & 81 & 82 & 83 \\
80 & 78 & 79 & 80 & 81 & 82 & 83 \\
80 & 78 & 79 & 80 & 81 & 82 & 83 \\
80 & 78 & 79 & 80 & 81 & 82 & 83 \\
80 & 78 & 79 & 80 & 81 & 82 & 83 \\
};

\draw[decorate,line width=1pt] 
  (mat-1-1.north west) -- (mat-1-7.north east);
\draw[decorate,line width=1pt] 
  (mat-7-1.south west) -- (mat-7-7.south east);
\draw[decorate,line width=0.4pt] 
  (mat-1-1.south west) -- (mat-1-7.south east);
\end{tikzpicture}\par\bigskip

\begin{tikzpicture}[decoration=penciline]
\matrix[table=2em,minimum height=2em] (mat1)
{
  1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\
  1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\
  1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\
  1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\
  1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\
  1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\
  1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\
  1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\
  1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\
};

\foreach \Row in {1,...,9}
{
  \draw[decorate,line width=0.4pt] 
    (mat1-\Row-1.north west) -- (mat1-\Row-9.north east);
}
\foreach \Column in {1,...,9}
{
  \draw[decorate,line width=0.4pt] 
    (mat1-1-\Column.north west) -- (mat1-9-\Column.south west);
}
\draw[decorate,line width=0.4pt] 
    (mat1-9-1.south west) -- (mat1-9-9.south east);
\draw[decorate,line width=0.4pt] 
    (mat1-1-9.north east) -- (mat1-9-9.south east);
\end{tikzpicture}

\end{document}

Remark

For the first option I used a variation of egreg's idea in his answer to How to set tikzmarks with \noalign at the edge of tabular rows.

  • 2
    Your solution is really very nice. And I'd love to use it for my tabulars. But the code is much to complex to use it in a document. Why don't you make a package? Please!? :-)) It just has to redefine \hline and vertical lines... – Keks Dose Sep 22 '15 at 14:33
  • @KeksDose Thank you. I've provided now another option that will work with regular tabular environments (tabular, tabularx, etc.). The code can be improved a lot yet, but it's a good starting point; only horizontal rules were considered. – Gonzalo Medina Sep 23 '15 at 1:59
  • Thanks a lot. When I try a tabu environment from the tabu package in your first MWE the table extends to a strange wideness. In another class it works good. Also the multicolumn is not so useful, at least I didn't managed to span a line from cell 2 to 3 for example. When there would be a possibility to also make vertical lines in hand drawn style, it would be very nice. I accept your answer anyway. – Rafael Wörner Sep 23 '15 at 10:39
  • @RafaelWörner Thanks. I didn't try tabu, and I wouldn't recommend using it (it has some problems and the author has said he won't fix them). As for an equivalent to \cline maybe I'll provide a replacement, but not soon. Vertical rules are still more complicated. – Gonzalo Medina Sep 23 '15 at 13:50
  • @GonzaloMedina Wonderful. The first code block renders to something quite similiar to booktabs. And the code still is fast enough for daily use. Couldn't you just improve the code a bit: instead of \tikzLrule{7} and \tikzHrule{7} just \\ \tikzLrule{} and \\ \tikzHrule{}, please? Because the booktabs package has this syntax (e.g. \\ \toprule) and so users just could switch between the two styles. – Keks Dose Sep 23 '15 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.