Skip to content

Commit 1f6f1e6

Browse files
Multi-threaded version
1 parent 5ad0e77 commit 1f6f1e6

File tree

4 files changed

+227
-69
lines changed

4 files changed

+227
-69
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package edu.abhi.poi.excel;
2+
3+
import java.util.List;
4+
import java.util.concurrent.Future;
5+
6+
import org.apache.commons.collections4.CollectionUtils;
7+
8+
/**
9+
*
10+
* @author abhishek sarkar
11+
*
12+
*/
13+
public class CallableValue {
14+
15+
/** Failure flag */
16+
private boolean failed = false;
17+
18+
/** Diff Flag */
19+
private boolean diffFlag = false;
20+
21+
/** The exception on failure */
22+
private Exception exception = null;
23+
24+
/** To contain the diff report */
25+
private StringBuilder diffContainer = new StringBuilder();
26+
27+
/**
28+
* @return the failed
29+
*/
30+
public boolean isFailed() {
31+
return failed;
32+
}
33+
34+
/**
35+
* @param failed
36+
* the failed to set
37+
*/
38+
public void setFailed(boolean failed) {
39+
this.failed = failed;
40+
}
41+
42+
/**
43+
* @return the exception
44+
*/
45+
public Exception getException() {
46+
return exception;
47+
}
48+
49+
/**
50+
* @param exception
51+
* the exception to set
52+
*/
53+
public void setException(Exception exception) {
54+
this.exception = exception;
55+
}
56+
57+
/**
58+
* Analyze the output of the threads. If any of the thread failed, it
59+
* prints the Exception stack trace.
60+
*
61+
* @param futures
62+
* the list of {@link Future} which contains the returned
63+
* {@link CallableValue} for all the threads.
64+
* @return if any diff found
65+
*/
66+
public static boolean analyzeResult(List<Future<CallableValue>> futures) {
67+
boolean diffFound = false;
68+
if (!CollectionUtils.isEmpty(futures)) {
69+
try {
70+
for (Future<CallableValue> future : futures) {
71+
CallableValue value = future.get();
72+
if(value != null && value.isDiffFlag()) {
73+
System.out.println(value.getDiffContainer());
74+
diffFound |= value.isDiffFlag();
75+
}
76+
if (value != null && value.isFailed()) {
77+
value.getException().printStackTrace(System.out);
78+
}
79+
}
80+
} catch (Exception e) {
81+
e.printStackTrace(System.out);
82+
}
83+
}
84+
return diffFound;
85+
}
86+
87+
/**
88+
* @return the diffFlag
89+
*/
90+
public boolean isDiffFlag() {
91+
return diffFlag;
92+
}
93+
94+
/**
95+
* @param diffFlag the diffFlag to set
96+
*/
97+
public void setDiffFlag(boolean diffFlag) {
98+
this.diffFlag = diffFlag;
99+
}
100+
101+
/**
102+
* @return the diffReport
103+
*/
104+
public StringBuilder getDiffContainer() {
105+
return diffContainer;
106+
}
107+
}

src/main/java/edu/abhi/poi/excel/ExcelDiffChecker.java

Lines changed: 17 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import java.io.File;
44
import java.io.FileInputStream;
55
import java.io.FileOutputStream;
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
import java.util.concurrent.ExecutorService;
9+
import java.util.concurrent.Executors;
10+
import java.util.concurrent.Future;
611
import java.util.function.Consumer;
712

813
import org.apache.poi.ss.usermodel.Sheet;
9-
import org.apache.poi.xssf.usermodel.XSSFCell;
10-
import org.apache.poi.xssf.usermodel.XSSFRow;
1114
import org.apache.poi.xssf.usermodel.XSSFSheet;
1215
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
1316

