1 package com.gh.mygreen.xlsmapper.util;
2
3 import java.awt.Point;
4 import java.lang.reflect.Field;
5 import java.lang.reflect.InvocationTargetException;
6 import java.lang.reflect.Method;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.Date;
11 import java.util.List;
12 import java.util.TimeZone;
13 import java.util.concurrent.atomic.AtomicBoolean;
14
15 import org.apache.poi.common.usermodel.HyperlinkType;
16 import org.apache.poi.hssf.model.InternalSheet;
17 import org.apache.poi.hssf.model.InternalWorkbook;
18 import org.apache.poi.hssf.record.DVRecord;
19 import org.apache.poi.hssf.record.Record;
20 import org.apache.poi.hssf.record.aggregates.DataValidityTable;
21 import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
22 import org.apache.poi.hssf.usermodel.HSSFSheet;
23 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
24 import org.apache.poi.ss.SpreadsheetVersion;
25 import org.apache.poi.ss.usermodel.BorderStyle;
26 import org.apache.poi.ss.usermodel.Cell;
27 import org.apache.poi.ss.usermodel.CellStyle;
28 import org.apache.poi.ss.usermodel.CellType;
29 import org.apache.poi.ss.usermodel.DataValidation;
30 import org.apache.poi.ss.usermodel.DataValidationConstraint;
31 import org.apache.poi.ss.usermodel.DataValidationHelper;
32 import org.apache.poi.ss.usermodel.Hyperlink;
33 import org.apache.poi.ss.usermodel.Name;
34 import org.apache.poi.ss.usermodel.Row;
35 import org.apache.poi.ss.usermodel.Sheet;
36 import org.apache.poi.ss.usermodel.Workbook;
37 import org.apache.poi.ss.util.AreaReference;
38 import org.apache.poi.ss.util.CellRangeAddress;
39 import org.apache.poi.ss.util.CellRangeAddressBase;
40 import org.apache.poi.ss.util.CellRangeAddressList;
41 import org.apache.poi.ss.util.CellReference;
42 import org.apache.poi.xssf.usermodel.XSSFSheet;
43 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
44 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation;
45 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidations;
46 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 import com.gh.mygreen.xlsmapper.CellFormatter;
51 import com.gh.mygreen.xlsmapper.DefaultCellFormatter;
52 import com.github.mygreen.cellformatter.lang.ExcelDateUtils;
53
54
55
56
57
58
59
60
61 public class POIUtils {
62
63 private static final Logger logger = LoggerFactory.getLogger(POIUtils.class);
64
65
66 private static CellFormatter defaultCellFormatter = new DefaultCellFormatter();
67
68
69
70
71
72
73
74
75
76 public static SpreadsheetVersion getVersion(final Sheet sheet) {
77 ArgUtils.notNull(sheet, "sheet");
78
79 if(sheet instanceof HSSFSheet) {
80 return SpreadsheetVersion.EXCEL97;
81
82 } else if(sheet instanceof XSSFSheet) {
83 return SpreadsheetVersion.EXCEL2007;
84 }
85
86 return null;
87 }
88
89
90
91
92
93
94
95
96 public static int getColumns(final Sheet sheet) {
97 ArgUtils.notNull(sheet, "sheet");
98
99 int minRowIndex = sheet.getFirstRowNum();
100 int maxRowIndex = sheet.getLastRowNum();
101 int maxColumnsIndex = 0;
102 for(int i = minRowIndex; i <= maxRowIndex; i++) {
103 final Row row = sheet.getRow(i);
104 if(row == null) {
105 continue;
106 }
107
108 final int column = row.getLastCellNum();
109 if(column > maxColumnsIndex) {
110 maxColumnsIndex = column;
111 }
112 }
113
114 return maxColumnsIndex;
115 }
116
117
118
119
120
121
122
123
124
125 public static int getRows(final Sheet sheet) {
126 ArgUtils.notNull(sheet, "sheet");
127 return sheet.getLastRowNum() + 1;
128 }
129
130
131
132
133
134
135
136
137
138 public static Cell getCell(final Sheet sheet, final Point address) {
139 ArgUtils.notNull(sheet, "sheet");
140 ArgUtils.notNull(address, "address");
141 return getCell(sheet, address.x, address.y);
142 }
143
144
145
146
147
148
149
150
151
152 public static Cell getCell(final Sheet sheet, final CellPosition address) {
153 ArgUtils.notNull(sheet, "sheet");
154 ArgUtils.notNull(address, "address");
155 return getCell(sheet, address.getColumn(), address.getRow());
156 }
157
158
159
160
161
162
163
164
165
166
167
168 public static Cell getCell(final Sheet sheet, final int column, final int row) {
169 ArgUtils.notNull(sheet, "sheet");
170
171 Row rows = sheet.getRow(row);
172 if(rows == null) {
173 rows = sheet.createRow(row);
174 }
175
176 Cell cell = rows.getCell(column);
177 if(cell == null) {
178 cell = rows.createCell(column, CellType.BLANK);
179 }
180
181 return cell;
182 }
183
184
185
186
187
188
189
190
191
192
193 public static Cell[] getRow(final Sheet sheet, final int row) {
194 ArgUtils.notNull(sheet, "sheet");
195
196 Row rows = sheet.getRow(row);
197 if(rows == null) {
198 rows = sheet.createRow(row);
199 }
200 int maxColumn = getColumns(sheet);
201 Cell[] cells = new Cell[maxColumn];
202 for(int i=0; i < maxColumn; i++) {
203 Cell cell = rows.getCell(i);
204 if(cell == null) {
205 cell = rows.createCell(i, CellType.BLANK);
206 }
207 cells[i] = cell;
208 }
209
210 return cells;
211 }
212
213
214
215
216
217
218
219
220
221
222 public static Cell[] getColumn(final Sheet sheet, final int col) {
223 ArgUtils.notNull(sheet, "sheet");
224
225 int maxRow = getRows(sheet);
226 Cell[] cells = new Cell[maxRow];
227 for(int i=0; i < maxRow; i++) {
228 Row rows = sheet.getRow(i);
229 if(rows == null) {
230 rows = sheet.createRow(i);
231
232 }
233
234 Cell cell = rows.getCell(col);
235 if(cell == null) {
236 cell = rows.createCell(col, CellType.BLANK);
237 }
238
239 cells[i] = cell;
240 }
241
242 return cells;
243 }
244
245
246
247
248
249
250
251
252
253 public static String getCellContents(final Cell cell, final CellFormatter cellFormatter) {
254 ArgUtils.notNull(cell, "cell");
255 ArgUtils.notNull(cellFormatter, "cellFormatter");
256
257 return cellFormatter.format(cell);
258
259 }
260
261
262
263
264
265
266
267 public static boolean isEmptyCellContents(final Cell cell) {
268 return isEmptyCellContents(cell, defaultCellFormatter);
269 }
270
271
272
273
274
275
276
277
278
279 public static boolean isEmptyCellContents(final Cell cell, final CellFormatter cellFormatter) {
280 ArgUtils.notNull(cell, "cell");
281 ArgUtils.notNull(cellFormatter, "cellFormatter");
282
283 return getCellContents(cell, cellFormatter).isEmpty();
284 }
285
286
287
288
289
290
291
292
293
294 public static short getDataFormatIndex(final Sheet sheet, final String pattern) {
295 ArgUtils.notNull(sheet, "sheet");
296 ArgUtils.notEmpty(pattern, "pattern");
297
298 return sheet.getWorkbook().getCreationHelper().createDataFormat().getFormat(pattern);
299
300 }
301
302
303
304
305
306
307
308
309
310
311 public static String getCellFormatPattern(final Cell cell, final CellFormatter cellFormatter) {
312 if(cell == null) {
313 return "";
314 }
315
316 String pattern = cellFormatter.getPattern(cell);
317 if(pattern.equalsIgnoreCase("general")) {
318 return "";
319 }
320
321 return pattern;
322
323 }
324
325
326
327
328
329
330
331
332
333
334
335 public static CellRangeAddress mergeCells(final Sheet sheet, int startCol, int startRow, int endCol, int endRow) {
336 ArgUtils.notNull(sheet, "sheet");
337
338
339 for(int r=startRow; r <= endRow; r++) {
340 for(int c=startCol; c <= endCol; c++) {
341
342 if(r == startRow && c == startCol) {
343 continue;
344 }
345
346 Cell cell = getCell(sheet, c, r);
347 cell.setBlank();
348 }
349 }
350
351 final CellRangeAddress range = new CellRangeAddress(startRow, endRow, startCol, endCol);
352 sheet.addMergedRegion(range);
353 return range;
354 }
355
356
357
358
359
360
361
362
363
364 public static CellRangeAddress getMergedRegion(final Sheet sheet, final int rowIdx, final int colIdx) {
365 ArgUtils.notNull(sheet, "sheet");
366
367 final int num = sheet.getNumMergedRegions();
368 for(int i=0; i < num; i ++) {
369 final CellRangeAddress range = sheet.getMergedRegion(i);
370 if(range.isInRange(rowIdx, colIdx)) {
371 return range;
372 }
373 }
374
375 return null;
376 }
377
378
379
380
381
382
383
384 public static boolean removeMergedRange(final Sheet sheet, final CellRangeAddress mergedRange) {
385 ArgUtils.notNull(sheet, "sheet");
386 ArgUtils.notNull(mergedRange, "mergedRange");
387
388 final String mergedAddress = mergedRange.formatAsString(sheet.getSheetName(), true);
389
390 final int num = sheet.getNumMergedRegions();
391 for(int i=0; i < num; i ++) {
392 final CellRangeAddress range = sheet.getMergedRegion(i);
393 final String rangeAddress = range.formatAsString(sheet.getSheetName(), true);
394 if(rangeAddress.equals(mergedAddress)) {
395 sheet.removeMergedRegion(i);
396 return true;
397 }
398 }
399
400 return false;
401 }
402
403
404
405
406
407
408
409
410 public static int getColumnSize(final CellRangeAddress region) {
411 if(region == null) {
412 return 0;
413 }
414 return region.getLastColumn() - region.getFirstColumn() + 1;
415 }
416
417
418
419
420
421
422
423
424 public static int getRowSize(final CellRangeAddress region) {
425 if(region == null) {
426 return 0;
427 }
428 return region.getLastRow() - region.getFirstRow() + 1;
429 }
430
431
432
433
434
435
436
437 public static Row insertRow(final Sheet sheet, final int rowIndex) {
438
439 ArgUtils.notNull(sheet, "sheet");
440 ArgUtils.notMin(rowIndex, 0, "rowIndex");
441
442
443 int lastRow = sheet.getLastRowNum();
444 if(lastRow < rowIndex) {
445
446 return sheet.createRow(rowIndex);
447 }
448
449 sheet.shiftRows(rowIndex, lastRow+1, 1);
450 return sheet.createRow(rowIndex);
451 }
452
453
454
455
456
457
458
459
460
461 public static Row removeRow(final Sheet sheet, final int rowIndex) {
462
463 ArgUtils.notNull(sheet, "cell");
464 ArgUtils.notMin(rowIndex, 0, "rowIndex");
465
466 final Row row = sheet.getRow(rowIndex);
467 if(row == null) {
468
469 return row;
470 }
471
472 sheet.removeRow(row);
473
474
475 int lastRow = sheet.getLastRowNum();
476 if(rowIndex +1 > lastRow) {
477 return row;
478 }
479
480 sheet.shiftRows(rowIndex+1, lastRow, -1);
481
482 return row;
483 }
484
485
486
487
488
489
490
491
492 public static String formatCellAddress(final int rowIndex, final int colIndex) {
493 return CellReference.convertNumToColString(colIndex) + String.valueOf(rowIndex+1);
494 }
495
496
497
498
499
500
501
502 public static String formatCellAddress(final Point cellAddress) {
503 ArgUtils.notNull(cellAddress, "cellAddress");
504 return formatCellAddress(cellAddress.y, cellAddress.x);
505 }
506
507
508
509
510
511
512 public static String formatCellAddress(final Cell cell) {
513 ArgUtils.notNull(cell, "cell");
514 return CellReference.convertNumToColString(cell.getColumnIndex()) + String.valueOf(cell.getRowIndex()+1);
515 }
516
517
518
519
520
521
522
523 public static HyperlinkType judgeLinkType(final String linkAddress) {
524
525 ArgUtils.notEmpty(linkAddress, "linkAddress");
526
527 if(linkAddress.matches(".*![\\p{Alnum}]+")) {
528
529 return HyperlinkType.DOCUMENT;
530
531 } else if(linkAddress.matches("[\\p{Alpha}]+[0-9]+")) {
532
533 return HyperlinkType.DOCUMENT;
534
535 } else if(linkAddress.matches(".+@.+")) {
536
537 return HyperlinkType.EMAIL;
538
539 } else if(linkAddress.matches("[\\p{Alpha}]+://.+")) {
540
541 return HyperlinkType.URL;
542
543 } else if(linkAddress.matches(".+\\.[\\p{Alnum}]+")) {
544
545 return HyperlinkType.FILE;
546
547 } else {
548 return HyperlinkType.NONE;
549 }
550
551 }
552
553
554
555
556
557
558
559
560
561 public static boolean updateDataValidationRegion(final Sheet sheet,
562 final CellRangeAddressList oldRegion, final CellRangeAddressList newRegion) {
563
564 ArgUtils.notNull(sheet, "sheet");
565 ArgUtils.notNull(oldRegion, "oldRegion");
566 ArgUtils.notNull(newRegion, "newRegion");
567
568 if(sheet instanceof XSSFSheet) {
569
570 final List<String> oldSqref = convertSqref(oldRegion);
571
572 try {
573 final XSSFSheet xssfSheet = (XSSFSheet) sheet;
574 Field fWorksheet = XSSFSheet.class.getDeclaredField("worksheet");
575 fWorksheet.setAccessible(true);
576 CTWorksheet worksheet = (CTWorksheet) fWorksheet.get(xssfSheet);
577
578 CTDataValidations dataValidations = worksheet.getDataValidations();
579 if(dataValidations == null) {
580 return false;
581 }
582
583 for(int i=0; i < dataValidations.getCount(); i++) {
584 CTDataValidation dv = dataValidations.getDataValidationArray(i);
585
586
587 @SuppressWarnings("unchecked")
588 List<String> sqref = new ArrayList<>(dv.getSqref());
589 if(equalsSqref(sqref, oldSqref)) {
590 List<String> newSqref = convertSqref(newRegion);
591 dv.setSqref(newSqref);
592
593
594 dataValidations.setDataValidationArray(i, dv);
595 return true;
596 }
597
598 }
599
600 return false;
601
602 } catch(Exception e) {
603 throw new RuntimeException("fail update DataValidation's Regsion.", e);
604 }
605
606 } else if(sheet instanceof HSSFSheet) {
607
608 final HSSFSheet hssfSheet = (HSSFSheet) sheet;
609 try {
610 Field fWorksheet = HSSFSheet.class.getDeclaredField("_sheet");
611 fWorksheet.setAccessible(true);
612 InternalSheet worksheet = (InternalSheet) fWorksheet.get(hssfSheet);
613
614 DataValidityTable dvt = worksheet.getOrCreateDataValidityTable();
615
616
617 final AtomicBoolean updated = new AtomicBoolean(false);
618 RecordVisitor visitor = new RecordVisitor() {
619
620 @Override
621 public void visitRecord(final Record r) {
622 if (!(r instanceof DVRecord)) {
623 return;
624 }
625
626 final DVRecord dvRecord = (DVRecord) r;
627 final CellRangeAddressList region = dvRecord.getCellRangeAddress();
628 if(equalsRegion(region, oldRegion)) {
629
630
631 while(region.countRanges() != 0) {
632 region.remove(0);
633 }
634
635
636 for(CellRangeAddress newRange : newRegion.getCellRangeAddresses()) {
637 region.addCellRangeAddress(newRange);
638 }
639
640 updated.set(true);
641 return;
642 }
643 }
644 };
645
646 dvt.visitContainedRecords(visitor);
647
648 return updated.get();
649
650 } catch(Exception e) {
651 throw new RuntimeException("fail update DataValidation's Regsion.", e);
652 }
653 } else {
654 throw new UnsupportedOperationException("not supported update dava validation's region for type " + sheet.getClass().getName());
655 }
656
657 }
658
659
660
661
662
663
664
665 private static List<String> convertSqref(final CellRangeAddressList region) {
666
667 List<String> sqref = new ArrayList<>();
668 for(CellRangeAddress range : region.getCellRangeAddresses()) {
669 sqref.add(range.formatAsString());
670 }
671
672 return sqref;
673
674 }
675
676
677
678
679
680
681
682
683 public static boolean equalsSqref(final List<String> sqref1, final List<String> sqref2) {
684
685 if(sqref1.size() != sqref2.size()) {
686 return false;
687 }
688
689 Collections.sort(sqref1);
690 Collections.sort(sqref2);
691
692 final int size = sqref1.size();
693 for(int i=0; i < size; i++) {
694 if(!sqref1.get(i).equals(sqref2.get(i))) {
695 return false;
696 }
697 }
698
699 return true;
700
701 }
702
703
704
705
706
707
708
709
710 public static boolean equalsRegion(final CellRangeAddressList region1, final CellRangeAddressList region2) {
711
712 return equalsSqref(convertSqref(region1), convertSqref(region2));
713
714 }
715
716
717
718
719
720
721
722
723
724 public static void setupExplicitListConstaint(final Sheet sheet, final Collection<String> constraints,
725 final Point startPosition, final Point endPosition) {
726
727 ArgUtils.notNull(sheet, "sheet");
728 ArgUtils.notEmpty(constraints, "constraints");
729 ArgUtils.notNull(startPosition, "startPosition");
730 ArgUtils.notNull(endPosition, "endPosition");
731
732 setupExplicitListConstaint(sheet, constraints.toArray(new String[constraints.size()]),
733 startPosition, endPosition);
734 }
735
736
737
738
739
740
741
742
743
744 public static void setupExplicitListConstaint(final Sheet sheet, final String[] constraints,
745 final Point startPosition, final Point endPosition) {
746
747 ArgUtils.notNull(sheet, "sheet");
748 ArgUtils.notEmpty(constraints, "constraints");
749 ArgUtils.notNull(startPosition, "startPosition");
750 ArgUtils.notNull(endPosition, "endPosition");
751
752 final DataValidationHelper helper = sheet.getDataValidationHelper();
753 final DataValidationConstraint constraint = helper.createExplicitListConstraint(constraints);
754 setupConstaint(sheet, constraint, startPosition, endPosition);
755
756 }
757
758
759
760
761
762
763
764
765
766 public static void setupFormulaListConstaint(final Sheet sheet, final String listFormula,
767 final Point startPosition, final Point endPosition) {
768
769 ArgUtils.notNull(sheet, "sheet");
770 ArgUtils.notEmpty(listFormula, "listFormula");
771 ArgUtils.notNull(startPosition, "startPosition");
772 ArgUtils.notNull(endPosition, "endPosition");
773
774 final DataValidationHelper helper = sheet.getDataValidationHelper();
775 final DataValidationConstraint constraint = helper.createFormulaListConstraint("=" + listFormula);
776 setupConstaint(sheet, constraint, startPosition, endPosition);
777 }
778
779
780
781
782
783
784
785
786
787 public static void setupConstaint(final Sheet sheet, final DataValidationConstraint constraint,
788 final Point startPosition, final Point endPosition) {
789
790 ArgUtils.notNull(sheet, "sheet");
791 ArgUtils.notNull(constraint, "constraint");
792 ArgUtils.notNull(startPosition, "startPosition");
793 ArgUtils.notNull(endPosition, "endPosition");
794
795 final DataValidationHelper helper = sheet.getDataValidationHelper();
796
797 final CellRangeAddressList region = new CellRangeAddressList(
798 startPosition.y, endPosition.y,
799 startPosition.x, endPosition.x
800 );
801 final DataValidation dataValidation = helper.createValidation(constraint, region);
802 sheet.addValidationData(dataValidation);
803 }
804
805
806
807
808
809
810
811
812
813
814
815 public static Name defineName(final Sheet sheet, final String name,
816 final Point startPosition, final Point endPosition) {
817
818 ArgUtils.notNull(sheet, "sheet");
819 ArgUtils.notEmpty(name, "name");
820 ArgUtils.notNull(startPosition, "startPosition");
821 ArgUtils.notNull(endPosition, "endPosition");
822
823 final Workbook workbook = sheet.getWorkbook();
824 Name nameObj = workbook.getName(name);
825 if(nameObj == null) {
826 nameObj = workbook.createName();
827 nameObj.setNameName(name);
828 }
829
830 final AreaReference areaRef = buildNameArea(sheet.getSheetName(), startPosition, endPosition,
831 sheet.getWorkbook().getSpreadsheetVersion());
832 nameObj.setRefersToFormula(areaRef.formatAsString());
833
834 return nameObj;
835
836 }
837
838
839
840
841
842
843
844
845
846
847 public static AreaReference buildNameArea(final String sheetName,
848 final Point startPosition, final Point endPosition, SpreadsheetVersion sheetVersion) {
849
850 ArgUtils.notEmpty(sheetName, "sheetName");
851 ArgUtils.notNull(startPosition, "startPosition");
852 ArgUtils.notNull(endPosition, "endPosition");
853
854 final CellReference firstRefs = new CellReference(sheetName, startPosition.y, startPosition.x, true, true);
855 final CellReference lastRefs = new CellReference(sheetName, endPosition.y, endPosition.x, true, true);
856
857 return new AreaReference(firstRefs, lastRefs, sheetVersion);
858 }
859
860
861
862
863
864
865
866
867
868 public static boolean intersectsRegion(final CellRangeAddressBase my, final CellRangeAddressBase other) {
869 return my.getFirstRow() <= other.getLastRow() &&
870 my.getFirstColumn() <= other.getLastColumn() &&
871 other.getFirstRow() <= my.getLastRow() &&
872 other.getFirstColumn() <= my.getLastColumn();
873 }
874
875
876
877
878
879
880
881 public static boolean isDateStart1904(final Workbook workbook) {
882
883 if(workbook instanceof HSSFWorkbook) {
884 try {
885 Method method = HSSFWorkbook.class.getDeclaredMethod("getWorkbook");
886 method.setAccessible(true);
887
888 InternalWorkbook iw = (InternalWorkbook) method.invoke(workbook);
889 return iw.isUsing1904DateWindowing();
890
891 } catch(NoSuchMethodException | SecurityException e) {
892 logger.warn("fail access method HSSFWorkbook.getWorkbook.", e);
893 return false;
894 } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
895 logger.warn("fail invoke method HSSFWorkbook.getWorkbook.", e);
896 return false;
897 }
898
899 } else if(workbook instanceof XSSFWorkbook) {
900 try {
901 Method method = XSSFWorkbook.class.getDeclaredMethod("isDate1904");
902 method.setAccessible(true);
903
904 boolean value = (boolean) method.invoke(workbook);
905 return value;
906
907 } catch(NoSuchMethodException | SecurityException e) {
908 logger.warn("fail access method XSSFWorkbook.isDate1904.", e);
909 return false;
910 } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
911 logger.warn("fail invoke method XSSFWorkbook.isDate1904.", e);
912 return false;
913 }
914
915 } else {
916 logger.warn("unknown workbook type.", workbook.getClass().getName());
917 }
918
919 return false;
920 }
921
922
923
924
925
926
927
928
929 public static BorderStyle getBorderTop(final Cell cell) {
930
931 ArgUtils.notNull(cell, "cell");
932
933 final Sheet sheet = cell.getSheet();
934 CellRangeAddress mergedRegion = getMergedRegion(sheet, cell.getRowIndex(), cell.getColumnIndex());
935
936 final Cell target;
937 if(mergedRegion == null) {
938
939 target = cell;
940
941 } else {
942 if(mergedRegion.getFirstRow() == cell.getRowIndex()) {
943
944 target = cell;
945 } else {
946 target = getCell(sheet, cell.getColumnIndex(), mergedRegion.getFirstRow());
947 }
948
949 }
950
951 final CellStyle style = target.getCellStyle();
952 if(style == null) {
953 return BorderStyle.NONE;
954 } else {
955 return style.getBorderTop();
956 }
957
958 }
959
960
961
962
963
964
965
966
967 public static BorderStyle getBorderBottom(final Cell cell) {
968
969 ArgUtils.notNull(cell, "cell");
970
971 final Sheet sheet = cell.getSheet();
972 CellRangeAddress mergedRegion = getMergedRegion(sheet, cell.getRowIndex(), cell.getColumnIndex());
973
974 final Cell target;
975 if(mergedRegion == null) {
976
977 target = cell;
978
979 } else {
980 if(mergedRegion.getLastRow() == cell.getRowIndex()) {
981
982 target = cell;
983 } else {
984 target = getCell(sheet, cell.getColumnIndex(), mergedRegion.getLastRow());
985 }
986
987 }
988
989 final CellStyle style = target.getCellStyle();
990 if(style == null) {
991 return BorderStyle.NONE;
992 } else {
993 return style.getBorderBottom();
994 }
995
996 }
997
998
999
1000
1001
1002
1003
1004
1005 public static BorderStyle getBorderRight(final Cell cell) {
1006
1007 ArgUtils.notNull(cell, "cell");
1008
1009 final Sheet sheet = cell.getSheet();
1010 CellRangeAddress mergedRegion = getMergedRegion(sheet, cell.getRowIndex(), cell.getColumnIndex());
1011
1012 final Cell target;
1013 if(mergedRegion == null) {
1014
1015 target = cell;
1016
1017 } else {
1018 if(mergedRegion.getLastColumn() == cell.getColumnIndex()) {
1019
1020 target = cell;
1021 } else {
1022 target = getCell(sheet, mergedRegion.getLastColumn(), cell.getRowIndex());
1023 }
1024
1025 }
1026
1027 final CellStyle style = target.getCellStyle();
1028 if(style == null) {
1029 return BorderStyle.NONE;
1030 } else {
1031 return style.getBorderRight();
1032 }
1033
1034 }
1035
1036
1037
1038
1039
1040
1041
1042
1043 public static BorderStyle getBorderLeft(final Cell cell) {
1044
1045 ArgUtils.notNull(cell, "cell");
1046
1047 final Sheet sheet = cell.getSheet();
1048 CellRangeAddress mergedRegion = getMergedRegion(sheet, cell.getRowIndex(), cell.getColumnIndex());
1049
1050 final Cell target;
1051 if(mergedRegion == null) {
1052
1053 target = cell;
1054
1055 } else {
1056 if(mergedRegion.getFirstColumn() == cell.getColumnIndex()) {
1057
1058 target = cell;
1059 } else {
1060 target = getCell(sheet, mergedRegion.getFirstColumn(), cell.getRowIndex());
1061 }
1062
1063 }
1064
1065 final CellStyle style = target.getCellStyle();
1066 if(style == null) {
1067 return BorderStyle.NONE;
1068 } else {
1069 return style.getBorderLeft();
1070 }
1071
1072 }
1073
1074
1075
1076
1077
1078
1079
1080
1081 public static Hyperlink getHyperlink(final Cell cell) {
1082
1083 ArgUtils.notNull(cell, "cell");
1084
1085 Hyperlink link = cell.getHyperlink();
1086 if(link != null) {
1087 return link;
1088 }
1089
1090 final Sheet sheet = cell.getSheet();
1091 CellRangeAddress mergedRange = getMergedRegion(sheet, cell.getRowIndex(), cell.getColumnIndex());
1092 if(mergedRange == null) {
1093 return null;
1094 }
1095
1096 for(Hyperlink item : sheet.getHyperlinkList()) {
1097 if(item.getFirstRow() == mergedRange.getFirstRow()
1098 && item.getFirstColumn() == mergedRange.getFirstColumn()) {
1099 return item;
1100 }
1101
1102 }
1103
1104 return null;
1105
1106 }
1107
1108
1109
1110
1111
1112 public static final long MILLISECONDS_19000101_END = ExcelDateUtils.parseDate("1900-01-01 23:59:54.999").getTime();
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122 public static void setCellValueAsDate(Cell cell, Date date, boolean dateStart1904) {
1123
1124 ArgUtils.notNull(cell, "cell");
1125 ArgUtils.notNull(date, "date");
1126
1127 if(dateStart1904) {
1128
1129 cell.setCellValue(date);
1130
1131 } else {
1132
1133 long timemills = date.getTime();
1134 if(timemills <= MILLISECONDS_19000101_END) {
1135
1136
1137 Date strip = new Date(date.getTime() + TimeZone.getDefault().getRawOffset());
1138 double num = ExcelDateUtils.convertExcelNumber(strip, dateStart1904);
1139 cell.setCellValue(num);
1140
1141 } else {
1142 cell.setCellValue(date);
1143 }
1144
1145 }
1146
1147 }
1148
1149 }