استخدام واجهة LightCells API
بنية معمارية مدعومة بالأحداث
توفر Aspose.Cells واجهة LightCells API مصممة بشكل رئيسي للتلاعب ببيانات الخلية واحدة تلو الأخرى دون بناء نموذج بيانات كاملاً (باستخدام مجموعة الخلية إلخ) في الذاكرة. تعمل في وضع محفز بالأحداث.
لحفظ دفاتر العمل، يتم تقديم محتوى الخلية خلية بخلية عند الحفظ، ويقوم المكون بحفظه في ملف الإخراج مباشرةً.
عند قراءة ملفات القالب، يُحلل المكون كل خلية ويقدم قيمها واحدة تلو الأخرى.
في كل من الإجراءين، يتم معالجة كائن Cell ومن ثم التخلّص منه، ولا يحمل كائن Workbook المجموعة. وبالتالي، يتم توفير الذاكرة عند استيراد وتصدير ملف Microsoft Excel الذي يحتوي على مجموعة بيانات كبيرة والتي ستستخدم وحدة كبيرة من الذاكرة وإلا.
على الرغم من أن واجهة LightCells API تعالج الخلايا بنفس الطريقة لملفات XLSX وXLS (حيث لا تقوم فعليًا بتحميل كل الخلايا في الذاكرة ولكن تعالج خلية ومن ثم تتخلص منها)، إلا أنها تحفظ الذاكرة بشكل أكثر فعالية لملفات XLSX من ملفات XLS بسبب النماذج والهياكل المختلفة للصيغتين.
ومع ذلك، بالنسبة لملفات XLS، يمكن للمطورين تحديد موقع مؤقت لحفظ البيانات المؤقتة التي تُولد أثناء عملية الحفظ، لتحفيظ المزيد من الذاكرة. بشكل شائع، يمكن لاستخدام واجهة LightCells API لحفظ ملف XLSX توفير 50% أو أكثر من الذاكرة مقارنة بالطريقة الشائعة، حفظ ملف XLS قد يوفر حوالي 20-40% من الذاكرة.
كتابة ملفات إكسيل الكبيرة
يوفر Aspose.Cells واجهة LightCellsDataProvider التي يجب تنفيذها في برنامجك. تُمثل الواجهة موفّر بيانات لحفظ ملفات جداول بيانات ضخمة في وضع خفيف الوزن.
عند حفظ دفتر عمل بهذا الوضع، يتم فحص startSheet(int) عند حفظ كل ورقة عمل في الدفتر. بالنسبة إلى ورقة عمل واحدة، إذا كانت startSheet(int) صحيحة، فإن جميع البيانات والخصائص للصفوف والخلايا لهذه الورقة التي ستُحفظ يتم توفيرها من هذا التنفيذ. في المقام الأول، يتم استدعاء nextRow() للحصول على مؤشر الصف التالي الذي سيتم حفظه. إذا تم إرجاع مؤشر صف صحيح (يجب أن يكون مؤشر الصف مرتبًا ترتيبًا تصاعديًا للصفوف المراد حفظها)، فإن كائن Row الذي يُمثّل هذا الصف يتم توفيره للتنفيذ لتعيين خصائصه بواسطة startRow(Row).
بالنسبة إلى صف واحد، يتم فحص nextCell() أولاً. إذا تم إرجاع فهرس العمود صحيح (يجب أن يكون فهرس العمود مرتبًا ترتيبًا تصاعديًا لجميع الخلايا في صف واحد تم حفظه)، فإن كائن Cell الذي يُمثّل هذه الخلية يتم توفيره لتعيين البيانات والخصائص بواسطة startCell(Cell). بعد تعيين بيانات هذه الخلية، يتم حفظ هذه الخلية مباشرةً إلى ملف الجدولة الناتج وسيتم فحص الخلية التالية ومعالجتها.
المثال التالي يوضح كيفية عمل واجهة برمجة التطبيقات LightCells.
البرنامج التالي يقوم بإنشاء ملف كبير يحتوي على 100،000 سجل في ورقة عمل، مملوءة بالبيانات. لقد أضفنا بعض الروابط التشعبية، وقيم السلاسل، والقيم الرقمية وأيضًا الصيغ إلى خلايا معينة في ورقة العمل. علاوة على ذلك، لقد قمنا بتنسيق نطاق من الخلايا أيضًا.
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java | |
public class LightCellsDataProviderDemo implements LightCellsDataProvider { | |
private final int sheetCount; | |
private final int maxRowIndex; | |
private final int maxColIndex; | |
private int rowIndex; | |
private int colIndex; | |
private final Style style1; | |
private final Style style2; | |
public LightCellsDataProviderDemo(Workbook wb, int sheetCount, int rowCount, int colCount) { | |
// set the variables/objects | |
this.sheetCount = sheetCount; | |
this.maxRowIndex = rowCount - 1; | |
this.maxColIndex = colCount - 1; | |
// add new style object with specific formattings | |
style1 = wb.createStyle(); | |
Font font = style1.getFont(); | |
font.setName("MS Sans Serif"); | |
font.setSize(10); | |
font.setBold(true); | |
font.setItalic(true); | |
font.setUnderline(FontUnderlineType.SINGLE); | |
font.setColor(Color.fromArgb(0xffff0000)); | |
style1.setHorizontalAlignment(TextAlignmentType.CENTER); | |
// create another style | |
style2 = wb.createStyle(); | |
style2.setCustom("#,##0.00"); | |
font = style2.getFont(); | |
font.setName("Copperplate Gothic Bold"); | |
font.setSize(8); | |
style2.setPattern(BackgroundType.SOLID); | |
style2.setForegroundColor(Color.fromArgb(0xff0000ff)); | |
style2.setBorder(BorderType.TOP_BORDER, CellBorderType.THICK, Color.getBlack()); | |
style2.setVerticalAlignment(TextAlignmentType.CENTER); | |
} | |
public boolean isGatherString() { | |
return false; | |
} | |
public int nextCell() { | |
if (colIndex < maxColIndex) { | |
colIndex++; | |
return colIndex; | |
} | |
return -1; | |
} | |
public int nextRow() { | |
if (rowIndex < maxRowIndex) { | |
rowIndex++; | |
colIndex = -1; // reset column index | |
if (rowIndex % 1000 == 0) { | |
System.out.println("Row " + rowIndex); | |
} | |
return rowIndex; | |
} | |
return -1; | |
} | |
public void startCell(Cell cell) { | |
if (rowIndex % 50 == 0 && (colIndex == 0 || colIndex == 3)) { | |
// do not change the content of hyperlink. | |
return; | |
} | |
if (colIndex < 10) { | |
cell.putValue("test_" + rowIndex + "_" + colIndex); | |
cell.setStyle(style1); | |
} else { | |
if (colIndex == 19) { | |
cell.setFormula("=Rand() + test!L1"); | |
} else { | |
cell.putValue(rowIndex * colIndex); | |
} | |
cell.setStyle(style2); | |
} | |
} | |
public void startRow(Row row) { | |
row.setHeight(25); | |
} | |
public boolean startSheet(int sheetIndex) { | |
if (sheetIndex < sheetCount) { | |
// reset row/column index | |
rowIndex = -1; | |
colIndex = -1; | |
return true; | |
} | |
return false; | |
} | |
} |
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java | |
public class Demo { | |
private static final String OUTPUT_FILE_PATH = Utils.getDataDir(LightCellsDataProviderDemo.class); | |
public static void main(String[] args) throws Exception { | |
// Instantiate a new Workbook | |
Workbook wb = new Workbook(); | |
// set the sheet count | |
int sheetCount = 1; | |
// set the number of rows for the big matrix | |
int rowCount = 100000; | |
// specify the worksheet | |
for (int k = 0; k < sheetCount; k++) { | |
Worksheet sheet = null; | |
if (k == 0) { | |
sheet = wb.getWorksheets().get(k); | |
sheet.setName("test"); | |
} else { | |
int sheetIndex = wb.getWorksheets().add(); | |
sheet = wb.getWorksheets().get(sheetIndex); | |
sheet.setName("test" + sheetIndex); | |
} | |
Cells cells = sheet.getCells(); | |
// set the columns width | |
for (int j = 0; j < 15; j++) { | |
cells.setColumnWidth(j, 15); | |
} | |
// traverse the columns for adding hyperlinks and merging | |
for (int i = 0; i < rowCount; i++) { | |
// The first 10 columns | |
for (int j = 0; j < 10; j++) { | |
if (j % 3 == 0) { | |
cells.merge(i, j, 1, 2, false, false); | |
} | |
if (i % 50 == 0) { | |
if (j == 0) { | |
sheet.getHyperlinks().add(i, j, 1, 1, "test!A1"); | |
} else if (j == 3) { | |
sheet.getHyperlinks().add(i, j, 1, 1, "http://www.google.com"); | |
} | |
} | |
} | |
// The second 10 columns | |
for (int j = 10; j < 20; j++) { | |
if (j == 12) { | |
cells.merge(i, j, 1, 3, false, false); | |
} | |
} | |
} | |
} | |
// Create an object with respect to LightCells data provider | |
LightCellsDataProviderDemo dataProvider = new LightCellsDataProviderDemo(wb, 1, rowCount, 20); | |
// Specify the XLSX file's Save options | |
OoxmlSaveOptions opt = new OoxmlSaveOptions(); | |
// Set the data provider for the file | |
opt.setLightCellsDataProvider(dataProvider); | |
// Save the big file | |
wb.save(OUTPUT_FILE_PATH + "/DemoTest.xlsx", opt); | |
} | |
} |
قراءة ملفات Excel الكبيرة
توفر Aspose.Cells واجهة LightCellsDataHandler التي يجب تنفيذها في برنامجك. تمثل الواجهة مزود البيانات لقراءة ملفات جداول بيانات كبيرة بوضع خفيف.
عند قراءة دفتر العمل في هذا الوضع، يتم التحقق من startSheet() عند قراءة كل ورقة في دفتر العمل. بالنسبة للورقة، إذا كانت startSheet() ترجع true، فيتم التحقق ومعالجة جميع البيانات والخصائص للخلايا في صفوف الورقة وأعمدتها. بالنسبة لكل صف، يتم استدعاء startRow() للتحقق مما إذا كان بحاجة للمعالجة. إذا كان الصف بحاجة للمعالجة، يتم قراءة خصائص الصف أولاً ويمكن للمطورين الوصول إلى خصائصه بـ processRow().
إذا كانت خلايا الصف تحتاج أيضًا إلى المعالجة، يرجع processRow() true ويتم استدعاء startCell() لكل خلية موجودة في الصف للتحقق مما إذا كان بحاجة للمعالجة. إذا كان الأمر كذلك، يتم استدعاء processCell().
الكود البرنامج التالي يوضح هذه العملية. البرنامج يقرأ ملفًا كبيرًا يحتوي على ملايين السجلات. يستغرق وقتًا قليلاً لقراءة كل ورقة في دفتر العمل. يقوم الكود البرنامجي بقراءة الملف واسترجاع العدد الكلي للخلايا، وعدد السلاسل وعدد الصيغ لكل ورقة عمل.
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java | |
public class LightCellsTest1 { | |
public static void main(String[] args) throws Exception { | |
String dataDir = Utils.getDataDir(LightCellsTest1.class); | |
LoadOptions opts = new LoadOptions(); | |
LightCellsDataHandlerVisitCells v = new LightCellsDataHandlerVisitCells(); | |
opts.setLightCellsDataHandler((LightCellsDataHandler) v); | |
Workbook wb = new Workbook(dataDir + "LargeBook1.xlsx", opts); | |
int sheetCount = wb.getWorksheets().getCount(); | |
System.out.println("Total sheets: " + sheetCount + ", cells: " + v.cellCount + ", strings: " + v.stringCount | |
+ ", formulas: " + v.formulaCount); | |
} | |
} |
فئة تقوم بتنفيذ واجهة LightCellsDataHandler
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java | |
public class LightCellsDataHandlerVisitCells implements LightCellsDataHandler { | |
public int cellCount; | |
public int formulaCount; | |
public int stringCount; | |
public LightCellsDataHandlerVisitCells() { | |
this.cellCount = 0; | |
this.formulaCount = 0; | |
this.stringCount = 0; | |
} | |
public int cellCount() { | |
return cellCount; | |
} | |
public int formulaCount() { | |
return formulaCount; | |
} | |
public int stringCount() { | |
return stringCount; | |
} | |
public boolean startSheet(Worksheet sheet) { | |
System.out.println("Processing sheet[" + sheet.getName() + "]"); | |
return true; | |
} | |
public boolean startRow(int rowIndex) { | |
return true; | |
} | |
public boolean processRow(Row row) { | |
return true; | |
} | |
public boolean startCell(int column) { | |
return true; | |
} | |
public boolean processCell(Cell cell) { | |
this.cellCount = this.cellCount + 1; | |
if (cell.isFormula()) { | |
this.formulaCount = this.formulaCount + 1; | |
} else if (cell.getType() == CellValueType.IS_STRING) { | |
this.stringCount = this.stringCount + 1; | |
} | |
return false; | |
} | |
} |