From: Marko Luukkainen Date: Thu, 2 Feb 2017 13:06:06 +0000 (+0200) Subject: Excel parsing interface X-Git-Tag: v1.31.0~38 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=7abd05645636ea510269d77005717f43c2c445ba;hp=f11cbe76b3f4be142c9f84ef9a7b6bc9dcc8ff23;p=simantics%2Finterop.git Excel parsing interface refs #7012 Change-Id: I49f4880147ccdd0f6b9eab4294c41f2335df6761 --- diff --git a/org.simantics.excel.poi/.classpath b/org.simantics.excel.poi/.classpath new file mode 100644 index 0000000..b862a29 --- /dev/null +++ b/org.simantics.excel.poi/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.simantics.excel.poi/.gitignore b/org.simantics.excel.poi/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/org.simantics.excel.poi/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/org.simantics.excel.poi/.project b/org.simantics.excel.poi/.project new file mode 100644 index 0000000..33943a7 --- /dev/null +++ b/org.simantics.excel.poi/.project @@ -0,0 +1,28 @@ + + + org.simantics.excel.poi + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.simantics.excel.poi/.settings/org.eclipse.jdt.core.prefs b/org.simantics.excel.poi/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..295926d --- /dev/null +++ b/org.simantics.excel.poi/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/org.simantics.excel.poi/META-INF/MANIFEST.MF b/org.simantics.excel.poi/META-INF/MANIFEST.MF new file mode 100644 index 0000000..4356d5c --- /dev/null +++ b/org.simantics.excel.poi/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Excel / Apache POI +Bundle-SymbolicName: org.simantics.excel.poi +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.excel.poi.Activator +Bundle-Vendor: VTT +Require-Bundle: org.eclipse.core.runtime, + org.apache.poi;bundle-version="3.15.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy +Export-Package: org.simantics.excel.poi.parser, + org.simantics.excel.poi.parser.streaming diff --git a/org.simantics.excel.poi/build.properties b/org.simantics.excel.poi/build.properties new file mode 100644 index 0000000..41eb6ad --- /dev/null +++ b/org.simantics.excel.poi/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/Activator.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/Activator.java new file mode 100644 index 0000000..68aaf2f --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/Activator.java @@ -0,0 +1,30 @@ +package org.simantics.excel.poi; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellBooleanDataResolver.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellBooleanDataResolver.java new file mode 100644 index 0000000..b2e12de --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellBooleanDataResolver.java @@ -0,0 +1,22 @@ +package org.simantics.excel.poi.parser; + +import org.apache.poi.ss.usermodel.Row; + +public class CellBooleanDataResolver extends CellDataResolverBase { + int column; + + public CellBooleanDataResolver(int column) { + super(); + this.column = column; + } + + @Override + public Boolean getValue(Row row) { + if (row == null) + return null; + return getCellBooleanValue(getCell(row, column)); + } + + + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellContentDataResolver.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellContentDataResolver.java new file mode 100644 index 0000000..e84c04d --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellContentDataResolver.java @@ -0,0 +1,61 @@ +package org.simantics.excel.poi.parser; + +import org.apache.poi.ss.usermodel.Row; + +public class CellContentDataResolver extends CellStringDataResolver { + int column; + int element; + String separator; + boolean cut = true; + + public CellContentDataResolver(int column, int element, String separator) { + super(column); + this.column = column; + this.element = element; + this.separator = separator; + } + + public CellContentDataResolver(int column, int element, String separator, boolean cut) { + super(column); + this.column = column; + this.element = element; + this.separator = separator; + this.cut = cut; + } + +// @Override +// public Double getDouble(Row row) { +// String s = getSubString(row); +// if (s != null) { +// return Double.parseDouble(s); +// } +// return null; +// } + + @Override + public String getValue(Row row) { + if (row == null) + return null; + return getSubString(row); + } + + protected String getSubString(Row row) { + String s = getCellStringValue(getCell(row, column)); + if (cut) { + String vals[] = s.split(separator); + if (vals.length > element) { + return vals[element]; + } + } else { + int index = -1; + for (int i = 0; i < element; i++) { + index = s.indexOf(separator,index+1); + if (index == -1) + return null; + } + return s.substring(index+1); + } + return null; + } +} + diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellDataResolverBase.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellDataResolverBase.java new file mode 100644 index 0000000..5a78735 --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellDataResolverBase.java @@ -0,0 +1,88 @@ +package org.simantics.excel.poi.parser; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; + +public abstract class CellDataResolverBase implements DataResolver { + + + protected Double getCellNumericValue(Cell cell) { + if (cell == null) + return null; + switch (cell.getCellType()) { + case Cell.CELL_TYPE_BLANK: + return null; + case Cell.CELL_TYPE_BOOLEAN: + return null; + case Cell.CELL_TYPE_ERROR: + return null; + case Cell.CELL_TYPE_FORMULA: + return null; + case Cell.CELL_TYPE_NUMERIC: + return cell.getNumericCellValue(); + case Cell.CELL_TYPE_STRING: + return null; + + } + throw new RuntimeException(); + } + + protected String getCellStringValue(Cell cell) { + if (cell == null) + return null; + switch (cell.getCellType()) { + case Cell.CELL_TYPE_BLANK: + return null; + case Cell.CELL_TYPE_BOOLEAN: + return Boolean.toString(cell.getBooleanCellValue()); + case Cell.CELL_TYPE_ERROR: + return null; + case Cell.CELL_TYPE_FORMULA: + return null; + case Cell.CELL_TYPE_NUMERIC: + return Double.toString(cell.getNumericCellValue()); + case Cell.CELL_TYPE_STRING: + return cell.getStringCellValue(); + + } + throw new RuntimeException(); + } + + protected Boolean getCellBooleanValue(Cell cell) { + if (cell == null) + return null; + switch (cell.getCellType()) { + case Cell.CELL_TYPE_BLANK: + return null; + case Cell.CELL_TYPE_BOOLEAN: + return cell.getBooleanCellValue(); + case Cell.CELL_TYPE_ERROR: + return null; + case Cell.CELL_TYPE_FORMULA: + return null; + case Cell.CELL_TYPE_NUMERIC: + return null; + case Cell.CELL_TYPE_STRING: + String value = cell.getStringCellValue(); + if ("true".equalsIgnoreCase(value)) + return true; + if ("1".equalsIgnoreCase(value)) + return true; + return false; + } + throw new RuntimeException(); + } + + protected Cell getCell(Row row, int colIndex) { + for (short i = row.getFirstCellNum(); i <= row.getLastCellNum(); i++) { + Cell c = row.getCell(i); + if (c == null) + continue; + if (c.getColumnIndex() == colIndex) + return c; + + } + return null; + } + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellDoubleDataResolver.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellDoubleDataResolver.java new file mode 100644 index 0000000..53bad3a --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellDoubleDataResolver.java @@ -0,0 +1,24 @@ +package org.simantics.excel.poi.parser; + +import org.apache.poi.ss.usermodel.Row; + +public class CellDoubleDataResolver extends CellDataResolverBase { + int column; + + public CellDoubleDataResolver(int column) { + super(); + this.column = column; + } + + @Override + public Double getValue(Row row) { + if (row == null) + return null; + try { + return getCellNumericValue(getCell(row, column)); + } catch (Exception e) { + return null; + } + } + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellStringArrayDataResolver.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellStringArrayDataResolver.java new file mode 100644 index 0000000..4d6ce43 --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellStringArrayDataResolver.java @@ -0,0 +1,59 @@ +package org.simantics.excel.poi.parser; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.ss.usermodel.Row; + +public class CellStringArrayDataResolver extends CellDataResolverBase{ + + int index[]; + boolean all = false; + + public CellStringArrayDataResolver(int... index) { + this.index = index; + } + + public CellStringArrayDataResolver(List index) { + this.index = new int[index.size()]; + for (int i = 0; i < index.size(); i++) { + this.index[i] = index.get(i); + } + } + + /** + * If resolver is parameterized with one index, return all values from all columns from the index. Default false. + * @param all + */ + public CellStringArrayDataResolver setAll(boolean all) { + this.all = all; + return this; + } + + @Override + public String[] getValue(Row row) { + if (row == null) + return null; + if (index.length > 1 || !all) { + String data[] = new String[index.length]; + for (int i = 0; i < data.length; i++) { + data[i] = getCellStringValue(getCell(row, index[i])); + } + return data; + } else { + List data = new ArrayList(); + int i = index[0]; + while (true) { + String value = getCellStringValue(getCell(row, i)); + if (value != null && value.length() > 0) { + data.add(value); + i++; + } else { + break; + } + } + return data.toArray(new String[data.size()]); + } + } + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellStringDataResolver.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellStringDataResolver.java new file mode 100644 index 0000000..4c0929e --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/CellStringDataResolver.java @@ -0,0 +1,22 @@ +package org.simantics.excel.poi.parser; + +import org.apache.poi.ss.usermodel.Row; + +public class CellStringDataResolver extends CellDataResolverBase { + int column; + + public CellStringDataResolver(int column) { + super(); + this.column = column; + } + + @Override + public String getValue(Row row) { + if (row == null) + return null; + return getCellStringValue(getCell(row, column)); + } + + + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/ColumnResolver.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/ColumnResolver.java new file mode 100644 index 0000000..1aaec80 --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/ColumnResolver.java @@ -0,0 +1,106 @@ +package org.simantics.excel.poi.parser; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; + +public class ColumnResolver { + + private enum Type {SINGLE,MULTI}; + + private Map values = new HashMap(); + private Map types = new HashMap(); + private Set optional = new HashSet(); + private Set resolved = new HashSet(); + + public void addSingleColumn(String id) { + addSingleColumn(id, true); + } + + public void addSingleColumn(String id, boolean required) { + types.put(id, Type.SINGLE); + if (!required) + this.optional.add(id); + } + + public void addMultiColumn(String id) { + addMultiColumn(id, true); + } + + public void addMultiColumn(String id, boolean required) { + types.put(id, Type.MULTI); + if (!required) + this.optional.add(id); + } + + + public int getSingleColumn(String id) { + int[] val = values.get(id); + if (val == null) + return -1; + if (val.length == 0) + return -1; + return val[0]; + } + + public int[] getMultiColumn(String id) { + return values.get(id); + } + + public boolean resolve(Row row) { + return resolve(row, true); + } + + public boolean resolve(Row row, boolean ignoreCase) { + values.clear(); + resolved.clear(); + if (row == null) { + return false; + } + + for (int i = 0; i <= row.getLastCellNum(); i++) { + Cell cell = row.getCell(i); + if (cell == null) + continue; + int colIndex = cell.getColumnIndex(); + String value = cell.getStringCellValue(); + for (Entry col : types.entrySet()) { + String id = col.getKey(); + if (id.equals(value) || ignoreCase && id.equalsIgnoreCase(value)) { + if (col.getValue() == Type.SINGLE) { + values.put(id, new int[]{colIndex}); + } else { + int curr[] = values.get(id); + if (curr == null) { + values.put(id, new int[]{colIndex}); + } else { + int n[] = new int[curr.length+1]; + System.arraycopy(curr, 0, n, 0, curr.length); + n[curr.length] = colIndex; + values.put(id, n); + } + + } + resolved.add(id); + break; + } + } + } + // check that required columns have been resolved + for (Entry col : types.entrySet()) { + if (!optional.contains(col.getKey())) { + if (!resolved.contains(col.getKey())) + return false; + } + } + return true; + + } + + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/DataResolver.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/DataResolver.java new file mode 100644 index 0000000..ad3a6b6 --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/DataResolver.java @@ -0,0 +1,7 @@ +package org.simantics.excel.poi.parser; + +import org.apache.poi.ss.usermodel.Row; + +public interface DataResolver { + public T getValue(Row row); +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/CellImpl.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/CellImpl.java new file mode 100644 index 0000000..c5ee733 --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/CellImpl.java @@ -0,0 +1,262 @@ +package org.simantics.excel.poi.parser.streaming; + +import java.util.Calendar; +import java.util.Date; + +import org.apache.poi.ss.formula.FormulaParseException; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Comment; +import org.apache.poi.ss.usermodel.ExcelStyleDateFormatter; +import org.apache.poi.ss.usermodel.Hyperlink; +import org.apache.poi.ss.usermodel.RichTextString; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellAddress; +import org.apache.poi.ss.util.CellRangeAddress; + +public class CellImpl implements Cell{ + + private RowImpl row; + private int index; + + public CellImpl(RowImpl row, int index) { + this.row = row; + this.index = index; + } + + + private String getType() { + return row.cellTypes.get(index); + } + + @Override + public boolean getBooleanCellValue() { + return 1 == Integer.parseInt(getStringCellValue()); + } + + @Override + public Date getDateCellValue() { + ExcelStyleDateFormatter formatter = new ExcelStyleDateFormatter(""); //FIXME: date format + try { + return formatter.parse(getStringCellValue()); + } catch (Exception e) { + return null; + } + } + + @Override + public byte getErrorCellValue() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public double getNumericCellValue() { + return Double.parseDouble(getStringCellValue()); + } + + @Override + public RichTextString getRichStringCellValue() { + return null; + } + + @Override + public String getStringCellValue() { + return row.cellData.get(index); + } + + + @Override + public int getCellType() { + String type = getType(); + if ("v".equals(type)) { + return CELL_TYPE_NUMERIC; + } else if ("n".equals(type)) { + return CELL_TYPE_NUMERIC; + } else if ("s".equals(type)) { + return CELL_TYPE_STRING; + } else if ("b".equals(type)) { + return CELL_TYPE_STRING; + } else if ("inlineStr".equals(type)) { + return CELL_TYPE_STRING; + } + return CELL_TYPE_STRING; + } + + + + + @Override + public Row getRow() { + return row; + } + + @Override + public int getRowIndex() { + return row.getRowNum(); + } + + + @Override + public CellRangeAddress getArrayFormulaRange() { + return null; + } + + + @Override + public int getCachedFormulaResultType() { + return 0; + } + + @Override + public Comment getCellComment() { + return null; + } + + @Override + public String getCellFormula() { + return null; + } + + @Override + public CellStyle getCellStyle() { + return null; + } + + @Override + public int getColumnIndex() { + return index; + } + + @Override + public Hyperlink getHyperlink() { + return null; + } + + + @Override + public Sheet getSheet() { + return row.getSheet(); + } + + @Override + public boolean isPartOfArrayFormulaGroup() { + return false; + } + + @Override + public void removeCellComment() { + + } + + @Override + public void setAsActiveCell() { + + } + + @Override + public void setCellComment(Comment comment) { + + } + + @Override + public void setCellErrorValue(byte value) { + + } + + @Override + public void setCellFormula(String formula) throws FormulaParseException { + + } + + @Override + public void setCellStyle(CellStyle style) { + + } + + @Override + public void setCellType(int cellType) { + + } + + @Override + public void setCellValue(boolean value) { + + } + + @Override + public void setCellValue(Calendar value) { + + } + + @Override + public void setCellValue(Date value) { + + } + + @Override + public void setCellValue(double value) { + + } + + @Override + public void setCellValue(RichTextString value) { + + } + + @Override + public void setCellValue(String value) { + + } + + @Override + public void setHyperlink(Hyperlink link) { + + } + + + @Override + public CellAddress getAddress() { + return new CellAddress(this); + } + + + @Override + public CellType getCachedFormulaResultTypeEnum() { + throw new UnsupportedOperationException(); + } + + + @Override + public CellType getCellTypeEnum() { + String type = getType(); + if ("v".equals(type)) { + return CellType.NUMERIC; + } else if ("n".equals(type)) { + return CellType.NUMERIC; + } else if ("s".equals(type)) { + return CellType.STRING; + } else if ("b".equals(type)) { + return CellType.STRING; + } else if ("inlineStr".equals(type)) { + return CellType.STRING; + } + return CellType.STRING; + } + + @Override + public void setCellType(CellType arg0) { + throw new UnsupportedOperationException(); + } + + + + @Override + public void removeHyperlink() { + throw new UnsupportedOperationException(); + } + + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/RowImpl.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/RowImpl.java new file mode 100644 index 0000000..1ca2eb3 --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/RowImpl.java @@ -0,0 +1,166 @@ +package org.simantics.excel.poi.parser.streaming; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; + +public class RowImpl implements Row { + SheetImpl sheetImpl; + + List cellData; + List cellTypes; + List cells; + + int index; + + public RowImpl(SheetImpl sheetImpl, List cellData, List cellTypes, int index) { + this.sheetImpl = sheetImpl; + this.cellData = cellData; + this.cellTypes = cellTypes; + this.cells = new ArrayList(cellData.size()); + for (int i = 0; i < cellData.size(); i++) { + cells.add(new CellImpl(this, i)); + } + this.index = index; + } + + @Override + public Iterator cellIterator() { + return cells.iterator(); + } + + @Override + public Cell createCell(int column) { + return null; + } + + @Override + public Cell createCell(int column, int type) { + return null; + } + + @Override + public Cell getCell(int cellnum) { + return cells.get(cellnum); + } + + @Override + public Cell getCell(int cellnum, MissingCellPolicy policy) { + return cells.get(cellnum); + } + + @Override + public short getFirstCellNum() { + return 0; + } + + @Override + public short getLastCellNum() { + return (short)(cells.size()-1); + } + + + @Override + public short getHeight() { + return 0; + } + + @Override + public float getHeightInPoints() { + return 0; + } + + + @Override + public int getPhysicalNumberOfCells() { + return cells.size(); + } + + @Override + public int getRowNum() { + return index; + } + + @Override + public CellStyle getRowStyle() { + return null; + } + + @Override + public Sheet getSheet() { + return sheetImpl; + } + + @Override + public boolean getZeroHeight() { + return false; + } + + @Override + public boolean isFormatted() { + return false; + } + + @Override + public Iterator iterator() { + return cells.iterator(); + } + + @Override + public void removeCell(Cell cell) { + + } + + @Override + public void setHeight(short height) { + + } + + @Override + public void setHeightInPoints(float height) { + + } + + @Override + public void setRowNum(int rowNum) { + + } + + @Override + public void setRowStyle(CellStyle style) { + + } + + @Override + public void setZeroHeight(boolean zHeight) { + + } + + @Override + public int getOutlineLevel() { + return 0; + } + + @Override + public Cell createCell(int arg0, CellType arg1) { + throw new UnsupportedOperationException(); + } + + + + @Override + public String toString() { + String s = ""; + for (int i = 0; i < cellData.size(); i++) { + s += cellTypes.get(i)+":" + cellData.get(i) + "; "; + } + return s; + } + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/SheetImpl.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/SheetImpl.java new file mode 100644 index 0000000..f45fd21 --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/SheetImpl.java @@ -0,0 +1,675 @@ +package org.simantics.excel.poi.parser.streaming; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.poi.hssf.util.PaneInformation; +import org.apache.poi.ss.usermodel.AutoFilter; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellRange; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Comment; +import org.apache.poi.ss.usermodel.DataValidation; +import org.apache.poi.ss.usermodel.DataValidationHelper; +import org.apache.poi.ss.usermodel.Drawing; +import org.apache.poi.ss.usermodel.Footer; +import org.apache.poi.ss.usermodel.Header; +import org.apache.poi.ss.usermodel.Hyperlink; +import org.apache.poi.ss.usermodel.PrintSetup; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.SheetConditionalFormatting; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.util.CellAddress; +import org.apache.poi.ss.util.CellRangeAddress; + +public class SheetImpl implements Sheet{ + + private String name; + private int index; + private String id; + + public SheetImpl(String name, int index, String id) { + this.name = name; + this.index = index; + this.id = id; + } + + public int getIndex() { + return index; + } + + public String getId() { + return id; + } + + @Override + public int getFirstRowNum() { + return 0; + } + + @Override + public int getLastRowNum() { + return 0; + } + + @Override + public Row getRow(int rownum) { + return null; + } + + @Override + public int getPhysicalNumberOfRows() { + return 0; + } + + @Override + public Workbook getWorkbook() { + return null; + } + + @Override + public String getSheetName() { + return name; + } + + + + @Override + public int addMergedRegion(CellRangeAddress region) { + return 0; + } + + @Override + public void addValidationData(DataValidation dataValidation) { + + } + + public void autoSizeColumn(int column) {}; + + @Override + public void autoSizeColumn(int column, boolean useMergedCells) { + + } + + public org.apache.poi.ss.usermodel.Drawing createDrawingPatriarch() { + return null; + }; + + @Override + public void createFreezePane(int colSplit, int rowSplit) { + + } + + @Override + public void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) { + + } + + @Override + public Row createRow(int rownum) { + return null; + } + + @Override + public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) { + + } + + @Override + public boolean getAutobreaks() { + return false; + } + + @Override + public Comment getCellComment(int row, int column) { + return null; + } + + public int[] getColumnBreaks() { + return null; + }; + + @Override + public CellStyle getColumnStyle(int column) { + return null; + } + + @Override + public int getColumnWidth(int columnIndex) { + return 0; + } + + @Override + public DataValidationHelper getDataValidationHelper() { + return null; + } + + public int getDefaultColumnWidth() { + return 0; + } + + @Override + public Iterator iterator() { + return null; + } + + @Override + public void removeRow(Row row) { + + } + + + + + + @Override + public void setColumnHidden(int columnIndex, boolean hidden) { + + } + + @Override + public boolean isColumnHidden(int columnIndex) { + return false; + } + + @Override + public void setRightToLeft(boolean value) { + + } + + @Override + public boolean isRightToLeft() { + return false; + } + + @Override + public void setColumnWidth(int columnIndex, int width) { + + } + + @Override + public void setDefaultColumnWidth(int width) { + + } + + @Override + public short getDefaultRowHeight() { + return 0; + } + + @Override + public float getDefaultRowHeightInPoints() { + return 0; + } + + @Override + public void setDefaultRowHeight(short height) { + + } + + @Override + public void setDefaultRowHeightInPoints(float height) { + + } + + @Override + public void setVerticallyCenter(boolean value) { + + } + + @Override + public void setHorizontallyCenter(boolean value) { + + } + + @Override + public boolean getHorizontallyCenter() { + return false; + } + + @Override + public boolean getVerticallyCenter() { + return false; + } + + @Override + public void removeMergedRegion(int index) { + + } + + @Override + public int getNumMergedRegions() { + return 0; + } + + @Override + public CellRangeAddress getMergedRegion(int index) { + return null; + } + + @Override + public Iterator rowIterator() { + return null; + } + + @Override + public void setForceFormulaRecalculation(boolean value) { + + } + + @Override + public boolean getForceFormulaRecalculation() { + return false; + } + + @Override + public void setAutobreaks(boolean value) { + + } + + @Override + public void setDisplayGuts(boolean value) { + + } + + @Override + public void setDisplayZeros(boolean value) { + + } + + @Override + public boolean isDisplayZeros() { + return false; + } + + @Override + public void setFitToPage(boolean value) { + + } + + @Override + public void setRowSumsBelow(boolean value) { + + } + + @Override + public void setRowSumsRight(boolean value) { + + } + + @Override + public boolean getDisplayGuts() { + return false; + } + + @Override + public boolean getFitToPage() { + return false; + } + + @Override + public boolean getRowSumsBelow() { + return false; + } + + @Override + public boolean getRowSumsRight() { + return false; + } + + @Override + public boolean isPrintGridlines() { + return false; + } + + @Override + public void setPrintGridlines(boolean show) { + + } + + @Override + public PrintSetup getPrintSetup() { + return null; + } + + @Override + public Header getHeader() { + return null; + } + + @Override + public Footer getFooter() { + return null; + } + + @Override + public void setSelected(boolean value) { + + } + + @Override + public double getMargin(short margin) { + return 0; + } + + @Override + public void setMargin(short margin, double size) { + + } + + @Override + public boolean getProtect() { + return false; + } + + @Override + public void protectSheet(String password) { + + } + + @Override + public boolean getScenarioProtect() { + return false; + } + + @Override + public void setZoom(int numerator, int denominator) { + + } + + @Override + public short getTopRow() { + return 0; + } + + @Override + public short getLeftCol() { + return 0; + } + + @Override + public void showInPane(int toprow, int leftcol) { + + } + +// @Override +// public void showInPane(short toprow, short leftcol) { +// +// } + + @Override + public void shiftRows(int startRow, int endRow, int n) { + + } + + @Override + public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) { + + } + + @Override + public PaneInformation getPaneInformation() { + return null; + } + + @Override + public void setDisplayGridlines(boolean show) { + + } + + @Override + public boolean isDisplayGridlines() { + return false; + } + + @Override + public void setDisplayFormulas(boolean show) { + + } + + @Override + public boolean isDisplayFormulas() { + return false; + } + + @Override + public void setDisplayRowColHeadings(boolean show) { + + } + + @Override + public boolean isDisplayRowColHeadings() { + return false; + } + + @Override + public void setRowBreak(int row) { + + } + + @Override + public boolean isRowBroken(int row) { + return false; + } + + @Override + public void removeRowBreak(int row) { + + } + + @Override + public int[] getRowBreaks() { + return null; + } + + @Override + public void setColumnBreak(int column) { + + } + + @Override + public boolean isColumnBroken(int column) { + return false; + } + + @Override + public void removeColumnBreak(int column) { + } + + @Override + public void setColumnGroupCollapsed(int columnNumber, boolean collapsed) { + + } + + @Override + public void groupColumn(int fromColumn, int toColumn) { + + } + + @Override + public void ungroupColumn(int fromColumn, int toColumn) { + + } + + @Override + public void groupRow(int fromRow, int toRow) { + + } + + @Override + public void ungroupRow(int fromRow, int toRow) { + + } + + @Override + public void setRowGroupCollapsed(int row, boolean collapse) { + + } + + @Override + public void setDefaultColumnStyle(int column, CellStyle style) { + + } + + + + @Override + public boolean isSelected() { + return false; + } + + @Override + public CellRange setArrayFormula(String formula, CellRangeAddress range) { + return null; + } + + @Override + public CellRange removeArrayFormula(Cell cell) { + return null; + } + + @Override + public AutoFilter setAutoFilter(CellRangeAddress range) { + return null; + } + + @Override + public SheetConditionalFormatting getSheetConditionalFormatting() { + return null; + } + + @Override + public CellRangeAddress getRepeatingRows() { + return null; + } + + @Override + public CellRangeAddress getRepeatingColumns() { + return null; + } + + @Override + public void setRepeatingRows(CellRangeAddress rowRangeRef) { + + } + + @Override + public void setRepeatingColumns(CellRangeAddress columnRangeRef) { + + } + + @Override + public int addMergedRegionUnsafe(CellRangeAddress arg0) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public CellAddress getActiveCell() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Comment getCellComment(CellAddress arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map getCellComments() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getColumnOutlineLevel(int arg0) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public float getColumnWidthInPixels(int arg0) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public List getDataValidations() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Drawing getDrawingPatriarch() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Hyperlink getHyperlink(CellAddress arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Hyperlink getHyperlink(int arg0, int arg1) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getHyperlinkList() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getMergedRegions() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isPrintRowAndColumnHeadings() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void removeMergedRegions(Collection arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void setActiveCell(CellAddress arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void setPrintRowAndColumnHeadings(boolean arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void setZoom(int arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void validateMergedRegions() { + // TODO Auto-generated method stub + + }; + + + + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/StreamingParser.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/StreamingParser.java new file mode 100644 index 0000000..add64d9 --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/StreamingParser.java @@ -0,0 +1,62 @@ +package org.simantics.excel.poi.parser.streaming; + +import java.io.File; +import java.io.InputStream; +import java.util.Iterator; + +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.xssf.eventusermodel.XSSFReader; +import org.apache.poi.xssf.model.SharedStringsTable; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +public class StreamingParser { + + + public void process(Row row) { + + } + + public void processAllSheets(File file) throws Exception { + OPCPackage pkg = OPCPackage.open(file); + XSSFReader r = new XSSFReader( pkg ); + SharedStringsTable sst = r.getSharedStringsTable(); + + XSSWorkbookHandler workbookHandler = new XSSWorkbookHandler(); + XMLReader parser = fetchParser(workbookHandler); + InputStream wb = r.getWorkbookData(); + InputSource wbSource = new InputSource(wb); + parser.parse(wbSource); + wb.close(); + + + Iterator sheets = r.getSheetsData(); + XSSSheetHandler sheetHandler = new XSSSheetHandler(sst) { + @Override + public void writeRow(Row row) { + process(row); + } + }; + parser = fetchParser(sheetHandler); + int sheetIndex = 0; + while(sheets.hasNext()) { + sheetHandler.setSheet(workbookHandler.getSheets().get(sheetIndex)); + InputStream sheet = sheets.next(); + InputSource sheetSource = new InputSource(sheet); + parser.parse(sheetSource); + sheet.close(); + sheetIndex++; + } + } + + public XMLReader fetchParser(ContentHandler handler) throws SAXException { + XMLReader parser = XMLReaderFactory.createXMLReader(); + parser.setContentHandler(handler); + return parser; + } + +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/XSSSheetHandler.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/XSSSheetHandler.java new file mode 100644 index 0000000..5df804a --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/XSSSheetHandler.java @@ -0,0 +1,120 @@ +package org.simantics.excel.poi.parser.streaming; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.xssf.model.SharedStringsTable; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +public class XSSSheetHandler extends DefaultHandler { + private SharedStringsTable sst; + private String lastContents; + private boolean nextIsString; + + int rowIndex = 0; + List row = new ArrayList(); + List rowTypes = new ArrayList(); + + String cellType; + String cellId; + + SheetImpl sheet; + + public XSSSheetHandler(SharedStringsTable sst) { + this.sst = sst; + } + + public void setSheet(SheetImpl sheet) { + this.sheet = sheet; + } + + public void writeRow(Row row) { + System.out.println(row); + } + + public void startElement(String uri, String localName, String name, + Attributes attributes) throws SAXException { + // c => cell +// System.out.println(name); +// for (int i = 0; i < attributes.getLength(); i++) { +// System.out.println(" " + attributes.getLocalName(i) + "; "+attributes.getValue(i) + "; " + attributes.getType(i) ); +// +// } + if(name.equals("c")) { + // Figure out if the value is an index in the SST + cellType = attributes.getValue("t"); + cellId = attributes.getValue("r"); + if(cellType != null) { + if (cellType.equals("s")) + nextIsString = true; + else + nextIsString = false; + } else { + nextIsString = false; + cellType = "v"; + } + } + // Clear contents cache + lastContents = ""; + } + + public void endElement(String uri, String localName, String name) + throws SAXException { + // Process the last contents as required. + // Do now, as characters() may be called more than once + if(nextIsString) { + int idx = Integer.parseInt(lastContents); + lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString(); + nextIsString = false; + } + + // v => contents of a cell + // Output after we've seen the string contents + if(name.equals("c")) { + int colIndex = getColIndex(cellId); + for (int i = row.size(); i< colIndex; i++) { + row.add(null); + rowTypes.add("s"); + } + row.add(lastContents); + rowTypes.add(cellType); + //System.out.println(lastContents); + lastContents = ""; + } else if (name.equals("row")) { + writeRow( new RowImpl(sheet, row, rowTypes,rowIndex)); + rowIndex++; + row.clear(); + rowTypes.clear(); + } + } + + public void characters(char[] ch, int start, int length) + throws SAXException { + lastContents += new String(ch, start, length); +// System.out.println("char : " + lastContents); + } + + private int getColIndex(String id) { + int len = 0; + int range = 'Z'-'A'+1; + for (int i = 0; i < id.length(); i++) { + char c = id.charAt(i) ; + if ('A' <= c && c <= 'Z') { + len = i+1; + } else { + break; + } + } + int index = 0; + for (int i = 0; i < len; i++) { + char c = id.charAt(len-i-1); + index += (c-'A') + i * range; + } + return index; + + } +} diff --git a/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/XSSWorkbookHandler.java b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/XSSWorkbookHandler.java new file mode 100644 index 0000000..af59d37 --- /dev/null +++ b/org.simantics.excel.poi/src/org/simantics/excel/poi/parser/streaming/XSSWorkbookHandler.java @@ -0,0 +1,47 @@ +package org.simantics.excel.poi.parser.streaming; + +import java.util.ArrayList; +import java.util.List; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +public class XSSWorkbookHandler extends DefaultHandler { + + + + List sheets = new ArrayList(); + + + public List getSheets() { + return sheets; + } + + public void startElement(String uri, String localName, String name, + Attributes attributes) throws SAXException { +// System.out.println(name); +// for (int i = 0; i < attributes.getLength(); i++) { +// System.out.println(" " + attributes.getLocalName(i) + "; "+attributes.getValue(i) + "; " + attributes.getType(i) ); +// +// } + if(name.equals("sheet")) { + String sheetName = attributes.getValue("name"); + String sheetId = attributes.getValue("sheetId"); + String id = attributes.getValue("id"); + sheets.add(new SheetImpl(sheetName, Integer.parseInt(sheetId), id)); + } + + } + + public void endElement(String uri, String localName, String name) + throws SAXException { + + } + + public void characters(char[] ch, int start, int length) + throws SAXException { + + } + +}