embulk-parser-poi_excel 0.1.5 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +80 -21
  3. data/build.gradle +21 -11
  4. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  5. data/gradle/wrapper/gradle-wrapper.properties +5 -6
  6. data/gradlew +43 -35
  7. data/gradlew.bat +4 -10
  8. data/src/main/java/org/embulk/parser/poi_excel/PoiExcelColumnValueType.java +25 -3
  9. data/src/main/java/org/embulk/parser/poi_excel/PoiExcelParserPlugin.java +102 -11
  10. data/src/main/java/org/embulk/parser/poi_excel/bean/PoiExcelColumnBean.java +132 -6
  11. data/src/main/java/org/embulk/parser/poi_excel/bean/PoiExcelColumnIndex.java +167 -47
  12. data/src/main/java/org/embulk/parser/poi_excel/bean/PoiExcelSheetBean.java +13 -1
  13. data/src/main/java/org/embulk/parser/poi_excel/bean/record/PoiExcelRecord.java +52 -0
  14. data/src/main/java/org/embulk/parser/poi_excel/bean/record/PoiExcelRecordColumn.java +80 -0
  15. data/src/main/java/org/embulk/parser/poi_excel/bean/record/PoiExcelRecordRow.java +76 -0
  16. data/src/main/java/org/embulk/parser/poi_excel/bean/record/PoiExcelRecordSheet.java +49 -0
  17. data/src/main/java/org/embulk/parser/poi_excel/bean/record/RecordType.java +114 -0
  18. data/src/main/java/org/embulk/parser/poi_excel/bean/util/PoiExcelCellAddress.java +59 -0
  19. data/src/main/java/org/embulk/parser/poi_excel/bean/util/SearchMergedCell.java +71 -0
  20. data/src/main/java/org/embulk/parser/poi_excel/visitor/PoiExcelCellFontVisitor.java +0 -6
  21. data/src/main/java/org/embulk/parser/poi_excel/visitor/PoiExcelCellStyleVisitor.java +11 -11
  22. data/src/main/java/org/embulk/parser/poi_excel/visitor/PoiExcelCellTypeVisitor.java +52 -0
  23. data/src/main/java/org/embulk/parser/poi_excel/visitor/PoiExcelCellValueVisitor.java +87 -41
  24. data/src/main/java/org/embulk/parser/poi_excel/visitor/PoiExcelClientAnchorVisitor.java +1 -1
  25. data/src/main/java/org/embulk/parser/poi_excel/visitor/PoiExcelColumnVisitor.java +60 -12
  26. data/src/main/java/org/embulk/parser/poi_excel/visitor/PoiExcelVisitorFactory.java +14 -0
  27. data/src/main/java/org/embulk/parser/poi_excel/visitor/embulk/BooleanCellVisitor.java +5 -0
  28. data/src/main/java/org/embulk/parser/poi_excel/visitor/embulk/CellVisitor.java +3 -0
  29. data/src/main/java/org/embulk/parser/poi_excel/visitor/embulk/DoubleCellVisitor.java +5 -0
  30. data/src/main/java/org/embulk/parser/poi_excel/visitor/embulk/LongCellVisitor.java +5 -0
  31. data/src/main/java/org/embulk/parser/poi_excel/visitor/embulk/StringCellVisitor.java +30 -2
  32. data/src/main/java/org/embulk/parser/poi_excel/visitor/embulk/TimestampCellVisitor.java +5 -0
  33. data/src/main/java/org/embulk/parser/poi_excel/visitor/util/MergedRegionFinder.java +9 -0
  34. data/src/main/java/org/embulk/parser/poi_excel/visitor/util/MergedRegionList.java +20 -0
  35. data/src/main/java/org/embulk/parser/poi_excel/visitor/util/MergedRegionMap.java +55 -0
  36. data/src/main/java/org/embulk/parser/poi_excel/visitor/util/MergedRegionNothing.java +12 -0
  37. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin.java +27 -79
  38. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_cellAddress.java +69 -0
  39. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_cellComment.java +1 -1
  40. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_cellError.java +1 -1
  41. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_cellFont.java +1 -1
  42. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_cellStyle.java +14 -14
  43. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_cellType.java +79 -0
  44. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_columnNumber.java +1 -1
  45. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_constant.java +1 -1
  46. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_convertError.java +1 -1
  47. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_formula.java +90 -0
  48. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_mergedCell.java +94 -0
  49. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_recordType.java +192 -0
  50. data/src/test/java/org/embulk/parser/poi_excel/TestPoiExcelParserPlugin_sheets.java +35 -1
  51. metadata +36 -17
