# Creating Tables in Latex

Exclusive offer: get 50% off this eBook here

### LaTeX Beginner's Guide — Save 50%

Create high-quality and professional-looking texts, articles, and books for Business and Science using LaTeX

$26.99$13.50
by Stefan Kottwitz | March 2011 | Beginner's Guides Open Source

LaTeX is a high-quality open source typesetting software that produces professional prints and PDF files.

In this article by Stefan Kottwitz, author of LaTeX Beginner's Guide, we will learn how to perform the following:

• Lining up text and data in columns
• Typesetting complex tables

## LaTeX Beginner's Guide

 Create high-quality and professional-looking texts, articles, and books for Business and Science using LaTeX

(For more resources on this subject, see here.)

# Writing in columns

Remember the time of the typewriter and early word processing software? When we needed to line up some text in columns, we could use tab stops. LaTeX provides a similar way to easily align text in columns, namely, the tabbing environment.

# Time for action – lining up information using the tabbing environment

We would like to present a quick overview regarding LaTeX. We shall present one point on each line, aligned at words and double colons:

1. Begin a new document and open a tabbing environment:
\documentclass{article}\begin{document}\begin{tabbing}
2. Write the text, set tab stops by \=, and end the line by \\:
\emph{Info:} \= Software \= : \= \LaTeX \\
3. Add further lines, move to the next tab stop by \>, and again end lines by \\:
\> Author \> : \> Leslie Lamport \\\> Website \> : \> www.latex-project.org
4. Close the tabbing environment and end the document:
\end{tabbing}\end{document}
5. Typeset to get the output:

## What just happened?

The tabbing environment that we used begins a new line. We used three simple tags for markup:

• \= sets a tab stop. We could put several tab stops on a line. If we use \= later, the next awaited tab stop would be reset to this position.
• \\ ends a row.
• \> goes to the next tab stop. This could also mean to go backwards.

This way, we can quickly produce columns containing left-aligned text. If the rows of the tabbing environment would reach the end of a page, it could continue on the next page. What if a column is too long, running over the tab stop? Let's see how to solve that.

# Time for action – lining up font commands

Now we shall create a table:

