我正在尝试创建一个官方(外观)表格。使用 tikz 绘制字段时,我需要inner sep
从字段的预期宽度中减去以获得正确的宽度。
\documentclass[DIN, a4, 11pt]{scrartcl}
% encoding
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
% packages
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
% font
\usepackage{tgheros}
\renewcommand\familydefault{\sfdefault}
% dimensions
\newlength\margin
\setlength\margin{2cm}
\newlength\innersep
\setlength\innersep{\dimexpr3pt\relax}
\newcommand{\numberunits}{8}
% basic length unit (blu)
\newlength\blu
\setlength\blu{\dimexpr(\paperwidth-2\margin)/\numberunits\relax}
% basic height unit (bhu)
\newlength\bhu
\setlength\bhu{\dimexpr1.5em\relax}
% tikz styles
\tikzstyle{textfield} = [text depth = \bhu, draw, anchor=north west, outer sep=0, inner sep=\innersep, font = {\tiny\sffamily}]
\begin{document}
\begin{tikzpicture} [overlay, remember picture,shift={(current page.north west)}]
\coordinate (outer_border_north_west) at (\margin, -\margin);
\coordinate (outer_border_south_east) at (\dimexpr\paperwidth-\margin\relax,-\dimexpr\paperheight-\margin\relax);
\draw (outer_border_north_west) rectangle (outer_border_south_east);
\node[textfield, text width = 3\blu-2\innersep] (Name) at (outer_border_north_west) {Name};
\node[textfield, text width = 3\blu-2\innersep, right = 0cm of Name.east] (First Name) {First Name};
\node[textfield, text width = 2\blu-2\innersep, right = 0cm of First Name.east] (Birth Date) {Birth Date};
\end{tikzpicture}
\end{document}
这是为什么?这是内部分离,而不是外部分离……对吗?
答案1
我会将矩形绘制为矩形,并将小文本标签绘制为位于这些矩形左上角并已anchor = north west
设置的节点。我确信它们不会比实际的矩形长(否则我们需要确保它们具有最大文本宽度,但矩形和整行无论如何都不会向下增长)。
我也刚刚通过设置了适当的页面设置geometry
,即margin
四边都是 2 厘米。
而不是\numberunits
我使用值键(以及各个列)并设置X向量为一个这样的单位的长度。
trim left
和trim right
的使用使得矩形的线宽不会对边界框产生影响,并引发超满水平框错误。同样, 的baseline
使用使得图片也具有一定的深度(并且不会跳转到下一页)。
在form
环境中\row
,宏采用一个可选参数来设置/tikz/form
命名空间中的键,以及一个强制参数,即该行中的元素列表。
您始终可以在外部范围将columns
或设置height
为通用默认值,并且仅在可选参数中指定该默认值的变体\row
。
我还可以想象一个&
和\\
供电的输入(带有一些额外的预处理),以便它看起来几乎像您输入的普通矩阵/表格(但实际上将执行相同或类似的循环)\path
。foreach
输入语法几乎可以是任何东西。我认为最直接的实现方式是这个。
代码
\documentclass[paper=A4, 11pt]{scrartcl}
% encoding
\usepackage[T1]{fontenc}
% packages
\usepackage{tikz}
\usepackage[margin=2cm,footskip=1cm]{geometry}
% font
\usepackage{tgheros}
%\renewcommand\familydefault{\sfdefault}
\tikzset{
form/.cd,
.code=\pgfqkeys{/tikz/form}{#1},
textfield/.style={anchor=north west, font=\tiny\sffamily},
@columns/.code=%
\pgfmathparse{#1}\edef\pgfmathcounter{\pgfinteval{\pgfmathcounter+1}}%
\pgfkeyssetevalue{/tikz/form/col \pgfmathcounter\space width}{\pgfmathresult}%
\pgfmathparse{\pgfmathresult+\pgfkeysvalueof{/tikz/form/units}}%
\pgfkeyssetevalue{/tikz/form/units}{\pgfmathresult},
columns/.style={
/tikz/form/units/.initial=0,
/utils/exec=\def\pgfmathcounter{0},
/tikz/form/@columns/.list={#1}},
columns={3,3,2}, % initialize 3/3/2 column grid
height/.initial=2.5em, % initialize row height
row/.style=draw} % initialize row style
\makeatletter % let us setup the \row command here without having to globally def it
\newcommand*\tikzform@row[2][]{%
\path[form={#1},form/row,x=\linewidth/(\pgfkeysvalueof{/tikz/form/units})]
(@top left) foreach[count=\colCnt] \col in {#2}{
node[form/textfield]{\col}
rectangle ++(\pgfkeysvalueof{/tikz/form/col \colCnt\space width},
-\pgfkeysvalueof{/tikz/form/height})
++ (up:\pgfkeysvalueof{/tikz/form/height})
}
coordinate (@top left)
at ([shift=(down:\pgfkeysvalueof{/tikz/form/height})]@top left);}
\newenvironment*{form}[1][]{%
\par\noindent
\tikzpicture[trim left=+0pt, trim right=+\linewidth,baseline=1em,form={#1}]
\draw (0pt,0pt) rectangle (\linewidth,\textheight);
\coordinate (@top left) at (0pt,\textheight);
\let\row\tikzform@row
}{\endtikzpicture\par}
\makeatother
\begin{document}
\begin{form}
\row{Name, First Name, Birth Date}
\row[columns={8, 2}, height=4em]{Street, No.}
\row[columns={3,2,9}, height=1.5em]{Country, ZIP, City}
\end{form}
\end{document}