# Extract Highlighted Text from PDF to Excel Rows

- Author: FastBankConvert (https://fastbankconvert.com)
- Published: 2026-10-17
- Category: Tables and data from PDFs
- Canonical: https://fastbankconvert.com/blog/extract-highlighted-text-from-pdf-to-excel

> Extract highlighted text from a PDF to Excel: export highlight annotations with their page numbers, and why highlights on scans hold no text.
To extract highlighted text from a PDF to Excel, list the highlight annotations on each page, then read the words that sit under each one. A highlight stores its position and colour, not the text, so a script or reader export has to recover the words, and you get one Excel row per highlight with its page.

## What a PDF highlight annotation actually stores

A highlight in a PDF is an annotation: a separate object laid over the page that records where the coloured marks are, what colour they are, and any note you typed. It usually does not hold the highlighted words. The words stay in the page text underneath, untouched.

### Coordinates, not words

[The pypdf guide to reading PDF annotations](https://pypdf.readthedocs.io/en/stable/user/reading-pdf-annotations.html) shows highlights identified by the subtype `/Highlight` and read through their `/QuadPoints` value, which unpacks into eight numbers: the four corners of a marked area. A highlight that covers three lines carries one set of corners per line. Nothing in that list is text. To know what was highlighted, something has to look at the page and find the words inside those corners.

### Notes are a different field

When you add a comment to a highlight, the comment is stored in the annotation as its own text. That note travels with the highlight and is easy to export. The marked words are not. Some readers do copy the selected words into the note when you make the highlight, but that depends on the reader and its settings, so do not count on it for highlights someone else made.

Sticky notes, text boxes and other comment types work differently from highlights; [exporting PDF comments into a sheet](/blog/extract-comments-from-pdf-to-excel) covers those.

## How do you export highlight annotations with page numbers?

A short script lists every highlight annotation in a PDF along with the page it sits on. PyMuPDF's page object can filter its annotations by type, so the script asks each page for highlights only, then writes one row per highlight with the page number, colour and any attached note.

### Step list

1. Install the library with `pip install pymupdf`.
2. Open the PDF and loop over its pages.
3. On each page, ask for annotations of the highlight type.
4. For each one, record the page number, its colour, its note and its rectangle.
5. Read the words inside the rectangle, as the next section explains.
6. Write the rows to a CSV file that Excel opens.

### The script

```python
import csv, sys
import pymupdf

doc = pymupdf.open(sys.argv[1])
with open("highlights.csv", "w", newline="", encoding="utf-8-sig") as f:
    out = csv.writer(f)
    out.writerow(["page", "colour", "text", "note"])
    for page in doc:
        for annot in page.annots(types=[pymupdf.PDF_ANNOT_HIGHLIGHT]):
            text = page.get_textbox(annot.rect).replace("\n", " ").strip()
            colour = annot.colors.get("stroke")
            out.writerow([page.number + 1, colour, text, annot.info.get("content", "")])
```

[PyMuPDF's Page reference](https://pymupdf.readthedocs.io/en/latest/page.html) describes `annots()` as a generator over a page's annotations that takes an optional list of types, and warns that you cannot safely change annotations from inside that loop. Read only, as here, and it is fine.

### Example sheet

The rows below are examples from an imaginary contract review:

| page | colour | text | note |
| --- | --- | --- | --- |
| 3 | yellow | payment is due within 45 days of invoice | Check against our 30-day terms |
| 3 | yellow | late fees accrue at 1.5% per month | |
| 9 | green | either party may terminate with 60 days' notice | OK |
| 14 | red | liability is capped at fees paid in the prior 12 months | Ask legal |

The script writes colour as three numbers between 0 and 1. A lookup table on a second sheet turns the few colours you use into names, which makes filtering by colour easy.

## Reading the words under each highlight into Excel

The words under a highlight are recovered by asking the PDF library for the text inside the highlight's rectangle. That works cleanly for a highlight on one line. For a highlight that starts mid-line and wraps onto the next, the rectangle covers both full lines, so a few extra words at each end can creep in.

### Why the rectangle overshoots

The annotation's rectangle is drawn to enclose all of its marked areas. When a highlight runs from the middle of line 1 to the middle of line 2, the box spans the full width of both lines. Asking for the text in that box returns the start of line 1 and the end of line 2 as well. For short, single-line highlights, which most are, the problem does not arise.

### Tightening the text

If the extra words matter, read the text for each marked area separately rather than the whole rectangle. Each set of corners in the quad points covers one line, and asking for the words inside each one, then joining the results, gives the highlighted words only. Treat a word as inside a marked area when most of its width falls within it, since highlight edges rarely match word edges exactly.

### Keeping reading order

PyMuPDF returns annotations in the order they are stored, which is often the order they were made, not the order they appear on the page. To sort the sheet in reading order, write the rectangle's top coordinate to a hidden column, and sort by page, then by that column.

If you would rather keep the job inside Excel, a macro can call the same kind of tool, and [what a VBA macro can and cannot read from a PDF](/blog/pdf-to-excel-vba) explains the limits before you try.

## Why do highlights on scanned PDFs hold no text?

Highlights on a scanned PDF hold no text because there is no text on the page to hold: a scan is a picture, and the highlight sits on top of pixels. The script above will still find the highlight and its page, but the text column comes back empty.

### Getting the words back

There are two ways round it:

- **Run text recognition on the PDF first**, with a tool that adds an invisible text layer behind the image while keeping the annotations. Then rerun the script. Check the words, because recognition errors carry straight into your sheet.
- **Read the area as an image.** Crop each highlighted rectangle to a picture and run recognition on just that crop. This is slower, but it works when the tool that adds a text layer strips annotations.

### Highlights drawn into the image

Some scanned pages show highlighter pen marks made on paper before scanning. Those are colours in the picture, not annotations, and no script will list them. Recognition will read the words, but nothing marks which ones were highlighted, short of detecting the colour in the image. Adding text layers and many annotations also makes files bigger, and [the reasons a PDF grows so large](/blog/why-is-my-pdf-so-large) cover what to expect.

When highlights are one of several things you need from a document, [the guide to pulling fields from a PDF into Excel](/blog/extract-data-from-pdf-to-excel) sets out the other methods. FastBankConvert does not read annotations; its job is turning bank statement PDFs into Excel, CSV or JSON, and it is [opening to early sign-ups](/get-started).
