Printdown

Markdown tables: from Excel or CSV to a clean PDF

By ·

A table is often the reason a document exists: a price list for a client, a training schedule, the data appendix of a report. The numbers usually live in a spreadsheet, and the result has to be a PDF. Markdown sits comfortably in between: its tables are plain text you can edit and keep under version control, and they print as clean, bordered tables. This guide covers the syntax, the trip from Excel or CSV, how tables behave on paper and what to do when one refuses to render.

Table syntax in one minute

The Markdown editor follows the GitHub Flavored Markdown rules for tables: rows of cells separated by pipes.

| Plan     | Users | Price per month |
| :------- | :---: | --------------: |
| Starter  | 1     | $9.00           |
| Team     | 10    | $49.00          |
| Business | 50    | $199.00         |
  • The first row is the header. A table has exactly one, printed in bold on a shaded background.
  • The second row is the delimiter row: at least one hyphen per column, and exactly as many columns as the header.
  • Colons set the alignment: :--- left (the default), :---: centered, ---: right. Right-align prices and quantities so the digits line up.
  • Outer pipes are optional but make mistakes easier to spot. Columns need not line up in the source; padding is only for your eyes.
  • Leave a blank line before and after the table.

The complete rules are in the GitHub Flavored Markdown spec.

What fits inside a cell

Cells accept inline Markdown: bold, italics, strikethrough, `code`, links and footnote references. Three things need care:

  • A literal pipe must be escaped as \|, or it starts a new cell. That includes pipes inside backticks.
  • Line breaks: each row is a single line of source, so pressing Enter ends the row. Use <br> to break a line inside a cell.
  • Block elements (real lists, several paragraphs, code blocks) cannot go in a cell. Fake a short list with <br>, or move a long remark to a footnote, printed at the end of the document.
