[Tex/LaTex] Shouldn’t this table span the whole page width

tabularxwidth

I have this table definition as part of a invoice

\begin{tabularx}{\textwidth}[ht]{lXrr}%

It worked fine for years until I have a very short word in the X column for the first time.
Now my table is very small in width and centered horizontally on the page.

In my expectation the X column should fill up all space until the width of the table reaches the width of the page except the margins.

I have read about workarounds specifying something like 1.2\textwidth, but I don't like that, because the table is a template included via \include, so it would affect all my invoices.

I also tried \linewidth, \hsize and \columnwidth, but everything results in the same layout.

Is there a way to make the only X column expand so that it uses all available space?

Actual and expected output

Complete included table definition (Rechnungstabelle.tex):

\newcommand{\Rechnungstabelle}[4]{%
vielen Dank für Ihren Auftrag.
\noindent
\begin{tabularx}{\textwidth}[ht]{lXrr}%
\toprule%
\bf{Anzahl} & \bf{Bezeichnung} & \bf{Einzelpreis} & \bf{Gesamtpreis} \\%
\midrule%
#1%
\bottomrule%
& \bf{Rechnungsbetrag}  & & \bf{\EUR{#2}} \\%
\ifthenelse{\equal{#3}{}}{}{& Enthaltene MwSt. 19\% & & \EUR{#3} \\}%
\ifthenelse{\equal{#4}{}}{}{& * Enthaltene MwSt. 7\% & & \EUR{#4} \\}%
\end{tabularx}%
}

Changing the table header row to

\bf{Anzahl} & \bf{Bezeichnung} \hspace{\textwidth} & \bf{Einzelpreis} & \bf{Gesamtpreis} \\%

is a workaround, but I don't think that would be good TeX style.

Minimum example for reproducing:

\documentclass[ fontsize=12pt, 
                paper=a4,
                foldmarks=TBMPL,
                fromalign=center,
                ngerman
                ]{scrlttr2}
\usepackage{babel}
\usepackage[utf8]{inputenx}
\usepackage[right]{eurosym}
\usepackage{tabularx}
\usepackage{ltablex}
\usepackage{booktabs}
\usepackage{ifthen}

\input{Rechnungstabelle}
\begin{document}
\begin{letter}

\Rechnungstabelle{
    1,0 h & Do something & \EUR{99,00} & \EUR{99,00} \\ 
    }
    {99,00}
    {}{}
\end{letter}
\end{document}

Best Answer

ltablex is the culprit here, as it modifies the tabularx environment. If you're not using it, remove it, or consider ltxtable which provides similar functionality using a different environment.

You may be interested in the following definition of \Rechnungstabelle (note the paragraph break before \noindent):

% https://tex.stackexchange.com/a/58638/5764
\makeatletter
\def\ifemptyarg#1{%
  \if\relax\detokenize{#1}\relax % H. Oberdiek
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
\makeatother

\newcommand{\Rechnungstabelle}[4]{%
  vielen Dank für Ihren Auftrag.

  \noindent
  \begin{tabularx}{\linewidth}{lXrr}%
    \toprule%
    \textbf{Anzahl} & \textbf{Bezeichnung} & \textbf{Einzelpreis} & \textbf{Gesamtpreis} \\%
    \midrule%
    #1%
    \bottomrule%
    & \textbf{Rechnungsbetrag}  & & \textbf{\EUR{#2}} \\%
    \ifemptyarg{#3}{}{& Enthaltene MwSt. 19\% & & \EUR{#3} \\}%
    \ifemptyarg{#4}{}{& * Enthaltene MwSt. 7\% & & \EUR{#4}}%
  \end{tabularx}%
}

I've dropped the use of \ifthenelse (see Why is the ifthen package obsolete?) and used \ifemptyarg from Different command definitions with and without optional argument.