From b5201554110e0394e1f7b0c5cfdcac3d11503da4 Mon Sep 17 00:00:00 2001 From: Towhidul Islam Date: Tue, 9 Aug 2022 15:00:34 +0600 Subject: [PATCH] adding ReportContentIOKit --- ReportContentIOKit/pom.xml | 59 +++++ .../lab/definition/ContentWriter.java | 8 + .../lab/definition/ReadingService.java | 43 ++++ .../lab/definition/WritingService.java | 9 + .../services/excel/ExcelReadingService.java | 232 ++++++++++++++++++ .../services/excel/ExcelWritingService.java | 131 ++++++++++ .../lab/services/pdf/PdfWritingService.java | 73 ++++++ .../excel/ExcelReadingServiceTest.java | 17 ++ .../excel/ExcelWritingServiceTest.java | 17 ++ .../services/pdf/PdfWritingServiceTest.java | 17 ++ pom.xml | 1 + 11 files changed, 607 insertions(+) create mode 100644 ReportContentIOKit/pom.xml create mode 100644 ReportContentIOKit/src/main/java/com/infoworks/lab/definition/ContentWriter.java create mode 100644 ReportContentIOKit/src/main/java/com/infoworks/lab/definition/ReadingService.java create mode 100644 ReportContentIOKit/src/main/java/com/infoworks/lab/definition/WritingService.java create mode 100644 ReportContentIOKit/src/main/java/com/infoworks/lab/services/excel/ExcelReadingService.java create mode 100644 ReportContentIOKit/src/main/java/com/infoworks/lab/services/excel/ExcelWritingService.java create mode 100644 ReportContentIOKit/src/main/java/com/infoworks/lab/services/pdf/PdfWritingService.java create mode 100644 ReportContentIOKit/src/test/java/com/infoworks/lab/services/excel/ExcelReadingServiceTest.java create mode 100644 ReportContentIOKit/src/test/java/com/infoworks/lab/services/excel/ExcelWritingServiceTest.java create mode 100644 ReportContentIOKit/src/test/java/com/infoworks/lab/services/pdf/PdfWritingServiceTest.java diff --git a/ReportContentIOKit/pom.xml b/ReportContentIOKit/pom.xml new file mode 100644 index 0000000..13c2e2f --- /dev/null +++ b/ReportContentIOKit/pom.xml @@ -0,0 +1,59 @@ + + + + web-component-kit + com.infoworks.lab + 1.0-SNAPSHOT + + 4.0.0 + + report-content-io-kit + jar + 1.10.7-RELEASE + + + 1.8 + 1.8 + 1.8 + UTF-8 + [2.9.10.5,) + 1.1.4 + 4.1.2 + + + + + com.github.itsoulltd + JSQLEditor + 1.1.4.2-RELEASE + provided + + + com.infoworks.lab + http-rest-client + 1.10.7-RELEASE + provided + + + + org.apache.poi + poi + ${poi-version} + + + org.apache.poi + poi-ooxml + ${poi-version} + + + + com.monitorjbl + xlsx-streamer + 2.1.0 + + + + + \ No newline at end of file diff --git a/ReportContentIOKit/src/main/java/com/infoworks/lab/definition/ContentWriter.java b/ReportContentIOKit/src/main/java/com/infoworks/lab/definition/ContentWriter.java new file mode 100644 index 0000000..7bbeefb --- /dev/null +++ b/ReportContentIOKit/src/main/java/com/infoworks/lab/definition/ContentWriter.java @@ -0,0 +1,8 @@ +package com.infoworks.lab.definition; + +import java.util.Map; + +public interface ContentWriter extends AutoCloseable{ + default void write(Map data, boolean skipZeroIndex) { write("", data, skipZeroIndex); } + void write(String sheetName, Map data, boolean skipZeroIndex); +} diff --git a/ReportContentIOKit/src/main/java/com/infoworks/lab/definition/ReadingService.java b/ReportContentIOKit/src/main/java/com/infoworks/lab/definition/ReadingService.java new file mode 100644 index 0000000..1f95e41 --- /dev/null +++ b/ReportContentIOKit/src/main/java/com/infoworks/lab/definition/ReadingService.java @@ -0,0 +1,43 @@ +package com.infoworks.lab.definition; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +public interface ReadingService { + + void readAsync(InputStream inputStream + , Integer bufferSize + , Integer sheetAt + , Integer beginIndex + , Integer endIndex + , Integer pageSize + , Consumer>> consumer) throws IOException; + + void readAsync(File file + , Integer bufferSize + , Integer sheetAt + , Integer beginIndex + , Integer endIndex + , Integer pageSize + , Consumer>> consumer) throws IOException; + + void read(InputStream inputStream + , Integer sheetAt + , Integer startAt + , Integer pageSize + , Consumer>> consumer) throws IOException; + + void read(File file + , Integer sheetAt + , Integer startAt + , Integer pageSize + , Consumer>> consumer) throws IOException; + + Map> read(InputStream inputStream, Integer sheetAt, Integer start, Integer end) throws IOException; + + Map> read(File file, Integer sheetAt, Integer start, Integer end) throws IOException; +} diff --git a/ReportContentIOKit/src/main/java/com/infoworks/lab/definition/WritingService.java b/ReportContentIOKit/src/main/java/com/infoworks/lab/definition/WritingService.java new file mode 100644 index 0000000..9b7c528 --- /dev/null +++ b/ReportContentIOKit/src/main/java/com/infoworks/lab/definition/WritingService.java @@ -0,0 +1,9 @@ +package com.infoworks.lab.definition; + +import java.io.OutputStream; +import java.util.List; +import java.util.Map; + +public interface WritingService { + void write(OutputStream outputStream, String sheetName, Map> data) throws Exception; +} diff --git a/ReportContentIOKit/src/main/java/com/infoworks/lab/services/excel/ExcelReadingService.java b/ReportContentIOKit/src/main/java/com/infoworks/lab/services/excel/ExcelReadingService.java new file mode 100644 index 0000000..fe3e359 --- /dev/null +++ b/ReportContentIOKit/src/main/java/com/infoworks/lab/services/excel/ExcelReadingService.java @@ -0,0 +1,232 @@ +package com.infoworks.lab.services.excel; + +import com.infoworks.lab.definition.ReadingService; +import com.monitorjbl.xlsx.StreamingReader; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.NumberToTextConverter; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ExcelReadingService implements ReadingService { + + private static Logger LOG = Logger.getLogger(ExcelReadingService.class.getSimpleName()); + + public void readAsync(InputStream inputStream + , Integer bufferSize + , Integer sheetAt + , Integer beginIndex + , Integer endIndex + , Integer pageSize + , Consumer>> consumer) throws IOException { + // + Workbook workbook = StreamingReader.builder() + .rowCacheSize(pageSize) + .bufferSize(bufferSize) + .open(inputStream); + configureWorkbook(workbook); + readBuffered(workbook, sheetAt, beginIndex, endIndex, pageSize, consumer); + workbook.close(); + } + + public void readAsync(File file + , Integer bufferSize + , Integer sheetAt + , Integer beginIndex + , Integer endIndex + , Integer pageSize + , Consumer>> consumer) throws IOException { + // + Workbook workbook = StreamingReader.builder() + .rowCacheSize(pageSize) + .bufferSize(bufferSize) + .open(file); + configureWorkbook(workbook); + readBuffered(workbook, sheetAt, beginIndex, endIndex, pageSize, consumer); + workbook.close(); + } + + /** + * + * @param workbook + * @param sheetAt + * @param beginIndex the beginning index, inclusive. + * @param endIndex the ending index, exclusive. + * @param pageSize + * @param consumer + * @throws IOException + */ + private void readBuffered(Workbook workbook + , Integer sheetAt + , Integer beginIndex + , Integer endIndex + , Integer pageSize + , Consumer>> consumer) throws IOException { + // + Sheet sheet = workbook.getSheetAt(sheetAt); + int maxCount = sheet.getLastRowNum() + 1; + pageSize = (pageSize > maxCount) ? maxCount : pageSize; + if (endIndex <= 0 || endIndex == Integer.MAX_VALUE) endIndex = maxCount; + // + int idx = -1; + Map> data = new HashMap<>(); + for (Row row : sheet){ + if (++idx < beginIndex) {continue;} + if (idx >= endIndex) {break;} + // + data.put(idx, new ArrayList<>()); + for (Cell cell : row){ + addInto(data, idx, cell); + } + if (consumer != null && data.size() == pageSize ){ + Map xData = new HashMap(data); + data.clear(); + consumer.accept(xData); + } + } + //left-over + if (consumer != null && data.size() > 0 ){ + Map xData = new HashMap(data); + data.clear(); + consumer.accept(xData); + } + } + + public void read(InputStream inputStream + , Integer sheetAt + , Integer startAt + , Integer pageSize + , Consumer>> consumer) throws IOException { + // + Workbook workbook = WorkbookFactory.create(inputStream); + configureWorkbook(workbook); + readAsync(workbook, sheetAt, startAt, pageSize, consumer); + workbook.close(); + } + + public void read(File file + , Integer sheetAt + , Integer startAt + , Integer pageSize + , Consumer>> consumer) throws IOException { + // + Workbook workbook = WorkbookFactory.create(file); + configureWorkbook(workbook); + readAsync(workbook, sheetAt, startAt, pageSize, consumer); + workbook.close(); + } + + private void readAsync(Workbook workbook + , Integer sheetAt + , Integer startAt + , Integer pageSize + , Consumer>> consumer) throws IOException { + // + Sheet sheet = workbook.getSheetAt(sheetAt); + int maxCount = sheet.getLastRowNum() + 1; + int loopCount = (pageSize == maxCount) ? 1 : (maxCount / pageSize) + 1; + pageSize = (pageSize > maxCount) ? maxCount : pageSize; + int index = 0; + int start = (startAt < 0 || startAt >= maxCount) ? 0 : startAt; + while (index < loopCount){ + int end = start + pageSize; + if (end >= maxCount) end = maxCount; + Map res = parseContent(workbook, sheetAt, start, end); + if (consumer != null && res.size() > 0){ + consumer.accept(res); + } + // + start += pageSize; + index++; + } + } + + public Map> read(InputStream inputStream, Integer sheetAt, Integer start, Integer end) throws IOException { + Workbook workbook = WorkbookFactory.create(inputStream); + configureWorkbook(workbook); + Map res = parseContent(workbook, sheetAt, start, end); + workbook.close(); + return res; + } + + public Map> readXls(InputStream inputStream, Integer sheetAt, Integer start, Integer end) throws IOException { + Workbook workbook = new HSSFWorkbook(inputStream); + configureWorkbook(workbook); + Map res = parseContent(workbook, sheetAt, start, end); + workbook.close(); + return res; + } + + public Map> read(File file, Integer sheetAt, Integer start, Integer end) throws IOException { + Workbook workbook = WorkbookFactory.create(file); + configureWorkbook(workbook); + Map res = parseContent(workbook, sheetAt, start, end); + workbook.close(); + return res; + } + + private void configureWorkbook(Workbook workbook) { + if (workbook != null){ + try { + //Add All kind of setting for workbook: + workbook.setMissingCellPolicy(Row.MissingCellPolicy.RETURN_BLANK_AS_NULL); + }catch (UnsupportedOperationException e){ + LOG.log(Level.WARNING, e.getMessage()); + }catch (Exception e){ + LOG.log(Level.WARNING, e.getMessage()); + } + } + } + + private Map> parseContent(Workbook workbook, Integer sheetAt, Integer start, Integer end) throws IOException { + //DoTheMath: + Sheet sheet = workbook.getSheetAt(sheetAt); + Map> data = new HashMap<>(); + // + if (end <= 0 || end == Integer.MAX_VALUE){ + end = sheet.getLastRowNum() + 1; + } + int idx = (start < 0) ? 0 : start; + while (idx < end) { + data.put(idx, new ArrayList<>()); + for (Cell cell : sheet.getRow(idx)) { + addInto(data, idx, cell); + } + idx++; + } + return data; + } + + private void addInto(Map> data, int idx, Cell cell) { + switch (cell.getCellType()) { + case STRING: + data.get(idx).add(cell.getRichStringCellValue().getString()); + break; + case NUMERIC: + if (DateUtil.isCellDateFormatted(cell)) { + data.get(idx).add(cell.getDateCellValue() + ""); + } else { + data.get(idx).add(NumberToTextConverter.toText(cell.getNumericCellValue())); + } + break; + case BOOLEAN: + data.get(idx).add(cell.getBooleanCellValue() + ""); + break; + case FORMULA: + data.get(idx).add(cell.getStringCellValue() + ""); + break; + default: + data.get(idx).add(" "); + } + } + +} diff --git a/ReportContentIOKit/src/main/java/com/infoworks/lab/services/excel/ExcelWritingService.java b/ReportContentIOKit/src/main/java/com/infoworks/lab/services/excel/ExcelWritingService.java new file mode 100644 index 0000000..e027c86 --- /dev/null +++ b/ReportContentIOKit/src/main/java/com/infoworks/lab/services/excel/ExcelWritingService.java @@ -0,0 +1,131 @@ +package com.infoworks.lab.services.excel; + +import com.infoworks.lab.definition.ContentWriter; +import com.infoworks.lab.definition.WritingService; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFSheet; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ExcelWritingService implements WritingService { + + private static Logger LOG = Logger.getLogger(ExcelWritingService.class.getSimpleName()); + + public void write(boolean xssf, OutputStream outputStream, String sheetName, Map> data) throws Exception { + AsyncWriter writer = new AsyncWriter(xssf, outputStream); + writer.write(sheetName, data, false); + writer.close(); + } + + public void write(OutputStream outputStream, String sheetName, Map> data) throws Exception { + AsyncWriter writer = new AsyncStreamWriter(100, outputStream); + writer.write(sheetName, data, false); + writer.close(); + } + + public ContentWriter createWriter(boolean xssf, String outFileName, boolean replace) { + try { + if(outFileName == null || outFileName.isEmpty()) return null; + if (replace) removeIfExist(outFileName); + return new AsyncWriter(xssf, outFileName); + } catch (IOException e) {LOG.log(Level.WARNING, e.getMessage());} + return null; + } + + public ContentWriter createAsyncWriter(int rowSize, String outFileName, boolean replace) { + try { + if(outFileName == null || outFileName.isEmpty()) return null; + if (replace) removeIfExist(outFileName); + return new AsyncStreamWriter(rowSize, outFileName); + } catch (IOException e) {LOG.log(Level.WARNING, e.getMessage());} + return null; + } + + private boolean removeIfExist(String outFileName){ + try { + File outFile = new File(outFileName); + if (outFile.exists() && outFile.isFile()){ + return outFile.delete(); + } + } catch (Exception e) {LOG.log(Level.WARNING, e.getMessage());} + return false; + } + + //AsyncWriter Start: + public static class AsyncWriter implements ContentWriter> { + + protected Workbook workbook; + protected OutputStream outfile; + + public AsyncWriter() {} + + public AsyncWriter(boolean xssf, OutputStream outputStream) throws IOException { + this.workbook = WorkbookFactory.create(xssf); + this.outfile = outputStream; + } + + public AsyncWriter(boolean xssf, String fileNameToWrite) throws IOException { + this(xssf, new FileOutputStream(fileNameToWrite, true)); + } + + @Override + public void close() throws Exception { + if (workbook != null) { + workbook.write(outfile); + if (outfile != null) { + outfile.close(); + outfile = null; + } + if (workbook instanceof SXSSFWorkbook){ + ((SXSSFWorkbook) workbook).dispose(); + } + workbook.close(); + workbook = null; + } + } + + public void write(String sheetName, Map> data, boolean skipZeroIndex) { + //DoTheMath: + Sheet sheet = workbook.getSheet(sheetName); + if(sheet == null) sheet = workbook.createSheet(sheetName); + int rowIndex = 0; + for (Map.Entry> entry : data.entrySet()){ + Row row = sheet.createRow((skipZeroIndex) ? entry.getKey() : rowIndex); + int cellIndex = 0; + for (String cellVal : entry.getValue()) { + Cell cell = row.createCell(cellIndex); + cell.setCellValue(cellVal); + if(sheet instanceof XSSFSheet) + sheet.autoSizeColumn(cellIndex); + cellIndex++; + } + rowIndex++; + } + } + + } + //AsyncWriter Done: + + public static class AsyncStreamWriter extends AsyncWriter{ + + public AsyncStreamWriter(int rowSize, OutputStream outputStream){ + if (rowSize <= 0) rowSize = 100; + this.workbook = new SXSSFWorkbook(rowSize); + this.outfile = outputStream; + } + + public AsyncStreamWriter(int rowSize, String fileNameToWrite) throws IOException { + this(rowSize, new FileOutputStream(fileNameToWrite, true)); + } + + } + +} diff --git a/ReportContentIOKit/src/main/java/com/infoworks/lab/services/pdf/PdfWritingService.java b/ReportContentIOKit/src/main/java/com/infoworks/lab/services/pdf/PdfWritingService.java new file mode 100644 index 0000000..cbb72ee --- /dev/null +++ b/ReportContentIOKit/src/main/java/com/infoworks/lab/services/pdf/PdfWritingService.java @@ -0,0 +1,73 @@ +package com.infoworks.lab.services.pdf; + + +import com.infoworks.lab.definition.ContentWriter; +import com.infoworks.lab.definition.WritingService; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class PdfWritingService implements WritingService { + + private static Logger LOG = Logger.getLogger(PdfWritingService.class.getSimpleName()); + + @Override + public void write(OutputStream outputStream, String sheetName, Map> data) throws Exception { + AsyncWriter writer = new AsyncWriter(outputStream); + writer.write(sheetName, data, false); + writer.close(); + } + + public ContentWriter createWriter(String outFileName, boolean replace) { + try { + if(outFileName == null || outFileName.isEmpty()) return null; + if (replace) removeIfExist(outFileName); + return new AsyncWriter(outFileName); + } catch (IOException e) {LOG.log(Level.WARNING, e.getMessage());} + return null; + } + + private boolean removeIfExist(String outFileName) { + try { + File outFile = new File(outFileName); + if (outFile.exists() && outFile.isFile()){ + return outFile.delete(); + } + } catch (Exception e) {LOG.log(Level.WARNING, e.getMessage());} + return false; + } + + //AsyncWriter Start: + public static class AsyncWriter implements ContentWriter> { + + protected OutputStream outfile; + + public AsyncWriter(OutputStream outputStream) throws IOException { + this.outfile = outputStream; + } + + public AsyncWriter(String fileNameToWrite) throws IOException { + this(new FileOutputStream(fileNameToWrite, true)); + } + + @Override + public void close() throws Exception { + if (outfile != null) { + outfile.close(); + outfile = null; + } + } + + @Override + public void write(String sheetName, Map> data, boolean skipZeroIndex) { + //TODO: Use iText Pdf writing api to implement pdf content writing: + } + + } +} diff --git a/ReportContentIOKit/src/test/java/com/infoworks/lab/services/excel/ExcelReadingServiceTest.java b/ReportContentIOKit/src/test/java/com/infoworks/lab/services/excel/ExcelReadingServiceTest.java new file mode 100644 index 0000000..acb68ba --- /dev/null +++ b/ReportContentIOKit/src/test/java/com/infoworks/lab/services/excel/ExcelReadingServiceTest.java @@ -0,0 +1,17 @@ +package com.infoworks.lab.services.excel; + +import org.junit.After; +import org.junit.Before; + +import static org.junit.Assert.*; + +public class ExcelReadingServiceTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } +} \ No newline at end of file diff --git a/ReportContentIOKit/src/test/java/com/infoworks/lab/services/excel/ExcelWritingServiceTest.java b/ReportContentIOKit/src/test/java/com/infoworks/lab/services/excel/ExcelWritingServiceTest.java new file mode 100644 index 0000000..51f78ea --- /dev/null +++ b/ReportContentIOKit/src/test/java/com/infoworks/lab/services/excel/ExcelWritingServiceTest.java @@ -0,0 +1,17 @@ +package com.infoworks.lab.services.excel; + +import org.junit.After; +import org.junit.Before; + +import static org.junit.Assert.*; + +public class ExcelWritingServiceTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } +} \ No newline at end of file diff --git a/ReportContentIOKit/src/test/java/com/infoworks/lab/services/pdf/PdfWritingServiceTest.java b/ReportContentIOKit/src/test/java/com/infoworks/lab/services/pdf/PdfWritingServiceTest.java new file mode 100644 index 0000000..342d3e9 --- /dev/null +++ b/ReportContentIOKit/src/test/java/com/infoworks/lab/services/pdf/PdfWritingServiceTest.java @@ -0,0 +1,17 @@ +package com.infoworks.lab.services.pdf; + +import org.junit.After; +import org.junit.Before; + +import static org.junit.Assert.*; + +public class PdfWritingServiceTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7f62f96..c457f97 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ Simulator LedgerBook TFObjectDetectorKit + ReportContentIOKit