| Step | Command | Notes |
| ---- | ------- | ----- |
| 1 | `npm install` | Downloads the dependencies |
| 2 | `sort log.txt \| uniq` | Removes repeated lines[^1] |
| 3 | `npm run build` | Takes about a minute<br>Output goes to **dist/** |

[^1]: The backslash keeps the pipe inside the cell.

From Excel to a Markdown table

Open the Excel to Markdown converter and drop your workbook (.xlsx, .xlsm, .xlsb or the older .xls). It is read inside your browser, so confidential figures never leave your computer. The Markdown appears in a text box where you can edit it before you Copy it, Download .md or click Open in editor → PDF.

What the conversion does with each part of a spreadsheet:

  • Sheets: each sheet becomes its own table, preceded by a ## Sheet name heading when there is more than one. Empty and hidden sheets are skipped, as are hidden rows and columns, so hiding is a quick way to leave out helper columns.
  • Header row: the first row becomes the header only if it has a value in every column. With a title above the table, a merged title or a blank column name, you get an empty header row and your real headers end up in the body. Put the column names in row 1 and give every column a name.
  • Empty rows between your data are kept as blank rows (| | | |). Delete them in the spreadsheet or in the text box.
  • Formulas come out as their last calculated value. A file generated by another program may lack those values and show empty cells; open and save it in Excel once.
  • Number formats are applied: currency symbols, percentages, thousands separators and decimal places appear as formatted ($1,234.50, 15%), always with a comma for thousands and a period for decimals, whatever your regional settings.
  • Dates and times are written in ISO format, such as 2026-03-01 or 2026-11-20 14:30:00, whatever display format the cell uses.
  • Merged cells keep their value in the top-left cell; the cells they covered stay empty.
  • Lost on the way: bold, colors, borders and charts. Hyperlinks keep only their visible text, a line break inside a cell becomes a space, and characters like * are escaped, so text that looks like Markdown prints literally.

Every column comes out left-aligned. Before printing, change the delimiter row to ---: under numeric columns.

From CSV

CSV is what most tools export: Google Sheets, Numbers, accounting software, databases and Notion databases. Drop the file on the CSV to Markdown converter:

  • The separator is detected automatically: commas, semicolons (common where the comma is the decimal separator) and tabs all work.
  • Quoted values that contain the separator stay in one cell, and pipes are escaped as \|.
  • CSV is plain text, so values are kept exactly as written: dates are not reformatted and leading zeros survive (0012). Blank lines are skipped.
  • The header rule is the same as for Excel: the first line must name every column.
  • Files ending in .tsv or .txt are not recognized. Rename them to .csv first.

Want dates as shown on screen rather than in ISO format? Save the sheet as CSV from your spreadsheet app, which usually writes values as displayed, and convert that.

Getting the table into your document

Open in editor → PDF replaces whatever is in the editor, which suits a table-only document. To add the table to an existing one, click Copy instead and paste it in, with a blank line above and below.

How tables print

In the PDF, tables span the full width of the text, with thin borders, a shaded header row and type slightly smaller than the body.

  • Long tables continue across pages, and a row is never split between two pages. With Download PDF, the header row is repeated at the top of each page (in Chrome, Edge and Firefox). Quick PDF saves the pages as images and does not repeat it.
  • Header shading: if it prints white, turn on Background graphics in the print dialog.
  • Wide tables: columns shrink and text wraps, but a long URL, code or word without spaces cannot wrap; it pushes the table past the right margin and the PDF cuts it off. If a table sticks out in the preview, it will on paper too.
  • Orientation: there is no landscape option. Pages are A4 or Letter, in portrait.

To make a wide table fit, try these in order: lower the Font size in the Style panel (9 to 14 pt; it scales the whole document), set Margins to Narrow (12 mm instead of 20), replace long URLs with short link text such as [report](https://…), abbreviate column names and explain them under the table, and, as a last resort, split the table in two or swap rows and columns. To start a big table on a fresh page, put <!-- pagebreak --> on its own line before it.

Four recipes

Comparison

Options in columns, criteria in rows: three or four options fit a portrait page.

| | Supplier A | Supplier B | Supplier C |
| --- | :---: | :---: | :---: |
| Price per unit | $4.20 | $3.95 | $4.10 |
| Delivery | 3 days | 10 days | 5 days |
| Free returns | No | No | Yes |
| **Verdict** | Fastest | Cheapest | **Best value** |

Price list

Right-align the prices, bold the total and move conditions to a footnote.

| Service | Unit | Price |
| --- | --- | ---: |
| Website audit | per site | $450.00 |
| Copywriting | per page | $120.00 |
| Maintenance[^1] | per month | $90.00 |
| **Total, first month** | | **$660.00** |

[^1]: Minimum term of three months.

Schedule

Times down the side, days across the top; <br> keeps a two-line entry in one cell.

| Time | Monday | Tuesday |
| --- | --- | --- |
| 09:00 | Kick-off | Workshop: data model |
| 11:00 | Interviews<br>Rooms 2 and 3 | Workshop, continued |
| 14:00 | Site visit | Wrap-up and next steps |

Data appendix

Keep a summary in the body and the full data at the end, after a page break, where the repeated header row pays off.

<!-- pagebreak -->

## Appendix A. Monthly sales by region

| Month | North | South | Total |
| --- | ---: | ---: | ---: |
| January | 12,400 | 9,800 | 22,200 |
| February | 11,950 | 10,300 | 22,250 |

When a table is the wrong tool

  • Cells that need paragraphs or lists: give each item a ### heading with a list underneath.
  • A single column of values is simply a list.
  • More than seven or eight columns, or thousands of rows: summarize, and share the spreadsheet separately.
  • Page layout, such as text blocks side by side: tables are for data.

Troubleshooting

  • The table appears as plain text with pipes. Count the columns: the delimiter row needs exactly as many cells as the header, each with at least one hyphen. Also check that the table is not indented four spaces (that makes it a code block) and not glued to a list item without a blank line, which swallows it.
  • Data is missing from a row. Cells beyond the header’s column count are dropped without warning; shorter rows are padded with empty cells. An unescaped | in the text is the usual culprit.
  • The table stops halfway and the rest prints as lines of pipes: there is a blank line inside the table.
  • A sentence became a table row. Text on the line right after a table is read as another row. Add a blank line.
  • Part of a cell looks like a formula. The editor renders LaTeX between dollar signs, so a cell like between 5 $ and 10 $ turns into math. Escape the first sign: 5 \$.
  • The converted table has an empty header. Row 1 of the sheet was a title or had a blank cell. Fix the sheet and convert again, or delete the empty first line and the title rows, then move the real header above the --- line.
  • Codes changed slightly. Smart punctuation turns -- into an en dash (–) and straight quotes into curly ones. Wrap product codes and commands in backticks to keep them exactly as typed.

The Markdown guide covers everything else the editor supports.

More guides