Füllen Sie Felder für Formulare in TikZ aus

Füllen Sie Felder für Formulare in TikZ aus

Ich möchte einSEPA-Überweisungsformular mit IBAN

Wie erstelle ich ein Formularfeld mit Nje 5mm breiten Feldern und Abständen wie im Bild? Formularfeld

Momentan verwende ich einen Workaround mit einer For-Schleife, was den Code allerdings schwer wartbar macht. Abschließend benötige ich noch eine Funktion, \formline{N}{cellwidth}{label}{value}die das komplette Formularfeld erstellt und mit einem optionalen Wert füllt: Formularfeld ausfüllen

Der folgende Code ist verfügbar aufhttps://github.com/jonasstein/bankformtex.

\documentclass[a4paper,11pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{shapes}

\thispagestyle{empty} % no pagenumber. The form should be a stand alone macro... later.

\definecolor{SEPAOrange}{RGB}{254,213,161}
\definecolor{SEPADOrange}{RGB}{253,185,19}
\definecolor{SEPABlindcolor}{RGB}{255,0,0}
\begin{document}
\begin{tikzpicture}[x=1 mm, y=-1mm]
\pgfmathsetmacro{\yh}{4.2333} % y heigth step defined as 1/6 inch => 1/6 * 25.4 mm = 4.2333 mm
\pgfmathsetmacro{\xs}{9} % x start (own definition)
\pgfmathsetmacro{\xe}{141.5} % x end (own definition)
\pgfmathsetmacro{\widefield}{4.9859} % def: 134.62 mm / 27
\pgfmathsetmacro{\narrowfiels}{3.9594} % def: 134.62 mm/ 34

\filldraw[draw=black,color=SEPAOrange] (7.62, 4.5*\yh) rectangle (149.86-7.62,105.83-1); %orange background

\filldraw[draw=black,color=white] (\xs, 5*\yh) rectangle (\xe, 6.5*\yh -1.5); %Recepient 27 Char
\foreach \x in {1,...,26}
{
 \draw[color=SEPAOrange, line width=0.3mm] (7.62 + \x*\widefield, 5*\yh ) -- (7.62 + \x*\widefield, 6.5*\yh);
 \draw[color=SEPAOrange, line width=0.7mm] (7.62 + \x*\widefield, 5.8*\yh ) -- (7.62 + \x*\widefield, 6.5*\yh);
}

\filldraw[draw=black,color=white] (\xs, 7*\yh) rectangle (\xe, 8.5*\yh -1.5); %IBAN 34 Char
\foreach \x in {1,...,33}
 \draw[color=SEPAOrange, line width=0.3mm] (7.62 + \x*4, 7*\yh ) -- (7.62 + \x*4, 8.5*\yh);

\filldraw[draw=black,color=white] (\xs, 9*\yh) rectangle (\xe, 10.5*\yh -1.5); %BIC
\filldraw[draw=black,color=white] (\xe-12*5, 11*\yh) rectangle (\xe, 12.5*\yh -1.5); %Value 12 Char

\filldraw[draw=black,color=white] (\xs, 13*\yh) rectangle (\xe, 14.5*\yh -1.5); %Subject1
\filldraw[draw=black,color=white] (\xs, 15*\yh) rectangle (\xe, 16.5*\yh -1.5); %Subject2
\filldraw[draw=black,color=white] (\xs, 17*\yh) rectangle (\xe, 18.5*\yh -1.5); %Subject3

\filldraw[draw=black,color=white] (\xs, 19*\yh) rectangle (\xs+22*5, 20.5*\yh -1.5); % IBAN 22 Char

\filldraw[draw=black,color=white] (149.86-17.59, 19* \yh) rectangle (\xe, 20.5*\yh -1.5); % counter
\filldraw[draw=black,color=white] (\xs, 21* \yh) rectangle (42.52, 24.5*\yh); % date
\filldraw[draw=black,color=white] (42.52+5, 21*\yh) rectangle (149.86-17.59, 24.5*\yh); % signature

\draw[color=SEPADOrange] (0, 4.5 *\yh) --(149.86, 4.5*\yh); upper dark orange line
\draw[color=SEPADOrange] (0, 20.5 *\yh) --(149.86, 20.5*\yh); lower dark orange line
\draw[draw=black,color=black, line width=0.3mm] (0,0) rectangle (149.86,105.83); % black border
%\draw[align=left] at (\yh,\yh) {SEPA-Überweisung};

\end{tikzpicture}
\end{document} 

Antwort1

Verwendung

\formline*(coord)[field width][scope options]{N}{label}[value]<dividers>

obligatorische Argumente

  • coord: wo die Zeile platziert werden soll; der Anker ist westdas erste Feld.
  • N: Anzahl der Felder.
  • label: Name der Zeile.

optionale Argumente

  • *: Leerzeichen in ignorieren value.
  • field width: Breite eines Feldes.
  • scope options: Optionen werden an übergeben {scope}.
  • value: etwas ausfüllen, sollte nur enthaltennormalFiguren.
  • dividers: Trennzeichen zwischen Dateien hinzufügen; kann entweder eine Kommaliste von Dateinummern sein oder every n( nkann positiv oder negativ sein).

Beispiele

\begin{tikzpicture}
    % background
    \fill [SEPAOrange] (0,0) rectangle (15,12);
    % formlines
    \formline(1,10){25}{Bank}[Deutsche Bank Hamburg]
    \formline(1,9)[6mm]{5}{Number 1}[123456]
    \formline(1,8)[6mm]{5}{Number 2}[1234]
    \formline*(1,7){22}{IBAN 1}[DE00 2105 0170 0012 3456 78]<every 4>
        % dividers every 4th field from right
    \formline*(1,6){22}{IBAN 2}<every -4>% dividers every 4th from left
    \formline*(1,5){22}{IBAN 3}<2,5,10,15,20>% irregular dividers
\end{tikzpicture}

Beispiele

Anmerkungen

  • Jedes Feld ist ein einzelner Knoten und wird mit benannt form field label n, wobei labelder Argumentwert und ndie Nummer des Felds (beginnend bei 0) ist. Sie können diese Knotennamen verwenden, um Frames oder ähnliches hinzuzufügen.
  • Es gibt mehrere TikZ-Stile, mit denen das Erscheinungsbild geändert werden kann.
  • Ich habe dem Code einige Erklärungen hinzugefügt –bei Unklarheiten bitte nachfragen!

vollständiger Code

\documentclass{article}

% packages
\usepackage{tikz,xparse}
\usetikzlibrary{positioning,fit,calc}

% colors
\definecolor{SEPAOrange}{RGB}{254,213,161}
\definecolor{SEPADOrange}{RGB}{253,185,19}

% switch on expl3 syntax
% (_ and : become part of macro names; spaces are ignored; ~ is normal space)
\ExplSyntaxOn
% make @ available as part of macro name
\makeatletter
% commad to genreate internal lengths
% use \form_generate_lengths:n {<comma list>}
\cs_new:Npn \form_generate_lengths:n #1 {
    \clist_set:Nn \l_tmpa_clist { #1 }
    \clist_map_inline:Nn \l_tmpa_clist {
        \expandafter\newlength \csname form @ x ##1 \endcsname
        \expandafter\newlength \csname form @ y ##1 \endcsname
    }
}
% gererate internal length used in node shapes
\form_generate_lengths:n {
    A, Ab, At, Abt,
    B, Bb, Bt, Bbt,
    D,
    C,
}
% sep between fields
\dim_new:N \g_form_sep_dim
\dim_set:Nn \g_form_sep_dim { 0.5pt }
% dimensions of the edges in fields
\dim_new:N \g_form_x_edge_dim
\dim_set:Nn \g_form_x_edge_dim { 0.5pt }
\dim_new:N \g_form_y_edge_dim
\dim_set:Nn \g_form_y_edge_dim { 3pt }
\dim_new:N \formdividerwidth
\dim_set:Nn \formdividerwidth { 2\g_form_x_edge_dim + \g_form_sep_dim }
\dim_new:N \formdividerheight
\dim_set:Nn \formdividerheight { \g_form_y_edge_dim }
% new node shapes for fields
\pgfdeclareshape{form~field~middle}{% from p. 631 in pgfmanual.pdf
    \inheritsavedanchors[from=rectangle]
    \inheritanchorborder[from=rectangle]
    \inheritanchor[from=rectangle]{base}
    \inheritanchor[from=rectangle]{center}
    \inheritanchor[from=rectangle]{north}
    \inheritanchor[from=rectangle]{north~east}
    \inheritanchor[from=rectangle]{east}
    \inheritanchor[from=rectangle]{south~east}
    \inheritanchor[from=rectangle]{south}
    \inheritanchor[from=rectangle]{south~west}
    \inheritanchor[from=rectangle]{west}
    \inheritanchor[from=rectangle]{north~west}
    \backgroundpath{%  this is new
        %  store corners
        \southwest \form@xA = \pgf@x \form@yA = \pgf@y
        \northeast \form@xC = \pgf@x \form@yC = \pgf@y
        \form@xB = \form@xC \form@yB = \form@yA
        \form@xD = \form@xA \form@yD = \form@yC
        % calculate edges
        \form@xAt = \form@xA
        \form@yAt = \form@yA \advance \form@yAt by \g_form_y_edge_dim
        \form@xAb = \form@xA \advance \form@xAb by \g_form_x_edge_dim
        \form@yAb = \form@yA
        \form@xAbt = \form@xAb
        \form@yAbt = \form@yAt
        \form@xBt = \form@xB
        \form@yBt = \form@yB \advance \form@yBt by \g_form_y_edge_dim
        \form@xBb = \form@xB \advance \form@xBb by -\g_form_x_edge_dim
        \form@yBb = \form@yB
        \form@xBbt = \form@xBb
        \form@yBbt = \form@yBt
        %  construct main path
        \pgfpathmoveto{\pgfpoint{\form@xAt}{\form@yAt}}
        \pgfpathlineto{\pgfpoint{\form@xD}{\form@yD}}
        \pgfpathlineto{\pgfpoint{\form@xC}{\form@yC}}
        \pgfpathlineto{\pgfpoint{\form@xBt}{\form@yBt}}
        \pgfpathlineto{\pgfpoint{\form@xBbt}{\form@yBbt}}
        \pgfpathlineto{\pgfpoint{\form@xBb}{\form@yBb}}
        \pgfpathlineto{\pgfpoint{\form@xAb}{\form@yAb}}
        \pgfpathlineto{\pgfpoint{\form@xAbt}{\form@yAbt}}
        \pgfpathlineto{\pgfpoint{\form@xAt}{\form@yAt}}
        \pgfpathclose
    }
}
\pgfdeclareshape{form~field~start}{
    \inheritsavedanchors[from=rectangle]
    \inheritanchorborder[from=rectangle]
    \inheritanchor[from=rectangle]{center}
    \inheritanchor[from=rectangle]{base}
    \inheritanchor[from=rectangle]{north}
    \inheritanchor[from=rectangle]{north~east}
    \inheritanchor[from=rectangle]{east}
    \inheritanchor[from=rectangle]{south~east}
    \inheritanchor[from=rectangle]{south}
    \inheritanchor[from=rectangle]{south~west}
    \inheritanchor[from=rectangle]{west}
    \inheritanchor[from=rectangle]{north~west}
    \backgroundpath{%  this is new
        %  store corners
        \southwest \form@xA = \pgf@x \form@yA = \pgf@y
        \northeast \form@xC = \pgf@x \form@yC = \pgf@y
        \form@xB = \form@xC \form@yB = \form@yA
        \form@xD = \form@xA \form@yD = \form@yC
        % calculate edges
        \form@xAt = \form@xA
        \form@yAt = \form@yA \advance \form@yAt by \g_form_y_edge_dim
        \form@xAb = \form@xA \advance \form@xAb by \g_form_x_edge_dim
        \form@yAb = \form@yA
        \form@xAbt = \form@xAb
        \form@yAbt = \form@yAt
        \form@xBt = \form@xB
        \form@yBt = \form@yB \advance \form@yBt by \g_form_y_edge_dim
        \form@xBb = \form@xB \advance \form@xBb by -\g_form_x_edge_dim
        \form@yBb = \form@yB
        \form@xBbt = \form@xBb
        \form@yBbt = \form@yBt
        %  construct main path
        \pgfpathmoveto{\pgfpoint{\form@xA}{\form@yA}}
        \pgfpathlineto{\pgfpoint{\form@xD}{\form@yD}}
        \pgfpathlineto{\pgfpoint{\form@xC}{\form@yC}}
        \pgfpathlineto{\pgfpoint{\form@xBt}{\form@yBt}}
        \pgfpathlineto{\pgfpoint{\form@xBbt}{\form@yBbt}}
        \pgfpathlineto{\pgfpoint{\form@xBb}{\form@yBb}}
        \pgfpathlineto{\pgfpoint{\form@xA}{\form@yA}}
        \pgfpathclose
    }
}
\pgfdeclareshape{form~field~end}{
    \inheritsavedanchors[from=rectangle]
    \inheritanchorborder[from=rectangle]
    \inheritanchor[from=rectangle]{center}
    \inheritanchor[from=rectangle]{base}
    \inheritanchor[from=rectangle]{north}
    \inheritanchor[from=rectangle]{north~east}
    \inheritanchor[from=rectangle]{east}
    \inheritanchor[from=rectangle]{south~east}
    \inheritanchor[from=rectangle]{south}
    \inheritanchor[from=rectangle]{south~west}
    \inheritanchor[from=rectangle]{west}
    \inheritanchor[from=rectangle]{north~west}
    \backgroundpath{%  this is new
        %  store corners
        \southwest \form@xA = \pgf@x \form@yA = \pgf@y
        \northeast \form@xC = \pgf@x \form@yC = \pgf@y
        \form@xB = \form@xC \form@yB = \form@yA
        \form@xD = \form@xA \form@yD = \form@yC
        % calculate edges
        \form@xAt = \form@xA
        \form@yAt = \form@yA \advance \form@yAt by \g_form_y_edge_dim
        \form@xAb = \form@xA \advance \form@xAb by \g_form_x_edge_dim
        \form@yAb = \form@yA
        \form@xAbt = \form@xAb
        \form@yAbt = \form@yAt
        \form@xBt = \form@xB
        \form@yBt = \form@yB \advance \form@yBt by \g_form_y_edge_dim
        \form@xBb = \form@xB \advance \form@xBb by -\g_form_x_edge_dim
        \form@yBb = \form@yB
        \form@xBbt = \form@xBb
        \form@yBbt = \form@yBt
        %  construct main path
        \pgfpathmoveto{\pgfpoint{\form@xAt}{\form@yAt}}
        \pgfpathlineto{\pgfpoint{\form@xD}{\form@yD}}
        \pgfpathlineto{\pgfpoint{\form@xC}{\form@yC}}
        \pgfpathlineto{\pgfpoint{\form@xB}{\form@yB}}
        \pgfpathlineto{\pgfpoint{\form@xAb}{\form@yAb}}
        \pgfpathlineto{\pgfpoint{\form@xAbt}{\form@yAbt}}
        \pgfpathlineto{\pgfpoint{\form@xAt}{\form@yAt}}
        \pgfpathclose
    }
}
% new command to draw a line of fiels
% usage: \formline*(coord)[field width][scope options]{N}{label}[value]<dividers>
%                #1   #2       #3           #4        #5    #6    #7      #8
%        * = ignore spaces in [value]
%        required: #2, #5, #6,
%        optional: #1, #3, #4, #7, #8
\NewDocumentCommand { \formline } { s r() O{3mm} O{} m m o d<> } {
    % save field width
    \dim_set:Nn \l_tmpa_dim { #3 }
    % begin a scope
    \begin{scope}
        [every~form~field/.append~style={minimum~width=\dim_use:N \l_tmpa_dim}, #4]
        % draw fields
        %% set temp counter to 0
        \int_set:Nn \l_tmpa_int {0}
        %% first node (number 0)
        \node (form~field~#6~0) [at={(#2)}, every~form~field~start] {\strut};
        %% middle nodes, go through list form 1 to N-1
        \int_step_inline:nnnn { 1 } { 1 } { #5 - 2 } {
            %%% draw node
            \node (form~field~#6~##1) [
                every~form~field~middle,
                right=\dim_use:N \g_form_sep_dim of~form~field~#6~\int_use:N \l_tmpa_int
            ] {\strut};
            %%% incremet counter by 1
            \int_incr:N \l_tmpa_int
        }
        %% draw last node (number N)
        \node (form~field~#6~\int_eval:n { #5 - 1 }) [
            every~form~field~end,
            right=\dim_use:N \g_form_sep_dim of~form~field~#6~\int_use:N \l_tmpa_int
        ] {\strut};
        % draw label
        \node [every~form~label, above~right=0pt~of~form~field~#6~0.north~west] {#6};
        % add value, if exist
        \IfValueT { #7 } {
            %% save value to token list
            \tl_set:Nn \l_tmpa_tl { #7 }
            %% replace input space with space token
            \IfBooleanF { #1 } {
                \tl_replace_all:Nnn \l_tmpa_tl { ~ } { \c_space_token }
            }
            %% set temp counter to 0
            \int_set:Nn \l_tmpa_int { 0 }
            %% iterate through tokes and print digits above fields
            \tl_map_inline:Nn \l_tmpa_tl {
                %%% chack overlong values
                \int_compare:nT { \l_tmpa_int = #5 } {
                    \node at (form~field~#6~\int_eval:n { \l_tmpa_int - 1 })
                        [fill=red, font=\bfseries] {ERROR:~value~too~long};% some error message
                    \tl_map_break:
                }
                %%% draw digit
                \node [every~form~digit] at (form~field~#6~\int_use:N \l_tmpa_int.base) { ##1 };
                %%% incremet counter by 1
                \int_incr:N \l_tmpa_int
            }
        }
        % add sub-dividers, if exist
        \IfValueT { #8 } {
            %% save lowercase version of #7 to token list
            \tl_set:Nn \l_tmpa_tl { #8 }
            %% if it contains "every"
            \tl_if_in:NnTF \l_tmpa_tl { every } {
                %%% remove "every"
                \tl_remove_all:Nn \l_tmpa_tl { every }
                %%% save to int
                \int_set:Nn \l_tmpa_int { \l_tmpa_tl }
                %%% from left (> 0) or right (< 0)?
                \int_compare:nTF { \l_tmpa_int > 0 } {
                    %%%% draw marks from left
                    \int_step_inline:nnnn { \l_tmpa_int - 1 } { \l_tmpa_int } { #5 - 2 } {
                        \node at
                            ($(form~field~#6~##1.south~east)+(\dim_use:N \g_form_sep_dim / 2,0)$)
                            [every~form~divider] {};
                    }
                } {
                    %%%% draw marks from right
                    \int_step_inline:nnnn { #5 - 1 + \l_tmpa_int } { \l_tmpa_int } { 0 } {
                        \node at
                            ($(form~field~#6~##1.south~east)+(\dim_use:N \g_form_sep_dim / 2,0)$)
                            [every~form~divider] {};
                    }
                }
            } {
                %%% iterate throug comma list
                \clist_map_inline:nn { #8 } {
                    \node at
                        ($(form~field~#6~##1.south~east)+(\dim_use:N \g_form_sep_dim / 2,0)$)
                        [every~form~divider] {};
                }
            }
        }
    \end{scope}
}
% switch off expl3 syntax and @
\ExplSyntaxOff\makeatother

\tikzset{
    every form field/.style = {
        fill=white,
        inner sep=0pt,
        minimum height=4mm,
        align=center,
    },
    every form field middle/.style = {
        every form field,
        form field middle,
    },
    every form field start/.style = {
        every form field,
        form field start,
        anchor=south west,
    },
    every form field end/.style = {
        every form field,
        form field end,
    },
    every form label/.style = {
        fill=white, text=SEPADOrange,
        inner sep=1pt,
        outer sep=0pt,
        font=\tiny\sffamily\bfseries,
    },
    every form digit/.style = {
        anchor=base,
        font=\ttfamily,
        inner sep=0pt,
    },
    every form divider/.style = {
        fill=black,
        inner sep=0pt,
        outer sep=0pt,
        anchor=south,
        minimum width=\formdividerwidth,
        minimum height=\formdividerheight,
    },
}

\begin{document}
\begin{tikzpicture}
    % background
    \fill [SEPAOrange] (0,0) rectangle (15,12);
    % formlines
    \formline(1,10){25}{Bank}[Deutsche Bank Hamburg]
    \formline(1,9)[6mm]{5}{Number 1}[123456]
    \formline(1,8)[6mm]{5}{Number 2}[1234]
    \formline*(1,7){22}{IBAN 1}[DE00 2105 0170 0012 3456 78]<every 4>
        % dividers every 4th field from left
    \formline*(1,6){22}{IBAN 2}<every -4>% dividers every 4th from right
    \formline*(1,5){22}{IBAN 3}<2,5,10,15,20>% irregular dividers
\end{tikzpicture}
\end{document}

verwandte Informationen