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

Введение

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

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

  • Подход 1 — Размещение плавающего изображения над ячейкой. Добавьте Picture на рабочий лист, установите его Placement в значение MOVE_AND_SIZE и настройте якорные ячейки (getUpperLeftRow, getUpperLeftColumn, getLowerRightRow, getLowerRightColumn) так, чтобы изображение покрывало ровно одну ячейку.
  • Подход 2 — Встраивание изображения непосредственно в ячейку. Присвойте байты изображения сеттеру getEmbeddedImage() ячейки. Изображение автоматически масштабируется, чтобы заполнить область отображения ячейки, и перемещается вместе с ячейкой.

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

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

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

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

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

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

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

  • Picture.getUpperLeftRow() — индекс строки верхнего края изображения.
  • Picture.getUpperLeftColumn() — индекс столбца левого края изображения.
  • Picture.getLowerRightRow() — индекс строки нижнего края изображения. Чтобы нижний край изображения оказался у нижней границы строки r, установите это значение в r + 1.
  • Picture.getLowerRightColumn() — индекс столбца правого края изображения. Чтобы правый край изображения оказался у правой границы столбца c, установите это значение в c + 1.

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

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

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

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

  1. Создайте новую Workbook (или откройте существующую).
  2. Получите целевой Worksheet из workbook.getWorksheets().get(0).
  3. Откройте файл изображения с диска в InputStream (например, FileInputStream), используя блок try-with-resources, чтобы поток был корректно закрыт.
  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 com.aspose.cells.*;
import java.io.FileInputStream;

Workbook workbook = new Workbook();
Worksheet worksheet = workbook.getWorksheets().get(0);

try (FileInputStream fs = new FileInputStream("logo.png"))
{
    int picIndex = worksheet.getPictures().add(5, 2, fs);
    Picture picture = worksheet.getPictures().get(picIndex);
    picture.setUpperLeftRow(5);
    picture.setUpperLeftColumn(2);
    picture.setLowerRightRow(6);
    picture.setLowerRightColumn(3);
    picture.setPlacement(PlacementType.MOVE_AND_SIZE);
}

workbook.save("output.xlsx", SaveFormat.XLSX);

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

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

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

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

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

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

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

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

import com.aspose.cells.*;
import java.nio.file.Files;
import java.nio.file.Paths;

Workbook workbook = new Workbook();
Worksheet worksheet = workbook.getWorksheets().get(0);

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

// Прочитать файл изображения в массив байтов
byte[] imageData = Files.readAllBytes(Paths.get("logo.png"));

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

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

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

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

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

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

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

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