Вставка изображения в ячейку

Введение

Точная подгонка изображения под размер одной ячейки — распространённое требование при разработке электронных таблиц, которые выполняют роль визуальных отчётов, каталогов продукции, списков сотрудников, панелей мониторинга или инвентарных списков. Вместо того чтобы растягивать изображение на множество ячеек или размещать его произвольно на рабочем листе, может потребоваться чистое изображение, привязанное к ячейке, которое остаётся выровненным с ячейкой, которой оно принадлежит.

Aspose.Cells поддерживает этот сценарий двумя взаимодополняющими способами:

  • Подход 1 — Размещение плавающего изображения поверх ячейки. Добавьте Picture на рабочий лист, установите его setPlacement в значение MOVE_AND_SIZE и настройте его якорные ячейки (setUpperLeftRow, setUpperLeftColumn, setLowerRightRow, setLowerRightColumn) так, чтобы изображение покрывало ровно одну ячейку.
  • Подход 2 — Встраивание изображения непосредственно в ячейку. Присвойте байты изображения свойству setEmbeddedImage ячейки. Изображение автоматически масштабируется по области отображения ячейки и перемещается вместе с ячейкой.

В остальной части этой статьи рассматриваются оба подхода, объясняются соответствующие API и показано, как использовать их в коде.

Подход 1: Размещение изображения поверх ячейки

Плавающее изображение — это объект Picture, который находится на слое рисования рабочего листа. Хотя оно не является частью какой-либо отдельной ячейки, оно привязано к диапазону ячеек. Якорные ячейки изображения — его верхний левый и нижний правый углы — определяют его визуальные границы на рабочем листе. По умолчанию только что добавленное изображение охватывает несколько ячеек.

Чтобы плавающее изображение покрывало ровно одну ячейку, необходимо:

  1. Добавить изображение с помощью Worksheet.getPictures().add(int row, int column, InputStream stream), который привязывает новое изображение к указанной ячейке.
  2. Установить четыре свойства привязки так, чтобы ограничивающий прямоугольник изображения совпадал с целевой ячейкой.
  3. Установить Picture.setPlacement в значение PlacementType.MOVE_AND_SIZE, чтобы изображение перемещалось и изменялось в размере вместе с базовой ячейкой при изменении пользователем ширины столбца или высоты строки.

Привязка изображения к одной ячейке

Привязка изображения определяется четырьмя свойствами с индексами, начинающимися с нуля:

  • setUpperLeftRow — индекс строки верхнего края изображения.
  • setUpperLeftColumn — индекс столбца левого края изображения.
  • setLowerRightRow — индекс строки нижнего края изображения. Чтобы нижний край изображения располагался внизу строки r, установите это значение в r + 1.
  • setLowerRightColumn — индекс столбца правого края изображения. Чтобы правый край изображения располагался справа от столбца c, установите это значение в c + 1.

Например, чтобы точно подогнать изображение под ячейку C6 (индекс строки 5, индекс столбца 2), установите setUpperLeftRow(5), setUpperLeftColumn(2), setLowerRightRow(6) и setLowerRightColumn(3).

Управление поведением размещения

getPlacement — это перечисление типа PlacementType, которое управляет поведением изображения при изменении пользователем размера строки или столбца под ним. Рекомендуемое значение для изображения в одной ячейке — PlacementType.MOVE_AND_SIZE, при котором изображение перемещается и изменяется в размере вместе с базовой ячейкой, сохраняя точное соответствие.

Пошаговые инструкции

  1. Создайте новый Workbook (или откройте существующий).
  2. Получите доступ к целевому Worksheet через workbook.getWorksheets().get(0).
  3. Откройте файл изображения с диска в InputStream (как правило, FileInputStream), чтобы поток был корректно закрыт.
  4. Вызовите worksheet.getPictures().add(5, 2, stream), чтобы добавить изображение, привязанное к ячейке C6. Сохраните возвращённую ссылку на Picture.
  5. Установите четыре координаты привязки так, чтобы изображение покрывало только ячейку C6: setUpperLeftRow(5), setUpperLeftColumn(2), setLowerRightRow(6), setLowerRightColumn(3).
  6. Установите picture.setPlacement(PlacementType.MOVE_AND_SIZE), чтобы изображение оставалось выровненным с C6 при изменении размера столбца или строки.
  7. При необходимости добавьте образец текста в окружающие ячейки, чтобы продемонстрировать, что только ячейка C6 содержит изображение.
  8. Сохраните рабочую книгу на диск как файл .xlsx.