@@ -0,0 +1,71 @@
1
+ package org.embulk.parser.poi_excel.bean.util;
2
+
3
+ import java.util.HashMap;
4
+ import java.util.Map;
5
+ import java.util.TreeMap;
6
+
7
+ import org.apache.poi.ss.util.CellRangeAddress;
8
+ import org.embulk.parser.poi_excel.visitor.util.MergedRegionFinder;
9
+ import org.embulk.parser.poi_excel.visitor.util.MergedRegionList;
10
+ import org.embulk.parser.poi_excel.visitor.util.MergedRegionMap;
11
+ import org.embulk.parser.poi_excel.visitor.util.MergedRegionNothing;
12
+
13
+ public enum SearchMergedCell {
14
+ NONE {
15
+ @Override
16
+ public MergedRegionFinder createMergedRegionFinder() {
17
+ return new MergedRegionNothing();
18
+ }
19
+ },
20
+ LINEAR_SEARCH {
21
+ @Override
22
+ public MergedRegionFinder createMergedRegionFinder() {
23
+ return new MergedRegionList();
24
+ }
25
+ },
26
+ TREE_SEARCH {
27
+ @Override
28
+ public MergedRegionFinder createMergedRegionFinder() {
29
+ return new MergedRegionMap() {
30
+
31
+ @Override
32
+ protected Map<Integer, Map<Integer, CellRangeAddress>> newRowMap() {
33
+ return new TreeMap<>();
34
+ }
35
+
36
+ @Override
37
+ protected Map<Integer, CellRangeAddress> newColumnMap() {
38
+ return new TreeMap<>();
39
+ }
40
+ };
41
+ }
42
+ },
43
+ HASH_SEARCH {
44
+ @Override
45
+ public MergedRegionFinder createMergedRegionFinder() {
46
+ return new MergedRegionMap() {
47
+
48
+ @Override
49
+ protected Map<Integer, Map<Integer, CellRangeAddress>> newRowMap() {
50
+ return new HashMap<>();
51
+ }
52
+
53
+ @Override
54
+ protected Map<Integer, CellRangeAddress> newColumnMap() {
55
+ return new HashMap<>();
56
+ }
57
+ };
58
+ }
59
+ };
60
+
61
+ private MergedRegionFinder mergedRegionFinder;
62
+
63
+ public MergedRegionFinder getMergedRegionFinder() {
64
+ if (mergedRegionFinder == null) {
65
+ this.mergedRegionFinder = createMergedRegionFinder();
66
+ }
67
+ return mergedRegionFinder;
68
+ }
69
+
70
+ protected abstract MergedRegionFinder createMergedRegionFinder();
71
+ }
@@ -100,12 +100,6 @@ public class PoiExcelCellFontVisitor extends AbstractPoiExcelCellAttributeVisito
100
100
  return (long) font.getIndex();
101
101
  }
102
102
  });
