1 package net.technearts;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import java.nio.file.Path;
9 import java.text.DecimalFormat;
10 import java.util.HashMap;
11 import java.util.Iterator;
12 import java.util.Map;
13 import java.util.SortedSet;
14 import java.util.TreeSet;
15 import java.util.function.Consumer;
16 import java.util.function.Predicate;
17 import java.util.stream.Collectors;
18
19 import org.apache.poi.ss.usermodel.Cell;
20 import org.apache.poi.ss.usermodel.Row;
21 import org.apache.poi.ss.usermodel.Sheet;
22 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
23
24 import com.google.common.collect.Streams;
25
26 public class ExcelFile implements AutoCloseable {
27 private static final DecimalFormat DECIMAL = new DecimalFormat();
28 static {
29 DECIMAL.setMaximumFractionDigits(340);
30 DECIMAL.setMaximumIntegerDigits(309);
31 DECIMAL.setMinimumFractionDigits(0);
32 DECIMAL.setMinimumIntegerDigits(0);
33 DECIMAL.setGroupingUsed(false);
34 }
35 private XSSFWorkbook workbook;
36 private Map<String, Sheet> sheets;
37
38 public ExcelFile(Path path) throws FileNotFoundException, IOException {
39 this(path.toFile());
40 }
41
42 public ExcelFile(File file) throws FileNotFoundException, IOException {
43 this.workbook = new XSSFWorkbook(new FileInputStream(file));
44 sheets = new HashMap<>();
45 Iterator<Sheet> i = this.workbook.sheetIterator();
46 while (i.hasNext()) {
47 Sheet sheet = i.next();
48 sheets.put(sheet.getSheetName(), sheet);
49 }
50 }
51
52 public <T> T read(String sheetName, int line, int column, Converter<T> function,
53 Consumer<T> action) {
54 T result = read(sheetName, line, column, function);
55 action.accept(result);
56 return result;
57 }
58
59 public <T> T read(String sheetName, int line, int column, Converter<T> function) {
60 String result = read(sheetName, line, column);
61 try {
62 return function.apply(result);
63 } catch (NullPointerException e) {
64 return null;
65 }
66 }
67
68 public String read(String sheetName, int line, int column, Consumer<String> action) {
69 String result = read(sheetName, line, column);
70 action.accept(result);
71 return result;
72 }
73
74 public String read(String sheetName, int line, int column) {
75 String result;
76 try {
77 Sheet sheet = sheets.get(sheetName);
78 Row row = sheet.getRow(line);
79 Cell cell = row.getCell(column);
80 result = getCellValue(cell);
81 } catch (IllegalStateException | NullPointerException e) {
82 result = null;
83 }
84 return result;
85 }
86
87 public <T> void write(String sheetName, int line, int column, T value) {
88 Sheet sheet = sheets.get(sheetName);
89 Row row = sheet.getRow(line);
90 if (row == null) {
91 row = sheet.createRow(line);
92 }
93 Cell cell = row.getCell(column);
94 if (cell == null) {
95 cell = row.createCell(column);
96 }
97 setCellValue(cell, value);
98 }
99
100 public SortedSet<Integer> getRows(String sheetName, Predicate<Row> predicate) {
101 Sheet sheet = sheets.get(sheetName);
102 return Streams.stream(sheet::iterator).filter(predicate).map(row -> row.getRowNum())
103 .collect(Collectors.toCollection(TreeSet::new));
104 }
105
106 public int getColumn(String sheetName, Predicate<Cell> predicate) {
107 Sheet sheet = sheets.get(sheetName);
108 Iterator<Row> rows = sheet.iterator();
109 Iterator<Cell> cells;
110 Row row;
111 Cell cell;
112 while (rows.hasNext()) {
113 row = rows.next();
114 cells = row.cellIterator();
115 while (cells.hasNext()) {
116 cell = cells.next();
117 if (predicate.test(cell)) {
118 return cell.getColumnIndex();
119 }
120 }
121 }
122 return -1;
123 }
124
125 private String getCellValue(Cell cell) {
126 if (cell == null) {
127 return null;
128 }
129 switch (cell.getCellTypeEnum()) {
130 case STRING:
131 return cell.getStringCellValue();
132 case NUMERIC:
133 return DECIMAL.format(cell.getNumericCellValue());
134 case BOOLEAN:
135 return Boolean.toString(cell.getBooleanCellValue());
136 case _NONE:
137 case BLANK:
138 case FORMULA:
139 case ERROR:
140 default:
141 return null;
142 }
143 }
144
145 private void setCellValue(Cell cell, Object value) {
146 if (value.getClass().isAssignableFrom(Double.class)) {
147 cell.setCellValue((double) value);
148 } else if (value.getClass().isAssignableFrom(Boolean.class)) {
149 cell.setCellValue((boolean) value);
150 } else if (value.getClass().isAssignableFrom(Integer.class)) {
151 cell.setCellValue((int) value);
152 } else {
153 cell.setCellValue(value.toString());
154 }
155 }
156
157 public ExcelSheet sheet(String sheetName) {
158 return new ExcelSheet(this, sheetName);
159 }
160
161 public void save(Path path) {
162 save(path.toFile());
163 }
164
165 public void save(File file) {
166 try {
167 workbook.write(new FileOutputStream(file));
168 } catch (IOException e) {
169 throw new IllegalArgumentException("Arquivo não existe", e);
170 }
171 }
172
173 @Override
174 public void close() {
175 try {
176 workbook.close();
177 } catch (IOException e) {
178 ;
179 }
180 }
181
182 class ExcelSheet {
183 private final String sheet;
184 private final ExcelFile file;
185
186 private ExcelSheet(ExcelFile file, String sheet) {
187 this.sheet = sheet;
188 this.file = file;
189 }
190
191 public <T> T read(int line, int column, Converter<T> function, Consumer<T> action) {
192 return file.read(sheet, line, column, function, action);
193 }
194
195 public <T> T read(int line, int column, Converter<T> function) {
196 return file.read(sheet, line, column, function);
197 }
198
199 public String read(int line, int column, Consumer<String> action) {
200 return file.read(sheet, line, column, action);
201 }
202
203 public String read(int line, int column) {
204 return file.read(sheet, line, column);
205 }
206
207 public <T> void write(int line, int column, T value) {
208 file.write(sheet, line, column, value);
209 }
210
211 public SortedSet<Integer> getRows(Predicate<Row> predicate) {
212 return file.getRows(sheet, predicate);
213 }
214
215 public String toString() {
216 return sheet;
217 }
218
219 public int getColumn(Predicate<Cell> predicate) {
220 return file.getColumn(sheet, predicate);
221 }
222 }
223 }