@@ -37,7 +40,7 @@ public static void main(String[] args) {
3740
try(XSSFWorkbook resultWorkbook = new XSSFWorkbook(new FileInputStream(new File(FILE_NAME1)));
3841
XSSFWorkbook workbook2 = new XSSFWorkbook(new FileInputStream(new File(FILE_NAME2)))) {
3942

40-
processAllSheets(resultWorkbook, workbook2);
43+
diffFound = CallableValue.analyzeResult(processAllSheets(resultWorkbook, workbook2));
4144

4245
if(diffFound) {
4346
if(commentFlag) {
@@ -53,76 +56,26 @@ public static void main(String[] args) {
5356
}
5457
}
5558

56-
private static void processAllSheets(XSSFWorkbook resultWorkbook, XSSFWorkbook workbook2) throws Exception {
57-
59+
private static List<Future<CallableValue>> processAllSheets(XSSFWorkbook resultWorkbook, XSSFWorkbook workbook2) throws Exception {
60+
List<SheetProcessorTask> tasks = new ArrayList<>();
61+
5862
Consumer<Sheet> consumer = sheet1 -> {
5963
XSSFSheet sheet2 = (XSSFSheet) workbook2.getSheet(sheet1.getSheetName());
6064

6165
if(sheet2 == null) {
6266
System.out.println(String.format("Sheet[%s] doesn't exist in workbook[%s]", sheet1.getSheetName(), FILE_NAME2));
6367
} else
64-
try {
65-
processAllRows((XSSFSheet) sheet1, sheet2);
66-
} catch (Exception e) {
67-
e.printStackTrace(System.out);
68-
}
68+
tasks.add(new SheetProcessorTask((XSSFSheet) sheet1, sheet2, commentFlag));
6969
};
7070

7171
resultWorkbook.forEach(consumer);
72-
}
73-
74-
private static void processAllRows(XSSFSheet sheet1, XSSFSheet sheet2) throws Exception {
75-
for(int rowIndex = 0; rowIndex <= sheet1.getLastRowNum(); rowIndex++) {
76-
XSSFRow row1 = (XSSFRow) sheet1.getRow(rowIndex);
77-
XSSFRow row2 = (XSSFRow) sheet2.getRow(rowIndex);
78-
79-
if(row1 == null || row2 == null) {
80-
if(!(row1 == null && row2 ==null)) {
81-
diffFound = true;
82-
processNullRow(sheet1, rowIndex, row2);
83-
}
84-
continue;
85-
}
86-
87-
processAllColumns(row1, row2);
88-
}
89-
}
90-
91-
private static void processAllColumns(XSSFRow row1, XSSFRow row2) throws Exception {
92-
for(int columnIndex = 0; columnIndex <= row1.getLastCellNum(); columnIndex++) {
93-
XSSFCell cell1 = (XSSFCell) row1.getCell(columnIndex);
94-
XSSFCell cell2 = (XSSFCell) row2.getCell(columnIndex);
95-
96-
if(Utility.hasNoContent(cell1)) {
97-
if(Utility.hasContent(cell2)) {
98-
diffFound = true;
99-
Utility.processDiffForColumn(cell1 == null? row1.createCell(columnIndex) : cell1, commentFlag, Utility.getCellValue(cell2));
100-
}
101-
} else if(Utility.hasNoContent(cell2)) {
102-
if(Utility.hasContent(cell1)) {
103-
diffFound = true;
104-
Utility.processDiffForColumn(cell1, commentFlag, Utility.getCellValue(cell2));
105-
}
106-
} else if(!cell1.getRawValue().equals(cell2.getRawValue())) {
107-
diffFound = true;
108-
Utility.processDiffForColumn(cell1, commentFlag, Utility.getCellValue(cell2));
109-
}
110-
}
111-
}
112-
113-
public static void processNullRow(XSSFSheet sheet1, int rowIndex, XSSFRow row2) throws Exception {
114-
XSSFRow row1 = sheet1.getRow(rowIndex);
115-
116-
if(row1 == null) {
117-
row1 = sheet1.createRow(rowIndex);
118-
119-
for(int columnIndex = 0; columnIndex <= row2.getLastCellNum(); columnIndex++) {
120-
Utility.processDiffForColumn(row1.createCell(0), commentFlag, Utility.getCellValue(row2.getCell(columnIndex)));
121-
}
122-
} else {
123-
XSSFCell cell1 = row1.getCell(0);
124-
Utility.processDiffForColumn(cell1 == null? row1.createCell(0) : cell1, commentFlag, "Null row");
125-
}
72+
73+
int effectiveFixedThreadPoolSize = Math.min(Runtime.getRuntime().availableProcessors(), tasks.size());
74+
ExecutorService executor = Executors.newFixedThreadPool(effectiveFixedThreadPoolSize);
75+
List<Future<CallableValue>> futures = executor.invokeAll(tasks);
76+
executor.shutdown();
77+
78+
return futures;
12679
}
12780

12881
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/**
2+
*
3+
*/
4+
package edu.abhi.poi.excel;
5+
6+
import java.util.concurrent.Callable;
7+
8+
import org.apache.poi.xssf.usermodel.XSSFCell;
9+
import org.apache.poi.xssf.usermodel.XSSFRow;
10+
import org.apache.poi.xssf.usermodel.XSSFSheet;
11+
12+
/**
13+
* @author abhishek sarkar
14+
*
15+
*/
16+
public class SheetProcessorTask implements Callable<CallableValue> {
17+
18+
private XSSFSheet sheet1, sheet2;
19+
private boolean commentFlag;
20+
private CallableValue crt;
21+
22+
public SheetProcessorTask(XSSFSheet sheet1, XSSFSheet sheet2, boolean commentFlag) {
23+
this.sheet1 = sheet1;
24+
this.sheet2 = sheet2;
25+
this.commentFlag = commentFlag;
26+
}
27+
28+
@Override
29+
public CallableValue call() {
30+
crt = new CallableValue();
31+
try {
32+
processAllRows();
33+
} catch (Exception e) {
34+
crt.setFailed(true);
35+
crt.setException(e);
36+
}
37+
return crt;
38+
}
39+
40+
private void processAllRows() throws Exception {
41+
for (int rowIndex = 0; rowIndex <= sheet1.getLastRowNum(); rowIndex++) {
42+
XSSFRow row1 = (XSSFRow) sheet1.getRow(rowIndex);
43+
XSSFRow row2 = (XSSFRow) sheet2.getRow(rowIndex);
44+
45+
if (row1 == null || row2 == null) {
46+
if (!(row1 == null && row2 == null)) {
47+
crt.setDiffFlag(true);
48+
processNullRow(sheet1, rowIndex, row2);
49+
}
50+
continue;
51+
}
52+
53+
processAllColumns(row1, row2);
54+
}
55+
}
56+
57+
private void processAllColumns(XSSFRow row1, XSSFRow row2) throws Exception {
58+
for (int columnIndex = 0; columnIndex <= row1.getLastCellNum(); columnIndex++) {
59+
XSSFCell cell1 = (XSSFCell) row1.getCell(columnIndex);
60+
XSSFCell cell2 = (XSSFCell) row2.getCell(columnIndex);
61+
62+
if (Utility.hasNoContent(cell1)) {
63+
if (Utility.hasContent(cell2)) {
64+
crt.setDiffFlag(true);
65+
Utility.processDiffForColumn(cell1 == null ? row1.createCell(columnIndex) : cell1, commentFlag,
66+
Utility.getCellValue(cell2), crt.getDiffContainer());
67+
}
68+
} else if (Utility.hasNoContent(cell2)) {
69+
if (Utility.hasContent(cell1)) {
70+
crt.setDiffFlag(true);
71+
Utility.processDiffForColumn(cell1, commentFlag, Utility.getCellValue(cell2), crt.getDiffContainer());
72+
}
73+
} else if (!cell1.getRawValue().equals(cell2.getRawValue())) {
74+
crt.setDiffFlag(true);
75+
Utility.processDiffForColumn(cell1, commentFlag, Utility.getCellValue(cell2), crt.getDiffContainer());
76+
}
77+
}
78+
}
79+
80+
public void processNullRow(XSSFSheet sheet1, int rowIndex, XSSFRow row2) throws Exception {
81+
XSSFRow row1 = sheet1.getRow(rowIndex);
82+
83+
if (row1 == null) {
84+
if (row2.getPhysicalNumberOfCells() != 0) {
85+
row1 = sheet1.createRow(rowIndex);
86+
87+
for (int columnIndex = 0; columnIndex <= row2.getLastCellNum(); columnIndex++) {
88+
Utility.processDiffForColumn(row1.createCell(0), commentFlag,
89+
Utility.getCellValue(row2.getCell(columnIndex)), crt.getDiffContainer());
90+
}
91+
}
92+
} else {
93+
if (row1.getPhysicalNumberOfCells() != 0) {
94+
XSSFCell cell1 = row1.getCell(0);
95+
Utility.processDiffForColumn(cell1 == null ? row1.createCell(0) : cell1, commentFlag, "Null row", crt.getDiffContainer());
96+
}
97+
}
98+
}
99+
100+
}

src/main/java/edu/abhi/poi/excel/Utility.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
import org.apache.poi.ss.usermodel.Drawing;
1414
import org.apache.poi.ss.usermodel.Sheet;
1515
import org.apache.poi.xssf.usermodel.XSSFCell;
16-
import org.apache.poi.xssf.usermodel.XSSFRow;
17-
import org.apache.poi.xssf.usermodel.XSSFSheet;
1816

1917
/**
2018
* @author abhishek sarkar
@@ -31,14 +29,14 @@ public static boolean hasContent(XSSFCell cell) {
3129
}
3230

3331
@SuppressWarnings("rawtypes")
34-
public static void processDiffForColumn(XSSFCell cell1, boolean commentFlag, String note) throws Exception {
32+
public static void processDiffForColumn(XSSFCell cell1, boolean commentFlag, String note, StringBuilder sb) throws Exception {
3533

3634
Sheet sheet = cell1.getSheet();
3735

38-
System.out.println(String.format("Diff at cell[%s] of sheet[%s]", cell1.getReference(), sheet.getSheetName()));
36+
sb.append(String.format("Diff at cell[%s] of sheet[%s]\n", cell1.getReference(), sheet.getSheetName()));
3937

4038
if(!commentFlag) {
41-
System.out.println(String.format("Expected: [%s], Found: [%s]", getCellValue(cell1), note));
39+
sb.append(String.format("Expected: [%s], Found: [%s]\n", getCellValue(cell1), note));
4240
return;
4341
}
4442

0 commit comments

Comments
 (0)