1. Begin a new document, like the one in step 1 of our previous example, but define a command for setting the font of our header:
\documentclass{article}\newcommand{\head}[1]{\textbf{#1}}\begin{document}\begin{tabbing}
2. Write the first row set tab stops by \= and use \> to move to the tab stops. Use the command \verb…|| to typeset the LaTeX commands:
\begin{tabbing}Family \= \verb|\textrm{...}| \= \head{Declaration} \= \kill  \> \head{Command} \> \head{Declaration} \> \head{Example}\\Family \> \verb|\textrm{...}| \> \verb|\rmfamily|  \> \rmfamily Example text\\  \> \verb|\textsf{...}| \> \verb|\sffamily|  \> \sffamily Example text\\  \> \verb|\texttt{...}| \> \verb|\ttfamily|  \> \ttfamily Example text\end{tabbing}
3. Typeset and examine:

4. As we can see, the tab stops are too narrow. We shall correct it. Create a new head row containing the tab stops; this time, we will mark the line by \kill to hide that line. Use filler text to specify the width between the tab stops. Complete it with further font commands:
\begin{tabbing}Family \= \verb|\textrm{...}| \= \head{Declaration} \= \kill  \> \head{Command} \> \head{Declaration} \> \head{Example}\\Family \> \verb|\textrm{...}| \> \verb|\rmfamily|  \> \rmfamily Example text\\  \> \verb|\textsf{...}| \> \verb|\sffamily|  \> \sffamily Example text\\  \> \verb|\texttt{...}| \> \verb|\ttfamily|  \> \ttfamily Example text\end{tabbing}
5. Typeset to get the result:

## What just happened?

After we noticed that our tab stops have been set too narrow, we constructed a new first row containing the tab stops. It consists of words representing the widest entries of each column. To hide this auxiliary row, we used the command \kill right at the end of the line; \kill at the end of a line causes this line to have no output.

Like in this example, the command \verb|code| typesets code "as it is", without interpreting commands within. Instead of |, any character may be chosen as the delimiter. \verb cannot be used in arguments of commands including \section and \footnote, and not in table heads.
For longer, verbatim text, use the environment with the same name: verbatim.

There are further useful commands:

• \+ at the end of a line causes each subsequent line to start at the first tab. Use it twice \+\+ to start at the second tab and so on.
• \- cancels a preceding \+; also using multiply has cumulative effect.
• \< at the beginning of a line cancels the effect of one previous \+ command for that line.

The mentioned commands already allow a good use of the tabbing environment. Even more commands can be found in the reference manual: http://texblog.net/help/latex/ tabbing.html.

Inside tabbing environments, declarations are local to the current item. A following \=, \>, \\, or \kill command would stop the effect.
Tabbing environments cannot be nested.

 Create high-quality and professional-looking texts, articles, and books for Business and Science using LaTeX
Published: March 2011
eBook Price: $26.99 Book Price:$44.99
See more

(For more resources on this subject, see here.)

# Typesetting tables

We might need more complicated structures and formatting, like centering in columns, dividing lines, or even nested structures. LaTeX provides the tabular environment for typesetting simple and complex tables which can be nested.

# Time for action – building a table of font family commands

We shall create a table like in the previous example, but this time, we would like to make all entries in a column horizontally centered to each other. We will also add some horizontal lines to mark the border and the header of the table:

1. Create a new document. Define a command for setting the font for the head row:
\documentclass{article}\newcommand{\head}[1]{\textnormal{\textbf{#1}}}\begin{document}
2. Begin a tabular environment. As a mandatory argument, provide ccc standing for three centered columns:
\begin{tabular}{ccc}
3. Write the table head row, write & to separate column entries, and \\ to end rows. Use \hline to insert horizontal lines:
  \hline  \head{Command} & \head{Declaration} & \head{Output}\\  \hline
4. Continue with the table body and end the environment and the document. For typesetting LaTeX commands, write \verb\command||:
  \verb|\textrm| & \verb|\rmfamily| & \rmfamily Example text\\  \verb|\textsf| & \verb|\sffamily| & \sffamily Example text\\  \verb|\texttt| & \verb|\ttfamily| & \ttfamily Example text\\  \hline\end{tabular}\end{document}
5. Typeset to see the table:

## What just happened?

In the mandatory argument, we wrote a list of characters. Each character stands for a formatting option. As we used three characters, we've got three columns. c stands for centered alignment. Therefore, the entries of all columns have been centered.

Column entries are separated by &, while rows are terminated by \\. Don't end the last line by \\ unless you further wish to write a line below. It's also a good idea to align the ampersands in our source code to keep it readable.

Inside the entries, you may use ordinary text as well as LaTeX commands. As in the tabbing environment, declarations are local to the entry, like if each entry was surrounded by curly braces.

Furthermore, tabular has an optional alignment argument just like minipage. So, the complete definition is:

\begin{tabular}[position]{column specifiers}row 1 col 1 entry & row 1 col 2 entry ... & row 1 col n entry\\ ...\end{tabular}

In the optional argument, t means alignment at the top row and b means alignment at the bottom row. The default is vertically centered alignment. This may come in handy if you would like to place two tables next to each other or within further text.

## Drawing lines in tables

Within tabular, three types of lines may be used:

• \hline draws a horizontal line over the whole width of the table
• \cline{m-n} draws a horizontal line starting at the beginning of column m and ending at the end of column n
• \vline draws a vertical line over the full height and depth of the current row

## Understanding formatting arguments

Of course, further formatting is possible. Have a look at this example table:

\begin{tabular}{|l|c|r|p{1.7cm}|}  \hlineleft & centered & right & a fully justified paragraph cell\\\hline  l & c & r & p\\  \hline\end{tabular}

This code would produce the following table:

The options understood by the tabular environment are as follows:

• l for left alignment.
• c for centered alignment.
• r for right alignment.
• p{width} for a "paragraph" cell of a certain width. . If you place several p cells next to each other, they will be aligned at their top line. It's equivalent to using \parbox[t]{width} within a cell.
• @{code} inserts code instead of empty space before or after a column. This might also be some text or it could be left empty to avoid this space.
• | stands for a vertical line.
• *{n}{options} is equivalent to n copies of options, where n is a positive integer and options may consist of one or more column specifiers including * as well.

It is very advisable to avoid vertical lines in tables. Lines should subtly support your information but not make reading difficult.

After loading the array package by \usepackage{array} you may use some options, such as:

• m{width} is similar to \parbox{width}: the base line is at the middle
• b{width} is like \parbox[b]{width}: the base line is at the bottom
• !{code} can be used like | but inserts code instead of a vertical line. In contrast to @{…}, the space between columns will not be suppressed.
• >{code} can be used before an l, c, r, p, m, or b option and inserts code right at the beginning of each entry of that column
• <{code} can be used after an l, c, r, p, m, or b option and inserts code at the end of the entry of that column

This example shows the effect of @{} and the alignment arguments p, m, and b:

\begin{tabular}{@{}lp{1.2cm}m{1.2cm}b{1.2cm}@{}}  \hlinebaseline & aligned at the top & aligned at the middle& aligned at the bottom\\  \hline\end{tabular}

The output table is as follows:

## Increasing the row height

You may have noticed that horizontal lines nearly touch the letters in the cells, especially capital letters. The array package introduces a length called \extrarowheight . If it has a positive value, this will be added to the height of every row of the table.

The next example, following the very first example of this article, shows how to extend the row height and shows the effect of the remaining array options:

\documentclass{article}\usepackage{array}\setlength{\extrarowheight}{4pt}\begin{document}\begin{tabular}{@{}>{\itshape}ll!{:}l<{.}@{}}  \hline  Info: & Software & \LaTeX\\& Author & Leslie Lamport\\& Website & www.latex-project.org\\\hline\end{tabular}\end{document}

The output is as follows:

Here, >{\itshape} has been used to change the font of a row to italic. >{} is often used to insert an alignment declaration, but there's a pitfall: such declarations might change the internal meaning of \\, which is a shortcut for \tabularnewline within tables. But the array package offers a command to repair it; in such cases, just add \arraybackslash, for example:

\begin{tabular}{>{\centering\arraybackslash}p{5cm}}

Otherwise, the content of paragraph cells stated by p, m, or b will be fully justified.

After a specific row, you can add vertical space by the optional argument of \\, such as \\[10pt].

You may even stretch a whole table: the macro \arraystretch contains a stretching factor with a default value of 1. Just redefine it. For example, \renewcommand{\arraystretch} {1.5} will increase the height of the rows by 50 percent. You could use it inside a group or an environment to keep the effect local.

## Beautifying tables

Still our tables don't look as perfect as they look in good books. Especially, the lines and their distances to the text might need improvement. The booktabs package comes to the rescue; after loading it, you can enhance the quality of your tables by new line commands replacing \hline and \cline.

# Time for action – adding nicer horizontal lines with the booktabs package

We shall use the new commands introduced by booktabs:

1. In the previous example, load the package booktabs:
\usepackage{booktabs}
2. Use \toprule, \midrule, and \bottomrule instead of \hline. Specify a thickness as an optional argument:
\begin{tabular}{ccc}  \toprule[1.5pt]  \head{Command} & \head{Declaration} & \head{Output}\\  \midrule  \verb|\textrm| & \verb|\rmfamily| & \rmfamily Example text\\  \verb|\textsf| & \verb|\sffamily| & \sffamily Example text\\  \verb|\texttt| & \verb|\ttfamily| & \ttfamily Example text\\  \bottomrule[1.5pt]\end{tabular}
3. Typeset to see the difference:

## What just happened?

British typesetters call a line a rule. The booktabs developer chose this terminology for the new commands. We used three of them. These are their definitions:

• \toprule[thickness] may be used to draw a horizontal line at the top of the table. If desired, a thickness may be specified, like 1pt or 0.5mm.
• \midrule[thickness] draws a horizontal dividing line between rows of a table.
• \bottomrule[thickness] draws a horizontal line to finish off a table.
• \cmidrule[thickness](trim){m–n} draws a horizontal line from column m to column n. (trim) is optional like thickness, it could be (l) or (r) to trim the line at its left or right end. Write (lr) to trim at both ends. Even adding {width}, like in (l{10pt}), is possible and specifies the trim width.

The package does not define vertical lines. They are not advisable anyway. The same applies to double rules. Neither vertical nor double rules are recommended. They are even widely considered to be bad typographic style.

Consider using \toprule and the other line commands without optional arguments—let's figure out how.

### Have a go hero – adjusting lengths

We briefly introduced the command \setlength. Instead of specifying a line thickness by an optional argument to \toprule, \midrule, \cmidrule, or \bottomrule, always omit it. Instead, specify it once for your whole document by \setlength in the preamble.

These are the lengths that may be adjusted:

• \heavyrulewidth for the thickness of the top and bottom lines
• \lightrulewidth for the thickness of the middle lines by \midrule
• \cmidrulewidth for the thickness of \cmidrule
• \cmidrulekern for the trimming in \cmidrule
• \abovetopsep is the space above the top rule; the default is 0pt
• \belowbottomsep is the space below the bottom rule; the default is 0pt
• \aboverulesep specifies the space above \midrule, \cmidrule, and \bottomrule
• \belowrulesep stands for the space below \midrule, \cmidrule, and \toprule

Try to change the thickness of the lines. The lengths already have reasoned values, but you may change them. So, the adjustment in your preamble would improve all tables in your document.

## Spanning entries over multiple columns

Columns concerning the same subject might be grouped by a common header. In such a case, two cells in the header should be merged. The command \multicolumn does it for us.

# Time for action – merging cells

Regarding our example table, commands and declarations are both input, whereas, the remaining column contains output. We shall emphasize that in our header:

1. In our example, insert another header row. Use \multicolumn to merge cells. Alter the column formatting argument and the middle rule. Changes are highlighted:
\begin{tabular}{@{}*3l@{}}  \toprule[1.5pt]  \multicolumn{2}{c}{\head{Input}} &  \multicolumn{1}{c}{\head{Output}}\\  \head{Command} & \head{Declaration} & \\  \cmidrule(r){1-2}\cmidrule(l){3-3}  \verb|\textrm| & \verb|\rmfamily| & \rmfamily Example text\\  \verb|\textsf| & \verb|\sffamily| & \sffamily Example text\\  \verb|\texttt| & \verb|\ttfamily| & \ttfamily Example text\\  \bottomrule[1.5pt]\end{tabular}
2. Typeset and see the output:

## What just happened?

We used the command \multicolumn twice; once to merge two cells and surprisingly another time just for one cell. Let's first look at its definition:

\multicolumn{number of columns}{formatting options}{entry text}

The number of columns to be spanned may be a positive integer or just 1. The formatting options will be applied instead of the options specified in the tabular definition for this cell. We took advantage of this when we used \multicolumn{1}{c}{…}, overriding the l option of the column by a c option to get just this cell centered.

The other change we made concerns \cmidrule. We used it instead of \midrule together with the trimming argument to get a gap between the input and the output column.

## Inserting code column-wise

There are many more font commands that we would like to add to the table. Writing \verb…|| in each cell is tiresome. We shall exploit the >{…} feature of the array package to define the formatting of the entries once for the column.

 Create high-quality and professional-looking texts, articles, and books for Business and Science using LaTeX
Published: March 2011
eBook Price: $26.99 Book Price:$44.99
See more

(For more resources on this subject, see here.)

# Time for action – using the array package

We shall modify the table definition to set our input columns in the typewriter font. At the same time, we will insert a column on the left, standing for our command type:

1. Extend the preamble of our example by defining a command \normal. It shall use \multicolumn to produce an l cell, no matter what the column formatting is:
2. As \verb cannot be used in table headers, we shall use \ttfamily. Preceding it with \textbackslash is enough for our purposes. Use >{…} to insert it twice. Then add <{Example text} to the last column to save typing work:
\begin{tabular}{@{}l*2{>{\textbackslash\ttfamily}l}l%<{Example text}@{}}  \toprule[1.5pt]& \multicolumn{2}{c}{\head{Input}} &    \multicolumn{1}{c}{\head{Output}}\\
3. We'll use the \normal command to avoid the typewriter formatting in the header:
& \normal{\head{Command}} & \normal{\head{Declaration}}& \normal{}\\  \cmidrule(lr){2-3}\cmidrule(l){4-4}
4. Now we may continue listing the font command names:
  Family & textrm&rmfamily & \rmfamily\\& textsf & sffamily & \sffamily\\& texttt & ttfamily & \ttfamily\\  \bottomrule[1.5pt]\end{tabular}\end{document}
5. Typeset and look at the result:

## What just happened?

Using >{\textbackslash\ttfamily}l defines a left aligned row, where each entry is preceded by a backslash and by switching to typewriter font. We wrote *2{…} to define two columns of this style. Because the example text has been inserted according to our table definition with <{…}, we just had to put the declarations into the last column without the text.

## Spanning entries over multiple rows

We already know how to span text over several columns. But what if text should cross over several rows? LaTeX doesn't define a command for it. However, the package multirow does.

# Time for action – merging cells using the multirow package

Before we complement the font table, we would like to center the command type "Family" vertically, that is, span this cell over three columns. If we figured this out, we could use it later on:

\usepackage{multirow}
2. Replace the word «Family»:
\multirow{3}{*}{Family} & textrm & rmfamily & \rmfamily & \\
3. Typeset to see the small change:

## What just happened?

We used the command \multirow to span three rows. Its definition is:

\multirow{number of rows}{width}{entry text}

The entry will span that number of rows from the row on which \multirow has been used. If the number is negative, it will span the rows above.

You can specify a width or just write * for the natural width. If a width has been specified, the text would be wrapped accordingly.

multirow understands further optional arguments for fine tuning. They are described in its documentation.

Especially with longer text, we would like to add captions and numbers to our tables. Numbering the tables allows referring to them, whereas captions are informative, if the table is not exactly placed where we refer to it. LaTeX has built-in features to achieve that.

# Time for action – adding a caption to our font table

Now it's time to complete our table. We shall list the remaining font commands. We'll use the first column to describe the category of the font commands: Family, Weight, Shape, and so on. Then we will add another column to show the effect of combining font commands.

To finish, we shall center the table and provide a number and a caption:

1. Put a table environment around our example table, use \centering inside, and insert a \caption command at the end of the table environment. Add more font commands and add another column at the right containing more examples:
2. Typeset and our table is now ready:

## What just happened?

We put the tabular environment in a table environment. It's used in this way together with the \caption command:

\begin{table}[placement options]table body\caption{table title}\end{table}

The table environment is a so-called floating environment. Unlike normal text, they might appear somewhere else other than what is defined by their position in the source code. The optional placement argument determines where the table might appear. However, LaTeX decides it.

\caption understands an optional argument as well: if you write \caption[short text]{long text}, then short text will appear in a list of tables and long text in the document body. That's useful if you need very long descriptive captions.

Tables are automatically numbered.

## Placing captions above

In typesetting, it's very common to place captions above the tables instead of below. This can be achieved by writing \caption before the table body. However, LaTeX expects caption to always be below, resulting in a cramped look to the table. There's too little space between the caption and the following table. You might wish to add some space, for instance, by entering \vspace{10pt} directly after a top caption.

Remember booktabs? If you begin tables with \toprule, just specify the length \abovetopskip, for example:

\setlength{\abovetopsep}{10pt}

By putting this line into your preamble, 10pt space would be added below the caption and above the top line of the table.

### Have a go hero – customizing captions

By default, the captions look like normal body text; there's no visual difference. Would you like to have a slight change in font size, a different formatting of the label, some margins or indentation, or any other customization? The caption package is the answer to most needs. By using a few options, you could enhance the visual appearance of all of your captions. Try:

\usepackage[font=small,labelfont=bf,margin=1cm]{caption}

This way, your captions will be smaller than normal text, the label with number will be bold, and it will not be as wide as normal text. The package offers a lot of features, both for document wide settings and fine-tuning. It's very well documented. So, have a look at its documentation.

## Auto-fitting columns to the table width

l, c, and r columns have the width of their content. For p columns, you specify the width. This way, it's hard to find out the actual width of the table. Wouldn't it be a good idea to specify the table width and let LaTeX decide how wide the columns may be? The tabularx package allows that. Using it looks like:

\usepackage{tabularx}...\begin{tabularx}{width}{column specifiers}...\end{tabularx}

The new environment tabularx requires an additional argument: the width of the table. It introduces a new column type X. X columns behave like p columns, but they use all available space. One X column would take all of the available space. If you use several X columns, they would share the space equally. So you could write, for instance:

\begin{tabularx}{0.6\textwidth}{lcX}

This way you would get a table occupying 60 percent of the text width, a left aligned and a centered column as wide as their content, and a paragraph column as wide as possible until 60 percent is reached.

Though it's easy to use, the tabularx documentation gives further examples, informs about the derived types, and gives advice like this: don't let \multicolumn entries cross any X column.

There are two similar approaches:

• LaTeX provides a starred version of the tabular environment:
\begin{tabular*}{width}[position]{column specifiers}

The table is set to width, but by modifying the inter-column space. tabularx has been developed satisfying the need for a more useful way.

• The tabulary package provides another sophisticated tabular environment taking the total width. It's weighting each column width according to the natural width of the widest cell in the column.

## Generating multi-page tables

All tabular environments we've got to know until now cannot cross page boundaries. The tabbing environment is an exception due to its different nature.

As tables might contain a lot of data, we need a solution. There are several packages:

• longtable provides an environment with the same name that's like a multi-page version of tabular. It provides commands to set table captions, continued captions, and special headers and footers when a page break occurs. It's probably the easiest way for multi-page tables and therefore the most popular. The package documentation describes all you need. In combination with the booktabs package, you will get very good results.
• ltxtable provides a combination of longtable and tabularx.
• ltablex is another approach to combine the features of longtable and tabularx.
• supertabular offers another multi-page extension of the internally used tabular environment, providing optional table tails and heads where page breaks occur.
• xtab extends supertabular and reduces some of its weaknesses.
• stabular implements a simple way to use page breaks in tabular without much ado.

Example tables and links to documentation can be found at
http://texblog.net/beginners-guide/tables/.

## Coloring tables

We didn't even color text yet, as this usually isn't what we do first with LaTeX. But of course, this can be done with text as well as with tables. For coloring text, use the color package or, better, the extension xcolor. For coloring tables, use the package colortbl. All can be combined by using:

\usepackage[table]{xcolor}

The package allows coloring columns, rows, single entries, and lines in many ways. The package documentation may tell you more.

## Using landscape orientation

Very wide tables could be typeset in landscape orientation. The rotating package offers an environment called sidewaystable that you could use instead of the table environment. Both table and caption would be rotated +-90 degrees and placed on a separate page. The package provides further rotation-related environments and commands.

## Aligning columns at the decimal point

Columns containing numbers are more readable when the entries are aligned at the decimal marker and perhaps at an exponent. Several packages support this:

• siunitx is primarily intended for typesetting values with units in a consistent way according to scientific conventions. However, it provides a tabular column type for such decimal alignment of numbers.
• dcolumn offers a column type for aligning at a comma, a period, or another single character.
• rccol defines a column type where numbers are "right-centered", that is, they are centered with respect to other entries but flushed right to each other. This way corresponding digits are aligned along the column.

In contrast to dcolumn and rccol, the siunitx package is very new and powerful.

## Handling narrow columns

Text in very narrow columns might require special attention because justification is difficult if there's little space. Here's some advice:

• Have a look at the correct hyphenation.
• TeX doesn't hyphenate the first word of a line, a box, or a table entry. So, a long word may cross the column boundary. To enable hyphenation, insert an empty word: write \hspace{0pt} directly at the beginning.
• Load microtype to improve justification, it shows the best effect in narrow columns.
• Full justification in p columns and the like may look bad because of big gaps. Consider using >{\raggedright\arraybackslash} for such columns.
• From the ragged2e package, using the command \RaggedRight can do even better and doesn't need \arraybackslash.

# Summary

In this article, we have learned to create tables. Specifically, we dealt with:

• Putting text into columns
• Typesetting tables with captions
• Spanning columns and rows in tables
• Using packages to auto-fit columns and to create colored, landscape, and even multi-page tables

Further resources on this subject:

## Stefan Kottwitz

Stefan Kottwitz studied mathematics in Jena and Hamburg. Afterwards, he worked as an IT Administrator and Communication Officer onboard cruise ships for AIDA Cruises and for Hapag-Lloyd Cruises. Following 10 years of sailing around the world, he is now employed as a Network & IT Security Engineer for AIDA Cruises, focusing on network infrastructure and security such as managing firewall systems for headquarters and fleet.

In between contracts, he worked as a freelance programmer and typography designer. For many years he has been providing LaTeX support in online forums. He became a moderator of the web forum http://latex community.org/ and of the site http://golatex.de/. Recently, he began supporting the newly established Q&A site http://tex.stackexchange.com/ as a moderator.

He publishes ideas and news from the TeX world on his blog at http://texblog.net.