103
- map.put("boldweight", new AttributeSupplier<Font>() {
104
- @Override
105
- public Object get(Column column, Cell cell, Font font) {
106
- return (long) font.getBoldweight();
107
- }
108
- });
109
103
  map.put("bold", new AttributeSupplier<Font>() {
110
104
  @Override
111
105
  public Object get(Column column, Cell cell, Font font) {
@@ -41,16 +41,16 @@ public class PoiExcelCellStyleVisitor extends AbstractPoiExcelCellAttributeVisit
41
41
  map.put("alignment", new AttributeSupplier<CellStyle>() {
42
42
  @Override
43
43
  public Object get(Column column, Cell cell, CellStyle style) {
44
- return (long) style.getAlignment();
44
+ return (long) style.getAlignmentEnum().getCode();
45
45
  }
46
46
  });
47
47
  map.put("border", new AttributeSupplier<CellStyle>() {
48
48
  @Override
49
49
  public Object get(Column column, Cell cell, CellStyle style) {
50
- int n0 = style.getBorderTop();
51
- int n1 = style.getBorderBottom();
52
- int n2 = style.getBorderLeft();
53
- int n3 = style.getBorderRight();
50
+ int n0 = style.getBorderTopEnum().getCode();
51
+ int n1 = style.getBorderBottomEnum().getCode();
52
+ int n2 = style.getBorderLeftEnum().getCode();
53
+ int n3 = style.getBorderRightEnum().getCode();
54
54
  if (column.getType() instanceof StringType) {
55
55
  return String.format("%02x%02x%02x%02x", n0, n1, n2, n3);
56
56
  }
@@ -60,25 +60,25 @@ public class PoiExcelCellStyleVisitor extends AbstractPoiExcelCellAttributeVisit
60
60
  map.put("border_bottom", new AttributeSupplier<CellStyle>() {
61
61
  @Override
62
62
  public Object get(Column column, Cell cell, CellStyle style) {
63
- return (long) style.getBorderBottom();
63
+ return (long) style.getBorderBottomEnum().getCode();
64
64
  }
65
65
  });
66
66
  map.put("border_left", new AttributeSupplier<CellStyle>() {
67
67
  @Override
68
68
  public Object get(Column column, Cell cell, CellStyle style) {
69
- return (long) style.getBorderLeft();
69
+ return (long) style.getBorderLeftEnum().getCode();
70
70
  }
71
71
  });
72
72
  map.put("border_right", new AttributeSupplier<CellStyle>() {
73
73
  @Override
74
74
  public Object get(Column column, Cell cell, CellStyle style) {
75
- return (long) style.getBorderRight();
75
+ return (long) style.getBorderRightEnum().getCode();
76
76
  }
77
77
  });
78
78
  map.put("border_top", new AttributeSupplier<CellStyle>() {
79
79
  @Override
80
80
  public Object get(Column column, Cell cell, CellStyle style) {
81
- return (long) style.getBorderTop();
81
+ return (long) style.getBorderTopEnum().getCode();
82
82
  }
83
83
  });
84
84
  map.put("border_bottom_color", new AttributeSupplier<CellStyle>() {
@@ -154,7 +154,7 @@ public class PoiExcelCellStyleVisitor extends AbstractPoiExcelCellAttributeVisit
154
154
  map.put("fill_pattern", new AttributeSupplier<CellStyle>() {
155
155
  @Override
156
156
  public Object get(Column column, Cell cell, CellStyle style) {
157
- return (long) style.getFillPattern();
157
+ return (long) style.getFillPatternEnum().getCode();
158
158
  }
159
159
  });
160
160
  map.put("font_index", new AttributeSupplier<CellStyle>() {
@@ -190,7 +190,7 @@ public class PoiExcelCellStyleVisitor extends AbstractPoiExcelCellAttributeVisit
190
190
  map.put("vertical_alignment", new AttributeSupplier<CellStyle>() {
191
191
  @Override
192
192
  public Object get(Column column, Cell cell, CellStyle style) {
193
- return (long) style.getVerticalAlignment();
193
+ return (long) style.getVerticalAlignmentEnum().getCode();
194
194
  }
195
195
  });
196
196
  map.put("wrap_text", new AttributeSupplier<CellStyle>() {
@@ -0,0 +1,52 @@
1
+ package org.embulk.parser.poi_excel.visitor;
2
+
3
+ import org.apache.poi.ss.usermodel.Cell;
4
+ import org.apache.poi.ss.usermodel.CellType;
5
+ import org.embulk.parser.poi_excel.bean.PoiExcelColumnBean;
6
+ import org.embulk.parser.poi_excel.visitor.embulk.CellVisitor;
7
+ import org.embulk.spi.Column;
8
+ import org.embulk.spi.PageBuilder;
9
+ import org.embulk.spi.type.StringType;
10
+
11
+ public class PoiExcelCellTypeVisitor {
12
+ protected final PoiExcelVisitorValue visitorValue;
13
+ protected final PageBuilder pageBuilder;
14
+
15
+ public PoiExcelCellTypeVisitor(PoiExcelVisitorValue visitorValue) {
16
+ this.visitorValue = visitorValue;
17
+ this.pageBuilder = visitorValue.getPageBuilder();
18
+ }
19
+
20
+ public void visit(PoiExcelColumnBean bean, Cell cell, CellType cellType, CellVisitor visitor) {
21
+ assert cell != null;
22
+
23
+ Column column = bean.getColumn();
24
+ if (column.getType() instanceof StringType) {
25
+ String type = cellType.name();
26
+ visitor.visitCellValueString(column, cell, type);
27
+ return;
28
+ }
29
+
30
+ int code = getCode(cellType);
31
+ visitor.visitCellValueNumeric(column, cell, code);
32
+ }
33
+
34
+ private static int getCode(CellType cellType) {
35
+ switch (cellType) {
36
+ case NUMERIC:
37
+ return 0;
38
+ case STRING:
39
+ return 1;
40
+ case FORMULA:
41
+ return 2;
42
+ case BLANK:
43
+ return 3;
44
+ case BOOLEAN:
45
+ return 4;
46
+ case ERROR:
47
+ return 5;
48
+ default:
49
+ return -1;
50
+ }
51
+ }
52
+ }
@@ -4,6 +4,7 @@ import java.text.MessageFormat;
4
4
  import java.util.List;
5
5
 
6
6
  import org.apache.poi.ss.usermodel.Cell;
7
+ import org.apache.poi.ss.usermodel.CellType;
7
8
  import org.apache.poi.ss.usermodel.CellValue;
8
9
  import org.apache.poi.ss.usermodel.CreationHelper;
9
10
  import org.apache.poi.ss.usermodel.FormulaError;
@@ -12,11 +13,14 @@ import org.apache.poi.ss.usermodel.Row;
12
13
  import org.apache.poi.ss.usermodel.Sheet;
13
14
  import org.apache.poi.ss.usermodel.Workbook;
14
15
  import org.apache.poi.ss.util.CellRangeAddress;
16
+ import org.apache.poi.ss.util.CellReference;
15
17
  import org.embulk.parser.poi_excel.PoiExcelColumnValueType;
16
18
  import org.embulk.parser.poi_excel.PoiExcelParserPlugin.FormulaReplaceTask;
17
19
  import org.embulk.parser.poi_excel.bean.PoiExcelColumnBean;
18
20
  import org.embulk.parser.poi_excel.bean.PoiExcelColumnBean.ErrorStrategy;
21
+ import org.embulk.parser.poi_excel.bean.PoiExcelColumnBean.FormulaHandling;
19
22
  import org.embulk.parser.poi_excel.visitor.embulk.CellVisitor;
23
+ import org.embulk.parser.poi_excel.visitor.util.MergedRegionFinder;
20
24
  import org.embulk.spi.Column;
21
25
  import org.embulk.spi.Exec;
22
26
  import org.embulk.spi.PageBuilder;
@@ -38,15 +42,15 @@ public class PoiExcelCellValueVisitor {
38
42
 
39
43
  Column column = bean.getColumn();
40
44
 
41
- int cellType = cell.getCellType();
45
+ CellType cellType = cell.getCellTypeEnum();
42
46
  switch (cellType) {
43
- case Cell.CELL_TYPE_NUMERIC:
47
+ case NUMERIC:
44
48
  visitor.visitCellValueNumeric(column, cell, cell.getNumericCellValue());
45
49
  return;
46
- case Cell.CELL_TYPE_STRING:
50
+ case STRING:
47
51
  visitor.visitCellValueString(column, cell, cell.getStringCellValue());
48
52
  return;
49
- case Cell.CELL_TYPE_FORMULA:
53
+ case FORMULA:
50
54
  PoiExcelColumnValueType valueType = bean.getValueType();
51
55
  if (valueType == PoiExcelColumnValueType.CELL_FORMULA) {
52
56
  visitor.visitCellFormula(column, cell);
@@ -54,13 +58,13 @@ public class PoiExcelCellValueVisitor {
54
58
  visitCellValueFormula(bean, cell, visitor);
55
59
  }
56
60
  return;
57
- case Cell.CELL_TYPE_BLANK:
61
+ case BLANK:
58
62
  visitCellValueBlank(bean, cell, visitor);
59
63
  return;
60
- case Cell.CELL_TYPE_BOOLEAN:
64
+ case BOOLEAN:
61
65
  visitor.visitCellValueBoolean(column, cell, cell.getBooleanCellValue());
62
66
  return;
63
- case Cell.CELL_TYPE_ERROR:
67
+ case ERROR:
64
68
  visitCellValueError(bean, cell, cell.getErrorCellValue(), visitor);
65
69
  return;
66
70
  default:
@@ -69,35 +73,24 @@ public class PoiExcelCellValueVisitor {
69
73
  }
70
74
 
71
75
  protected void visitCellValueBlank(PoiExcelColumnBean bean, Cell cell, CellVisitor visitor) {
72
- assert cell.getCellType() == Cell.CELL_TYPE_BLANK;
76
+ assert cell.getCellTypeEnum() == CellType.BLANK;
73
77
 
74
78
  Column column = bean.getColumn();
75
79
 
76
- boolean search = bean.getSearchMergedCell();
77
- if (!search) {
78
- visitor.visitCellValueBlank(column, cell);
79
- return;
80
- }
81
-
82
- int r = cell.getRowIndex();
83
- int c = cell.getColumnIndex();
84
-
85
- Sheet sheet = cell.getSheet();
86
- int size = sheet.getNumMergedRegions();
87
- for (int i = 0; i < size; i++) {
88
- CellRangeAddress range = visitorValue.getSheet().getMergedRegion(i);
89
- if (range.isInRange(r, c)) {
90
- Row firstRow = sheet.getRow(range.getFirstRow());
91
- if (firstRow == null) {
92
- visitCellNull(column);
93
- return;
94
- }
95
- Cell firstCell = firstRow.getCell(range.getFirstColumn());
96
- if (firstCell == null) {
97
- visitCellNull(column);
98
- return;
99
- }
80
+ CellRangeAddress region = findRegion(bean, cell);
81
+ if (region != null) {
82
+ Row firstRow = cell.getSheet().getRow(region.getFirstRow());
83
+ if (firstRow == null) {
84
+ visitCellNull(column);
85
+ return;
86
+ }
87
+ Cell firstCell = firstRow.getCell(region.getFirstColumn());
88
+ if (firstCell == null) {
89
+ visitCellNull(column);
90
+ return;
91
+ }
100
92
 
93
+ if (firstCell.getRowIndex() != cell.getRowIndex() || firstCell.getColumnIndex() != cell.getColumnIndex()) {
101
94
  visitCellValue(bean, firstCell, visitor);
102
95
  return;
103
96
  }
@@ -106,9 +99,56 @@ public class PoiExcelCellValueVisitor {
106
99
  visitor.visitCellValueBlank(column, cell);
107
100
  }
108
101
 
102
+ protected CellRangeAddress findRegion(PoiExcelColumnBean bean, Cell cell) {
103
+ Sheet sheet = cell.getSheet();
104
+ int r = cell.getRowIndex();
105
+ int c = cell.getColumnIndex();
106
+
107
+ MergedRegionFinder finder = bean.getMergedRegionFinder();
108
+ return finder.get(sheet, r, c);
109
+ }
110
+
109
111
  protected void visitCellValueFormula(PoiExcelColumnBean bean, Cell cell, CellVisitor visitor) {
110
- assert cell.getCellType() == Cell.CELL_TYPE_FORMULA;
112
+ assert cell.getCellTypeEnum() == CellType.FORMULA;
111
113
 
114
+ FormulaHandling handling = bean.getFormulaHandling();
115
+ switch (handling) {
116
+ case CASHED_VALUE:
117
+ visitCellValueFormulaCashedValue(bean, cell, visitor);
118
+ break;
119
+ default:
120
+ visitCellValueFormulaEvaluate(bean, cell, visitor);
121
+ break;
122
+ }
123
+ }
124
+
125
+ protected void visitCellValueFormulaCashedValue(PoiExcelColumnBean bean, Cell cell, CellVisitor visitor) {
126
+ Column column = bean.getColumn();
127
+
128
+ CellType cellType = cell.getCachedFormulaResultTypeEnum();
129
+ switch (cellType) {
130
+ case NUMERIC:
131
+ visitor.visitCellValueNumeric(column, cell, cell.getNumericCellValue());
132
+ return;
133
+ case STRING:
134
+ visitor.visitCellValueString(column, cell, cell.getStringCellValue());
135
+ return;
136
+ case BLANK:
137
+ visitCellValueBlank(bean, cell, visitor);
138
+ return;
139
+ case BOOLEAN:
140
+ visitor.visitCellValueBoolean(column, cell, cell.getBooleanCellValue());
141
+ return;
142
+ case ERROR:
143
+ visitCellValueError(bean, cell, cell.getErrorCellValue(), visitor);
144
+ return;
145
+ case FORMULA:
146
+ default:
147
+ throw new IllegalStateException(MessageFormat.format("unsupported POI cellType={0}", cellType));
148
+ }
149
+ }
150
+
151
+ protected void visitCellValueFormulaEvaluate(PoiExcelColumnBean bean, Cell cell, CellVisitor visitor) {
112
152
  Column column = bean.getColumn();
113
153
 
114
154
  List<FormulaReplaceTask> list = bean.getFormulaReplace();
@@ -120,7 +160,13 @@ public class PoiExcelCellValueVisitor {
120
160
  String regex = replace.getRegex();
121
161
  String replacement = replace.getTo();
122
162
 
123
- replacement = replacement.replace("${row}", Integer.toString(cell.getRowIndex() + 1));
163
+ if (replacement.contains("${row}")) {
164
+ replacement = replacement.replace("${row}", Integer.toString(cell.getRowIndex() + 1));
165
+ }
166
+ if (replacement.contains("${column}")) {
167
+ replacement = replacement.replace("${column}",
168
+ CellReference.convertNumToColString(cell.getColumnIndex() + 1));
169
+ }
124
170
 
125
171
  formula = formula.replaceAll(regex, replacement);
126
172
  }
@@ -159,24 +205,24 @@ public class PoiExcelCellValueVisitor {
159
205
  throw new RuntimeException(MessageFormat.format("evaluate error. formula={0}", cell.getCellFormula()), e);
160
206
  }
161
207
 
162
- int cellType = cellValue.getCellType();
208
+ CellType cellType = cellValue.getCellTypeEnum();
163
209
  switch (cellType) {
164
- case Cell.CELL_TYPE_NUMERIC:
210
+ case NUMERIC:
165
211
  visitor.visitCellValueNumeric(column, cellValue, cellValue.getNumberValue());
166
212
  return;
167
- case Cell.CELL_TYPE_STRING:
213
+ case STRING:
168
214
  visitor.visitCellValueString(column, cellValue, cellValue.getStringValue());
169
215
  return;
170
- case Cell.CELL_TYPE_BLANK:
216
+ case BLANK:
171
217
  visitor.visitCellValueBlank(column, cellValue);
172
218
  return;
173
- case Cell.CELL_TYPE_BOOLEAN:
219
+ case BOOLEAN:
174
220
  visitor.visitCellValueBoolean(column, cellValue, cellValue.getBooleanValue());
175
221
  return;
176
- case Cell.CELL_TYPE_ERROR:
222
+ case ERROR:
177
223
  visitCellValueError(bean, cellValue, cellValue.getErrorValue(), visitor);
178
224
  return;
179
- case Cell.CELL_TYPE_FORMULA:
225
+ case FORMULA:
180
226
  default:
181
227
  throw new IllegalStateException(MessageFormat.format("unsupported POI cellType={0}", cellType));
182
228
  }
@@ -40,7 +40,7 @@ public class PoiExcelClientAnchorVisitor extends AbstractPoiExcelCellAttributeVi
40
40
  map.put("anchor_type", new AttributeSupplier<ClientAnchor>() {
41
41
  @Override
42
42
  public Object get(Column column, Cell cell, ClientAnchor anchor) {
43
- return (long) anchor.getAnchorType();
43
+ return (long) anchor.getAnchorType().value;
44
44
  }
45
45
  });
46
46
  map.put("col1", new AttributeSupplier<ClientAnchor>() {
@@ -3,22 +3,27 @@ package org.embulk.parser.poi_excel.visitor;
3
3
  import java.text.MessageFormat;
4
4
 
5
5
  import org.apache.poi.ss.usermodel.Cell;
6
- import org.apache.poi.ss.usermodel.Row;
7
- import org.apache.poi.ss.util.CellReference;
6
+ import org.apache.poi.ss.usermodel.CellType;
7
+ import org.apache.poi.ss.usermodel.Sheet;
8
8
  import org.embulk.parser.poi_excel.PoiExcelColumnValueType;
9
9
  import org.embulk.parser.poi_excel.bean.PoiExcelColumnBean;
10
+ import org.embulk.parser.poi_excel.bean.record.PoiExcelRecord;
11
+ import org.embulk.parser.poi_excel.bean.util.PoiExcelCellAddress;
10
12
  import org.embulk.parser.poi_excel.visitor.embulk.CellVisitor;
11
13
  import org.embulk.spi.Column;
12
14
  import org.embulk.spi.ColumnVisitor;
15
+ import org.embulk.spi.Exec;
13
16
  import org.embulk.spi.PageBuilder;
17
+ import org.slf4j.Logger;
14
18
 
15
19
  public class PoiExcelColumnVisitor implements ColumnVisitor {
20
+ private final Logger log = Exec.getLogger(getClass());
16
21
 
17
22
  protected final PoiExcelVisitorValue visitorValue;
18
23
  protected final PageBuilder pageBuilder;
19
24
  protected final PoiExcelVisitorFactory factory;
20
25
 
21
- protected Row currentRow;
26
+ protected PoiExcelRecord record;
22
27
 
23
28
  public PoiExcelColumnVisitor(PoiExcelVisitorValue visitorValue) {
24
29
  this.visitorValue = visitorValue;
@@ -26,8 +31,8 @@ public class PoiExcelColumnVisitor implements ColumnVisitor {
26
31
  this.factory = visitorValue.getVisitorFactory();
27
32
  }
28
33
 
29
- public void setRow(Row row) {
30
- this.currentRow = row;
34
+ public void setRecord(PoiExcelRecord record) {
35
+ this.record = record;
31
36
  }
32
37
 
33
38
  @Override
@@ -56,30 +61,53 @@ public class PoiExcelColumnVisitor implements ColumnVisitor {
56
61
  }
57
62
 
58
63
  protected final void visitCell0(Column column, CellVisitor visitor) {
64
+ if (log.isTraceEnabled()) {
65
+ log.trace("{} start", column);
66
+ }
59
67
  try {
60
68
  visitCell(column, visitor);
61
69
  } catch (Exception e) {
62
70
  String sheetName = visitorValue.getSheet().getSheetName();
63
- String ref = new CellReference(currentRow.getRowNum(), visitorValue.getColumnBean(column).getColumnIndex())
64
- .formatAsString();
71
+ String ref = record.getCellReference(visitorValue.getColumnBean(column)).formatAsString();
65
72
  throw new RuntimeException(MessageFormat.format("error at {0} cell={1}!{2}. {3}", column, sheetName, ref,
66
73
  e.getMessage()), e);
67
74
  }
75
+ if (log.isTraceEnabled()) {
76
+ log.trace("{} end", column);
77
+ }
68
78
  }
69
79
 
70
80
  protected void visitCell(Column column, CellVisitor visitor) {
71
81
  PoiExcelColumnBean bean = visitorValue.getColumnBean(column);
72
82
  PoiExcelColumnValueType valueType = bean.getValueType();
83
+ PoiExcelCellAddress cellAddress = bean.getCellAddress();
73
84
 
74
85
  switch (valueType) {
75
86
  case SHEET_NAME:
76
- visitor.visitSheetName(column);
87
+ if (cellAddress != null) {
88
+ Sheet sheet = cellAddress.getSheet(record);
89
+ visitor.visitSheetName(column, sheet);
90
+ } else {
91
+ visitor.visitSheetName(column);
92
+ }
77
93
  return;
78
94
  case ROW_NUMBER:
79
- visitor.visitRowNumber(column, currentRow.getRowNum() + 1);
95
+ int rowIndex;
96
+ if (cellAddress != null) {
97
+ rowIndex = cellAddress.getRowIndex();
98
+ } else {
99
+ rowIndex = record.getRowIndex(bean);
100
+ }
101
+ visitor.visitRowNumber(column, rowIndex + 1);
80
102
  return;
81
103
  case COLUMN_NUMBER:
82
- visitor.visitColumnNumber(column, bean.getColumnIndex() + 1);
104
+ int columnIndex;
105
+ if (cellAddress != null) {
106
+ columnIndex = cellAddress.getColumnIndex();
107
+ } else {
108
+ columnIndex = record.getColumnIndex(bean);
109
+ }
110
+ visitor.visitColumnNumber(column, columnIndex + 1);
83
111
  return;
84
112
  case CONSTANT:
85
113
  visitCellConstant(column, bean.getValueTypeSuffix(), visitor);
@@ -88,8 +116,13 @@ public class PoiExcelColumnVisitor implements ColumnVisitor {
88
116
  break;
89
117
  }
90
118
 
91
- assert valueType.useCell();
92
- Cell cell = currentRow.getCell(bean.getColumnIndex());
119
+ // assert valueType.useCell();
120
+ Cell cell;
121
+ if (cellAddress != null) {
122
+ cell = cellAddress.getCell(record);
123
+ } else {
124
+ cell = record.getCell(bean);
125
+ }
93
126
  if (cell == null) {
94
127
  visitCellNull(column);
95
128
  return;
@@ -108,6 +141,16 @@ public class PoiExcelColumnVisitor implements ColumnVisitor {
108
141
  case CELL_COMMENT:
109
142
  visitCellComment(bean, cell, visitor);
110
143
  return;
144
+ case CELL_TYPE:
145
+ visitCellType(bean, cell, cell.getCellTypeEnum(), visitor);
146
+ return;
147
+ case CELL_CACHED_TYPE:
148
+ if (cell.getCellTypeEnum() == CellType.FORMULA) {
149
+ visitCellType(bean, cell, cell.getCachedFormulaResultTypeEnum(), visitor);
150
+ } else {
151
+ visitCellType(bean, cell, cell.getCellTypeEnum(), visitor);
152
+ }
153
+ return;
111
154
  default:
112
155
  throw new UnsupportedOperationException(MessageFormat.format("unsupported value_type={0}", valueType));
113
156
  }
@@ -144,4 +187,9 @@ public class PoiExcelColumnVisitor implements ColumnVisitor {
144
187
  PoiExcelCellCommentVisitor delegator = factory.getPoiExcelCellCommentVisitor();
145
188
  delegator.visit(bean, cell, visitor);
146
189
  }
190
+
191
+ private void visitCellType(PoiExcelColumnBean bean, Cell cell, CellType cellType, CellVisitor visitor) {
192
+ PoiExcelCellTypeVisitor delegator = factory.getPoiExcelCellTypeVisitor();
193
+ delegator.visit(bean, cell, cellType, visitor);
194
+ }
147
195
  }