Skip to content
ATSPrep
Build my resume

Tables in resumes: what PDF and DOCX text extraction returns

We put a resume's experience and skills in tables, saved PDF and DOCX versions and read each with three extractors. The DOCX read cleanly; the PDFs didn't.

From What each reader made of the table
In this guide

A table in a resume is a set of cells the reader has to put back in order, and a PDF doesn't record which cell comes first. In our fixtures the Word table read cleanly as a DOCX. As PDFs, the same rows came back two ways: pdf.js read across each row, and pdftotext pulled the date column away from the roles. Our checker read the lines correctly but used to file no roles at all from the Word export; we fixed that on 20 October 2026 after these tests.

The short version

  • Word table as DOCX: our importer read 2 roles, 5 bullets and 5 skills, one cell per line.
  • pdf.js read both table PDFs row by row: “2021 - Present Senior Data Analyst, Northwind Traders Inc.”.
  • pdftotext split each date from its role in the Chromium PDF, and listed every date and skill before any role in the Word export.
  • pdftotext also reordered the skills grid to SQL, Python, dbt, Excel, Tableau.
  • Our checker used to file 0 roles from the Word table PDF and put job titles under Skills. Since our fix on 20 October 2026 it files 2 roles, 5 bullets and 5 skills.

What each reader made of the table

The fixtures put dates in a narrow left cell and the role with its bullets in the right cell, with skills in a three-across grid below.

Fixturepdf.jspdftotextATSPrep checker
HTML table saved as PDF (Chromium)row by rowdates split from roles, skills reordered2 roles, 5 bullets, 5 skills
Word table (DOCX)not a PDFnot a PDF2 roles, 5 bullets, 5 skills
The same Word table saved as PDFrow by rowevery date and skill before the roles2 roles, 5 bullets, 5 skills
Table fixtures by reader

Tables in a PDF

A PDF has no table object in its page content. Cell borders are lines, and the text in each cell is placed independently. An extractor either follows the order the text was written in, as pdf.js does, or rebuilds rows and columns from position, as pdftotext's default mode does.

In the Word table exported by LibreOffice 26.8.1.1, pdftotext treated the date column as its own block and returned both dates and every skill before the first role. pdf.js returned clean rows, and so did our checker's line text, but its section mapping used to fail: no roles, no bullets, and job titles and bullets filed under Skills. It took the gap between the date cells and the entries for the gap between two columns.

We fixed that on 20 October 2026 after these tests. A narrow left strip that holds every heading while the wider right side holds none is now read as part of a table, not as a column of its own, so the checker keeps each date with its role.

  1. 012021 - Present
  2. 022018 - 2021
  3. 03SKILLS
  4. 04SQL
  5. 05dbt
  6. 06Python
  7. 07Excel
  8. 08Senior Data Analyst, Northwind Traders Inc.
  9. 09[U+F0B7] Cut weekly reporting time from 6 hours to 40
  10. 10minutes by automating SQL pipelines
  11. 11[U+F0B7] Built a churn model that three regional sales
  12. 12teams now use to plan renewals
  13. 13[U+F0B7] Trained 12 analysts on dbt and code review
  14. 14Data Analyst, Contoso Ltd.
  15. 15[U+F0B7] Rebuilt the finance dashboard in Tableau
  16. 16[U+F0B7] Wrote the data dictionary used by every new
  17. 17hire
  18. 18Tableau
Before: Word table saved as PDF (pdftotext 26.10.0, table-word-pdf.pdf)
  1. 01SQL
  2. 02Python
  3. 03Tableau
  4. 04dbt
  5. 05Excel
Since the fix: what the ATSPrep checker files under Skills (table-word-pdf.pdf)
  1. 01Maya Ortiz
  2. 02maya.ortiz@example.com | (555) 010-4477 | Denver, CO
  3. 03EXPERIENCE
  4. 04Senior Data Analyst, Northwind Traders Inc. | 2021 - Present
  5. 05• Cut weekly reporting time from 6 hours to 40 minutes by automating SQL pipelines
  6. 06• Built a churn model that three regional sales teams now use to plan renewals
  7. 07• Trained 12 analysts on dbt and code review
  8. 08SKILLS
  9. 09SQL, Python, Tableau, dbt, Excel
  10. 10EDUCATION
  11. 11B.S. Statistics, Lakeview University, 2018
After: the same content as a single column (the ATSPrep checker, order-single-column.pdf)

Skills grids