Следующий код демонстрирует полный подход.

import jpype
import asposecells
jpype.startJVM()
from asposecells.api import Workbook
from asposecells.api import Workbook, SaveFormat, PlacementType

workbook = Workbook()
worksheet = workbook.getWorksheets().get(0)

FileInputStream = jpype.JClass("java.io.FileInputStream")
fs = FileInputStream("logo.png")
try:
    picIndex = worksheet.getPictures().add(5, 2, fs)
    picture = worksheet.getPictures().get(picIndex)
    picture.setUpperLeftRow(5)
    picture.setUpperLeftColumn(2)
    picture.setLowerRightRow(6)
    picture.setLowerRightColumn(3)
    picture.setPlacement(PlacementType.MoveAndSize)
finally:
    fs.close()

workbook.save("output.xlsx", SaveFormat.Xlsx)

jpype.shutdownJVM()

Подход 2: Встраивание изображения непосредственно в ячейку

Aspose.Cells также предоставляет более простой механизм для изображений, привязанных к ячейкам: свойство Cell.setEmbeddedImage. Присвоение байтов изображения этому свойству прикрепляет изображение к самой ячейке, как если бы оно было встроенным содержимым.

Как работают встроенные изображения

  • Изображение хранится как часть содержимого ячейки, а не как фигура на слое рисования.
  • Изображение автоматически масштабируется по границам отображения ячейки. Координаты привязки или параметры размещения не требуются.
  • Ячейка остаётся обычной ячейкой с обычным адресом, на которую можно ссылаться в формулах, сортировать как часть строки или использовать в других операциях на уровне ячеек.

Это делает Cell.setEmbeddedImage наиболее лаконичным вариантом, когда ваша цель просто — «изображение, которое находится внутри этой ячейки».

Пошаговые инструкции

  1. Создайте новый Workbook (или откройте существующий).
  2. Получите доступ к целевому Worksheet через workbook.getWorksheets().get(0).
  3. Прочитайте файл изображения с диска в массив byte[] (например, с помощью вызова Files.readAllBytes из java.nio.file.Files).
  4. Получите ссылку на целевую ячейку — либо через worksheet.getCells().get("C6"), либо через worksheet.getCells().get(5, 2).
  5. Присвойте массив байтов свойству setEmbeddedImage ячейки.
  6. При необходимости настройте высоту строки и ширину столбца целевой строки и столбца, чтобы встроенное изображение выглядело более заметным.
  7. Сохраните рабочую книгу на диск как файл .xlsx.

Следующий код демонстрирует полный подход.

import jpype
import asposecells
jpype.startJVM()
from asposecells.api import Workbook
from asposecells.api import Workbook, Worksheet, Cells, Range, SaveFormat

# перенесённый код здесь
workbook = Workbook()
worksheet = workbook.getWorksheets().get(0)

# Получить целевую ячейку C6
cell = worksheet.getCells().get("C6")

# Прочитать файл изображения в массив байтов
imageData = open("logo.png", "rb").read()

# Встроить изображение непосредственно в ячейку
cell.setEmbeddedImage(imageData)

# При необходимости настроить высоту строки и ширину столбца, чтобы встроенное изображение было лучше видно
worksheet.getCells().setColumnWidth(2, 30)   # Столбец C (индекс 2)
worksheet.getCells().setRowHeight(5, 100)    # Строка 6 (индекс 5)

# Сохранить полученную книгу как файл .xlsx
workbook.save("output.xlsx", SaveFormat.Xlsx)

jpype.shutdownJVM()

Выбор подходящего подхода

Оба подхода создают изображение, которое помещается внутри одной ячейки, но они различаются по способу хранения изображения и его поведению:

  • Используйте плавающее изображение (Подход 1), когда:

    • Вам нужен более тонкий контроль над размещением, наслоением или выравниванием с другими объектами рисования.
    • Вы хотите, чтобы изображение вело себя как фигура, которую можно выбирать, переупорядочивать или группировать с другими фигурами.
    • Вам требуется совместимость с устаревшим кодом, который уже работает с PictureCollection.
    • Вам необходимо динамически вычислять координаты привязки на основе макета рабочего листа.
  • Используйте встроенное изображение (Подход 2), когда:

    • Вам нужна максимально простая вставка изображения в ячейку.
    • Изображение должно перемещаться вместе с ячейкой, как любое другое содержимое ячейки.
    • Вам не нужно манипулировать изображением как фигурой.