Extracting text and data from PDF files
The extractor package handles all of it. Build an extractor for a page, then ask it
for text, tables, images or fonts.
page, err := pdfReader.GetPage(pageNum)
if err != nil {
return err
}
ex, err := extractor.New(page)
if err != nil {
return err
}
text, err := ex.ExtractText()
if err != nil {
return err
}
fmt.Println(text)Extraction is per page, so a whole document is a loop over GetPage.
What the extractor returns
| Call | Returns |
|---|---|
ExtractText() | The page text as one string. |
ExtractTextWithStats() | The same string, plus the character count and the number of characters that could not be decoded. |
ExtractPageText() | A *PageText and the same two counts. This is the structured form: text, marks, tables. |
ExtractPageImages(opts) | Every image drawn on the page with its position, displayed size and rotation. |
ExtractFonts(prev) | The fonts used, including embedded font files. Pass the previous page’s result to build a deduplicated list across a document. |
ExtractStrokePaths() | The stroked path geometry, in any extraction mode. |
Characters that cannot be decoded come back as U+FFFD rather than being dropped, so a
run of replacement characters in the output points at a font with a broken or missing
ToUnicode map, not at a bug in the extraction. ExtractTextWithStats gives you the
miss count without inspecting the string.
PageText is where the structure lives:
Text()is the same stringExtractTextreturns.Marks()gives everyTextMark, usually one per glyph, each with its bounding box, font, size, fill and stroke color.TextMarkArray.RangeOffsetmaps a substring of the extracted text back to the marks that produced it, andBBox()turns those into a rectangle, which is how you locate a phrase on the page.Tables()returns the detected tables as rows and cells.GridText()returns the fixed-width grid layout regardless of the mode in effect.ApplyArea(bbox)narrows everything above to a region of the page and can be called repeatedly with different rectangles.
Choosing an extraction mode
extractor.NewWithOptions takes an Options value, and ExtractionMode is the field
that changes the output most.
| Mode | What it does |
|---|---|
ExtractionModeLayout (default) | Infers paragraphs, reading order and tables. Marks() and Tables() are populated. |
ExtractionModePlain | Reads the content streams in order. Fastest, most complete text, no marks or tables. |
ExtractionModeLayoutNoBreaks | Layout, without line breaks inside a single horizontal line. |
ExtractionModeGrid | Words placed on a fixed-width character grid. Marks() and Tables() come back empty. |
Layout mode is what you want when you need positions or are feeding search and replace,
which depends on marks. Plain mode is worth trying whenever text is duplicated or
missing. The other Options fields cover annotation text (IncludeAnnotations),
clipping to the crop box (ApplyCropBox), damaged files (RelaxedMode) and words split
across lines (DisableDehyphenation).
Tables and positions
Extracting tables is a separate detection pass over text positions, spacing and rulings,
reached through PageText.Tables(). The
table extraction guide covers writing
the result out as CSV, and it handles several tables on one page, unlike the simpler
grid-splitting approach in
pdf_to_csv.go.
For working with position and formatting information directly, start from pdf_text_locations.go.
Longer treatments of each: text extraction, image extraction and font extraction.