A grid of skills is the most common resume table. pdf.js returned it row by row, so the words stayed in the order typed. pdftotext read it column by column and returned SQL, Python, dbt, Excel, Tableau. Nothing was lost, but a parser that expects one skill per cell or a comma list gets neither.

  1. 01SKILLS
  2. 02SQL Python Tableau
  3. 03dbt Excel
Skills grid (pdf.js 6.3.289, table-experience.pdf)
  1. 01SKILLS
  2. 02SQL
  3. 03Python
  4. 04dbt
  5. 05Excel
  6. 06Tableau
Skills grid (pdftotext 26.10.0, table-experience.pdf)

Tables in a DOCX

A DOCX stores a table as rows of cells in document order, so the reading order is written into the file. Our importer read the Word table one cell per line, with every role, bullet and skill in place. If a portal accepts DOCX and your resume must keep a table, the DOCX is the safer upload.

  1. 01EXPERIENCE
  2. 022021 - Present
  3. 03Senior Data Analyst, Northwind Traders Inc.
  4. 04• Cut weekly reporting time from 6 hours to 40 minutes by automating SQL pipelines
  5. 05• Built a churn model that three regional sales teams now use to plan renewals
  6. 06• Trained 12 analysts on dbt and code review
  7. 072018 - 2021
  8. 08Data Analyst, Contoso Ltd.
  9. 09• Rebuilt the finance dashboard in Tableau
Word table, as DOCX (the ATSPrep checker, table-word.docx)

What ATS vendors say about tables

Greenhouse's support article on unsuccessful resume parses (checked 19 October 2026) lists "Complex resumes with tables, headers, and footers" among the formatting issues that can lead to a partial parse that has to be corrected by hand.

Formatting best practices for tables and text extraction

  • Put each role on one line: title, employer and dates, followed by its bullets. No table needed.
  • Write skills as a comma-separated line under a SKILLS heading.
  • If you keep a table, upload the DOCX where the portal allows it.
  • Never put contact details or job titles in table cells.
  • Check a PDF export in two readers. If dates and roles come back apart, take the table out.

How we tested

We built every fixture from the same fictional one-page resume, changing one thing at a time. PDFs come from Chromium 153.0.8010.12 (printed through Playwright 1.63.0) and from LibreOffice 26.8.1.1 converting our DOCX files, the way Word users export. Each file was read three ways: pdf.js 6.3.289 getTextContent, poppler pdftotext 26.10.0 in its default mode, and the importer the ATSPrep checker runs in your browser. DOCX files have no PDF text layer, so only our importer reads them. The code blocks on this page are the readers' output, copied by script; private-use and control characters are written as [U+XXXX] because they would otherwise be invisible.

These are three common open readers, not any employer's applicant tracking system. Commercial parsers use their own extractors, so treat a failure here as a risk to remove, not a prediction of what a specific system will do.

Common questions

Are tables ATS friendly in a resume?

Not reliably in a PDF. In our test the same table PDF came back row by row in pdf.js and with dates pulled away from roles in pdftotext, and our checker filed no roles from the Word table export until we fixed it on 20 October 2026. As a DOCX the same table read cleanly. Greenhouse lists complex resumes with tables among its parse failure causes.

What are ATS resume formatting best practices for tables and text extraction?

Use one column, write each role as a line with title, employer and dates, list skills as a comma-separated line, and keep contact details as body text. If you need a table, upload a DOCX. Then check the export in an extractor and confirm every role comes back next to its dates.

Does a table in a DOCX extract better than a table in a PDF?

In our fixtures, yes. A DOCX stores cells in document order and our importer read every role, bullet and skill. The PDF export of the same table came back in different orders from pdf.js and pdftotext.

How should I list skills without a table?

One line under a SKILLS heading, separated by commas: SQL, Python, Tableau, dbt, Excel. That line came back identically from every reader we tested.

Sources and further reading

  1. Unsuccessful resume parse, Greenhouse Support
  2. pdftotext(1) manual page, poppler-utils, Debian
  3. PDFPageProxy.getTextContent, PDF.js API, Mozilla
  4. Test fixture: table-experience.pdf, ATSPrep
  5. Test fixture: table-word.docx, ATSPrep
  6. Test fixture: table-word-pdf.pdf, ATSPrep

Put it into practice on a real resume.

Each example is a complete resume with role keywords and bullets that show proof. Open one in the Studio and make it yours, then download it. The first download needs no account.

See what a parser reads in your own file.

The ATS checker reads your PDF or Word file with the same importer tested on this page and shows every line it got back, in order. It runs in your browser and the file isn't uploaded.

$0 forever · No watermark · No card · First download needs no account