8

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

  • This may be useful for drawing tables with TikZ (and then using the 'hand drawn' lines) http://tex.stackexchange.com/questions/180401/drawing-sql-tables – Nathanael Farley Sep 22 '15 at 11:09

1 Answers1

12

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.

Gonzalo Medina
  • 505,128
  • 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 01: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