إدراج صورة في خلية

المقدمة

يعد ضبط صورة لتتناسب تمامًا مع خلية واحدة متطلبًا شائعًا عند تصميم جداول البيانات التي تعمل كتقارير مرئية أو كتالوجات منتجات أو سجلات موظفين أو لوحات معلومات أو قوائم جرد. بدلاً من تمديد صورة عبر عدة خلايا أو وضعها بشكل فضفاض على ورقة عمل، قد ترغب في صورة نظيفة ومرتبطة بالخلية تظل محاذية مع الخلية التي تنتمي إليها.

يدعم Aspose.Cells هذا السيناريو بطريقتين متكاملتين:

  • الطريقة 1 — وضع صورة عائمة فوق خلية. أضف Picture إلى ورقة العمل، وعيّن Placement الخاصة بها إلى MOVE_AND_SIZE، واضبط خلايا الإرساء (getUpperLeftRow، getUpperLeftColumn، getLowerRightRow، getLowerRightColumn) بحيث تغطي الصورة خلية واحدة فقط بالضبط.
  • الطريقة 2 — تضمين صورة مباشرة في خلية. قم بتعيين بايتات الصورة إلى المُعيِّن getEmbeddedImage() الخاص بالخلية. تتناسب الصورة تلقائيًا مع منطقة عرض الخلية وتنتقل معها.

تمضي بقية هذه المقالة في شرح كلتا الطريقتين، وتوضح واجهات برمجة التطبيقات ذات الصلة، وتعرض كيفية استخدامها في الكود.

الطريقة 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) عندما:

    • تريد أبسط إدراج ممكن لصورة في خلية.
    • يجب أن تنتقل الصورة مع الخلية مثل أي محتوى خلية آخر.
    • لا تحتاج إلى معالجة الصورة كشكل.