Extract Images
Sheet.Images() returns the images the sheet’s drawing refers to, as
common.ImageRef values carrying the format, the pixel size and a path to the
stored bytes. It is the way to inspect or export pictures from a workbook you
did not create, and it is a read of what is already related to the sheet rather
than a scan of the file, so it costs nothing to call.
The bytes themselves are not on your filesystem. When spreadsheet.Open unzips
a workbook it extracts each image into unioffice’s temporary storage and hands
back a reference into it, which is why the copy below goes through
tempstorage.Open rather than os.Open.
Writing images out
wb, err := spreadsheet.Open("images.xlsx")
if err != nil {
panic(err)
}
defer wb.Close()
for si, sheet := range wb.Sheets() {
for i, img := range sheet.Images() {
in, err := tempstorage.Open(img.Path())
if err != nil {
panic(err)
}
out, err := os.Create(fmt.Sprintf("sheet%d_image%d.%s", si+1, i+1, img.Format()))
if err != nil {
panic(err)
}
io.Copy(out, in)
in.Close()
out.Close()
}
}Format() returns the extension the image was stored under, so it makes a
serviceable file suffix. Size() returns an image.Point of the pixel
dimensions, which is the stored size and not necessarily the size the picture is
displayed at; display size comes from the anchor.
The ordering is relationship order within the drawing, not visual order on the
sheet. If you need to know where an image sits, read the anchors on the drawing
returned by Sheet.GetDrawing().
Limitations
wb.Close() deletes the temporary storage the images live in. Copy the bytes
out before the workbook goes out of scope; a defer wb.Close() at the top of a
function is fine, a Close in the middle of the loop is not.
Sheet.Images() returns nil when the sheet has no drawing at all, which is the
common case, so an empty result is not an error.
Images embedded through VML or a legacy drawing are excluded. In practice that means comment background images, which will not appear in the results even though Excel displays them.
Workbook.Sheets() skips sheets marked hidden or very hidden, so a loop over
Sheets() will not reach images on a hidden tab.
Two placements of the same picture share one stored file. The workbook de-dupes on the original target when it reads the file, so a picture used on two sheets yields one set of bytes reached from both.
Run the example
The example opens images.xlsx, prints a count per sheet, and writes each image
out as sheet<N>_image<M>.<ext>. Its saveImage helper is the piece to copy;
everything else is reporting.
git clone https://github.com/unidoc/unioffice-examples.git
cd unioffice-examples/spreadsheet/image_extraction
go run main.goIf this is your first time using UniOffice, follow the getting started guide to create an API key and set up your development environment.