iterator() {
+ return workbook.first().iterator();
}
/**
- * Which sheet to open. There can only be one sheet open
- * for a single instance of {@code StreamingReader}. If
- * more sheets need to be read, a new instance must be
+ * Closes the streaming resource, attempting to clean up any temporary files
* created.
- *
- * Defaults to 0
- *
*
- * @param sheetIndex index of sheet
- * @return reference to current {@code Builder}
- * @deprecated This method will be removed in a future release. Use {@link StreamingWorkbook#getSheetAt(int)} instead.
+ * @throws com.monitorjbl.xlsx.exceptions.CloseException if there is an
+ * issue closing the stream
*/
- public Builder sheetIndex(int sheetIndex) {
- this.sheetIndex = sheetIndex;
- return this;
+ @Override
+ public void close() throws IOException {
+ try {
+ workbook.close();
+ } finally {
+ if (tmp != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Deleting tmp file [" + tmp.getAbsolutePath() + "]");
+ }
+ tmp.delete();
+ }
+ }
}
- /**
- * Which sheet to open. There can only be one sheet open
- * for a single instance of {@code StreamingReader}. If
- * more sheets need to be read, a new instance must be
- * created.
- *
- * @param sheetName name of sheet
- * @return reference to current {@code Builder}
- * @deprecated This method will be removed in a future release. Use {@link StreamingWorkbook#getSheet(String)} instead.
- */
- public Builder sheetName(String sheetName) {
- this.sheetName = sheetName;
- return this;
+ public static Builder builder() {
+ return new Builder();
}
- /**
- * For password protected files specify password to open file.
- * If the password is incorrect a {@code ReadException} is thrown on
- * {@code read}.
- * NULL indicates that no password should be used, this is the
- * default value.
- *
- * @param password to use when opening file
- * @return reference to current {@code Builder}
- */
- public Builder password(String password) {
- this.password = password;
- return this;
- }
+ public static class Builder {
- /**
- * !!! This option is experimental !!!
- *
- * Set the size of the Shared Strings Table cache. This option exists to accommodate
- * extremely large workbooks with millions of unique strings. Normally the SST is entirely
- * loaded into memory, but with large workbooks with high cardinality (i.e., very few
- * duplicate values) the SST may not fit entirely into memory.
- *
- * By default, the entire SST *will* be loaded into memory. Setting a value greater than
- * 0 for this option will only cache up to this many entries in memory. However,
- * enabling this option at all will have some noticeable performance degredation as you are
- * trading memory for disk space.
- *
- * @param sstCacheSizeBytes size of SST cache
- * @return reference to current {@code Builder}
- */
- public Builder sstCacheSizeBytes(int sstCacheSizeBytes) {
- this.sstCacheSizeBytes = sstCacheSizeBytes;
- return this;
- }
+ private int rowCacheSize = 10;
+ private int bufferSize = 1024;
+ private int sheetIndex = 0;
+ private int sstCacheSizeBytes = -1;
+ private String sheetName;
+ private String password;
- /**
- * Reads a given {@code InputStream} and returns a new
- * instance of {@code Workbook}. Due to Apache POI
- * limitations, a temporary file must be written in order
- * to create a streaming iterator. This process will use
- * the same buffer size as specified in {@link #bufferSize(int)}.
- *
- * @param is input stream to read in
- * @return A {@link Workbook} that can be read from
- * @throws com.monitorjbl.xlsx.exceptions.ReadException if there is an issue reading the stream
- */
- public Workbook open(InputStream is) {
- StreamingWorkbookReader workbook = new StreamingWorkbookReader(this);
- workbook.init(is);
- return new StreamingWorkbook(workbook);
- }
+ public int getRowCacheSize() {
+ return rowCacheSize;
+ }
- /**
- * Reads a given {@code File} and returns a new instance
- * of {@code Workbook}.
- *
- * @param file file to read in
- * @return built streaming reader instance
- * @throws com.monitorjbl.xlsx.exceptions.OpenException if there is an issue opening the file
- * @throws com.monitorjbl.xlsx.exceptions.ReadException if there is an issue reading the file
- */
- public Workbook open(File file) {
- StreamingWorkbookReader workbook = new StreamingWorkbookReader(this);
- workbook.init(file);
- return new StreamingWorkbook(workbook);
- }
+ public int getBufferSize() {
+ return bufferSize;
+ }
- /**
- * Reads a given {@code InputStream} and returns a new
- * instance of {@code StreamingReader}. Due to Apache POI
- * limitations, a temporary file must be written in order
- * to create a streaming iterator. This process will use
- * the same buffer size as specified in {@link #bufferSize(int)}.
- *
- * @param is input stream to read in
- * @return built streaming reader instance
- * @throws com.monitorjbl.xlsx.exceptions.ReadException if there is an issue reading the stream
- * @deprecated This method will be removed in a future release. Use {@link Builder#open(InputStream)} instead
- */
- public StreamingReader read(InputStream is) {
- File f = null;
- try {
- f = writeInputStreamToFile(is, bufferSize);
- log.debug("Created temp file [" + f.getAbsolutePath() + "]");
-
- StreamingReader r = read(f);
- r.tmp = f;
- return r;
- } catch(IOException e) {
- throw new ReadException("Unable to read input stream", e);
- } catch(RuntimeException e) {
- if(f != null) {
- f.delete();
+ /**
+ * @return The sheet index
+ * @deprecated This method will be removed in a future release.
+ */
+ public int getSheetIndex() {
+ return sheetIndex;
}
- throw e;
- }
- }
- /**
- * Reads a given {@code File} and returns a new instance
- * of {@code StreamingReader}.
- *
- * @param f file to read in
- * @return built streaming reader instance
- * @throws com.monitorjbl.xlsx.exceptions.OpenException if there is an issue opening the file
- * @throws com.monitorjbl.xlsx.exceptions.ReadException if there is an issue reading the file
- * @deprecated This method will be removed in a future release. Use {@link Builder#open(File)} instead
- */
- public StreamingReader read(File f) {
- try {
- OPCPackage pkg;
- if(password != null) {
- // Based on: https://poi.apache.org/encryption.html
- POIFSFileSystem poifs = new POIFSFileSystem(f);
- EncryptionInfo info = new EncryptionInfo(poifs);
- Decryptor d = Decryptor.getInstance(info);
- d.verifyPassword(password);
- pkg = OPCPackage.open(d.getDataStream(poifs));
- } else {
- pkg = OPCPackage.open(f);
+ /**
+ * @return The sheet name
+ * @deprecated This method will be removed in a future release.
+ */
+ public String getSheetName() {
+ return sheetName;
+ }
+
+ /**
+ * @return The password to use to unlock this workbook
+ */
+ public String getPassword() {
+ return password;
}
- boolean use1904Dates = false;
- XSSFReader reader = new XSSFReader(pkg);
-
- SharedStringsTable sst;
- File sstCache = null;
- if(sstCacheSizeBytes > 0) {
- sstCache = Files.createTempFile("", "").toFile();
- log.debug("Created sst cache file [" + sstCache.getAbsolutePath() + "]");
- sst = BufferedStringsTable.getSharedStringsTable(sstCache, sstCacheSizeBytes, pkg);
- } else {
- sst = reader.getSharedStringsTable();
+ /**
+ * @return The size of the shared string table cache. If less than 0, no
+ * cache will be used and the entire table will be loaded into memory.
+ */
+ public int getSstCacheSizeBytes() {
+ return sstCacheSizeBytes;
}
- StylesTable styles = reader.getStylesTable();
- NodeList workbookPr = searchForNodeList(document(reader.getWorkbookData()), "/ss:workbook/ss:workbookPr");
- if (workbookPr.getLength() == 1) {
- final Node date1904 = workbookPr.item(0).getAttributes().getNamedItem("date1904");
- if (date1904 != null) {
- use1904Dates = ("1".equals(date1904.getTextContent()));
- }
+ /**
+ * The number of rows to keep in memory at any given point.
+ *
+ * Defaults to 10
+ *
+ *
+ * @param rowCacheSize number of rows
+ * @return reference to current {@code Builder}
+ */
+ public Builder rowCacheSize(int rowCacheSize) {
+ this.rowCacheSize = rowCacheSize;
+ return this;
}
- InputStream sheet = findSheet(reader);
- if(sheet == null) {
- throw new MissingSheetException("Unable to find sheet at index [" + sheetIndex + "]");
+
+ /**
+ * The number of bytes to read into memory from the input resource.
+ *
+ * Defaults to 1024
+ *
+ *
+ * @param bufferSize buffer size in bytes
+ * @return reference to current {@code Builder}
+ */
+ public Builder bufferSize(int bufferSize) {
+ this.bufferSize = bufferSize;
+ return this;
}
- XMLEventReader parser = StaxHelper.newXMLInputFactory().createXMLEventReader(sheet);
-
- return new StreamingReader(new StreamingWorkbookReader(sst, sstCache, pkg, new StreamingSheetReader(sst, styles, parser, use1904Dates, rowCacheSize),
- this));
- } catch(IOException e) {
- throw new OpenException("Failed to open file", e);
- } catch(OpenXML4JException | XMLStreamException e) {
- throw new ReadException("Unable to read workbook", e);
- } catch(GeneralSecurityException e) {
- throw new ReadException("Unable to read workbook - Decryption failed", e);
- }
- }
+ /**
+ * Which sheet to open. There can only be one sheet open for a single
+ * instance of {@code StreamingReader}. If more sheets need to be read,
+ * a new instance must be created.
+ *
+ * Defaults to 0
+ *
+ *
+ * @param sheetIndex index of sheet
+ * @return reference to current {@code Builder}
+ * @deprecated This method will be removed in a future release. Use
+ * {@link StreamingWorkbook#getSheetAt(int)} instead.
+ */
+ public Builder sheetIndex(int sheetIndex) {
+ this.sheetIndex = sheetIndex;
+ return this;
+ }
- /**
- * @deprecated This will be removed when the transition to the 1.x API is complete
- */
- private InputStream findSheet(XSSFReader reader) throws IOException, InvalidFormatException {
- int index = sheetIndex;
- if(sheetName != null) {
- index = -1;
- //This file is separate from the worksheet data, and should be fairly small
- NodeList nl = searchForNodeList(document(reader.getWorkbookData()), "/ss:workbook/ss:sheets/ss:sheet");
- for(int i = 0; i < nl.getLength(); i++) {
- if(Objects.equals(nl.item(i).getAttributes().getNamedItem("name").getTextContent(), sheetName)) {
- index = i;
- }
+ /**
+ * Which sheet to open. There can only be one sheet open for a single
+ * instance of {@code StreamingReader}. If more sheets need to be read,
+ * a new instance must be created.
+ *
+ * @param sheetName name of sheet
+ * @return reference to current {@code Builder}
+ * @deprecated This method will be removed in a future release. Use
+ * {@link StreamingWorkbook#getSheet(String)} instead.
+ */
+ public Builder sheetName(String sheetName) {
+ this.sheetName = sheetName;
+ return this;
+ }
+
+ /**
+ * For password protected files specify password to open file. If the
+ * password is incorrect a {@code ReadException} is thrown on
+ * {@code read}.
+ *
+ * NULL indicates that no password should be used, this is the default
+ * value.
+ *
+ * @param password to use when opening file
+ * @return reference to current {@code Builder}
+ */
+ public Builder password(String password) {
+ this.password = password;
+ return this;
+ }
+
+ /**
+ * !!! This option is experimental !!!
+ *
+ * Set the size of the Shared Strings Table cache. This option exists to
+ * accommodate extremely large workbooks with millions of unique
+ * strings. Normally the SST is entirely loaded into memory, but with
+ * large workbooks with high cardinality (i.e., very few duplicate
+ * values) the SST may not fit entirely into memory.
+ *
+ * By default, the entire SST *will* be loaded into memory. Setting a
+ * value greater than 0 for this option will only cache up to this many
+ * entries in memory. However, enabling this option at
+ * all will have some noticeable performance degredation as you are
+ * trading memory for disk space.
+ *
+ * @param sstCacheSizeBytes size of SST cache
+ * @return reference to current {@code Builder}
+ */
+ public Builder sstCacheSizeBytes(int sstCacheSizeBytes) {
+ this.sstCacheSizeBytes = sstCacheSizeBytes;
+ return this;
}
- if(index < 0) {
- return null;
+
+ /**
+ * Reads a given {@code InputStream} and returns a new instance of
+ * {@code Workbook}. Due to Apache POI limitations, a temporary file
+ * must be written in order to create a streaming iterator. This process
+ * will use the same buffer size as specified in
+ * {@link #bufferSize(int)}.
+ *
+ * @param is input stream to read in
+ * @return A {@link Workbook} that can be read from
+ * @throws com.monitorjbl.xlsx.exceptions.ReadException if there is an
+ * issue reading the stream
+ */
+ public Workbook open(InputStream is) {
+ StreamingWorkbookReader workbook = new StreamingWorkbookReader(this);
+ workbook.init(is);
+ return new StreamingWorkbook(workbook);
}
- }
- Iterator iter = reader.getSheetsData();
- InputStream sheet = null;
-
- int i = 0;
- while(iter.hasNext()) {
- InputStream is = iter.next();
- if(i++ == index) {
- sheet = is;
- log.debug("Found sheet at index [" + sheetIndex + "]");
- break;
+
+ /**
+ * Reads a given {@code File} and returns a new instance of
+ * {@code Workbook}.
+ *
+ * @param file file to read in
+ * @return built streaming reader instance
+ * @throws com.monitorjbl.xlsx.exceptions.OpenException if there is an
+ * issue opening the file
+ * @throws com.monitorjbl.xlsx.exceptions.ReadException if there is an
+ * issue reading the file
+ */
+ public Workbook open(File file) {
+ StreamingWorkbookReader workbook = new StreamingWorkbookReader(this);
+ workbook.init(file);
+ return new StreamingWorkbook(workbook);
+ }
+
+ /**
+ * Reads a given {@code InputStream} and returns a new instance of
+ * {@code StreamingReader}. Due to Apache POI limitations, a temporary
+ * file must be written in order to create a streaming iterator. This
+ * process will use the same buffer size as specified in
+ * {@link #bufferSize(int)}.
+ *
+ * @param is input stream to read in
+ * @return built streaming reader instance
+ * @throws com.monitorjbl.xlsx.exceptions.ReadException if there is an
+ * issue reading the stream
+ * @deprecated This method will be removed in a future release. Use
+ * {@link Builder#open(InputStream)} instead
+ */
+ public StreamingReader read(InputStream is) {
+ File f = null;
+ try {
+ f = writeInputStreamToFile(is, bufferSize);
+ log.debug("Created temp file [" + f.getAbsolutePath() + "]");
+
+ StreamingReader r = read(f);
+ r.tmp = f;
+ return r;
+ } catch (IOException e) {
+ throw new ReadException("Unable to read input stream", e);
+ } catch (RuntimeException e) {
+ if (f != null) {
+ f.delete();
+ }
+ throw e;
+ }
+ }
+
+ /**
+ * Reads a given {@code File} and returns a new instance of
+ * {@code StreamingReader}.
+ *
+ * @param f file to read in
+ * @return built streaming reader instance
+ * @throws com.monitorjbl.xlsx.exceptions.OpenException if there is an
+ * issue opening the file
+ * @throws com.monitorjbl.xlsx.exceptions.ReadException if there is an
+ * issue reading the file
+ * @deprecated This method will be removed in a future release. Use
+ * {@link Builder#open(File)} instead
+ */
+ public StreamingReader read(File f) {
+ try {
+ OPCPackage pkg;
+ if (password != null) {
+ // Based on: https://poi.apache.org/encryption.html
+ POIFSFileSystem poifs = new POIFSFileSystem(f);
+ EncryptionInfo info = new EncryptionInfo(poifs);
+ Decryptor d = Decryptor.getInstance(info);
+ d.verifyPassword(password);
+ pkg = OPCPackage.open(d.getDataStream(poifs));
+ } else {
+ pkg = OPCPackage.open(f);
+ }
+
+ boolean use1904Dates = false;
+ XSSFReader reader = new XSSFReader(pkg);
+
+ SharedStrings sst;
+ File sstCache = null;
+ if (sstCacheSizeBytes > 0) {
+ sstCache = Files.createTempFile("", "").toFile();
+ log.debug("Created sst cache file [" + sstCache.getAbsolutePath() + "]");
+ sst = BufferedStringsTable.getSharedStringsTable(sstCache, sstCacheSizeBytes, pkg);
+ } else {
+ sst = reader.getSharedStringsTable();
+ }
+
+ StylesTable styles = reader.getStylesTable();
+ NodeList workbookPr = searchForNodeList(document(reader.getWorkbookData()), "/ss:workbook/ss:workbookPr");
+ if (workbookPr.getLength() == 1) {
+ final Node date1904 = workbookPr.item(0).getAttributes().getNamedItem("date1904");
+ if (date1904 != null) {
+ use1904Dates = ("1".equals(date1904.getTextContent()));
+ }
+ }
+ InputStream sheet = findSheet(reader);
+ if (sheet == null) {
+ throw new MissingSheetException("Unable to find sheet at index [" + sheetIndex + "]");
+ }
+
+ XMLEventReader parser = StaxHelper.newXMLInputFactory().createXMLEventReader(sheet);
+
+ return new StreamingReader(new StreamingWorkbookReader(sst, sstCache, pkg, new StreamingSheetReader(sst, styles, parser, use1904Dates, rowCacheSize),
+ this));
+ } catch (IOException e) {
+ java.util.logging.Logger.getLogger(Builder.class.getName()).log(Level.SEVERE, "AQUIII", e);
+ throw new OpenException("Failed to open file", e);
+ } catch (OpenXML4JException | XMLStreamException e) {
+ throw new ReadException("Unable to read workbook", e);
+ } catch (GeneralSecurityException e) {
+ throw new ReadException("Unable to read workbook - Decryption failed", e);
+ }
+ }
+
+ /**
+ * @deprecated This will be removed when the transition to the 1.x API
+ * is complete
+ */
+ private InputStream findSheet(XSSFReader reader) throws IOException, InvalidFormatException {
+ int index = sheetIndex;
+ if (sheetName != null) {
+ index = -1;
+ //This file is separate from the worksheet data, and should be fairly small
+ NodeList nl = searchForNodeList(document(reader.getWorkbookData()), "/ss:workbook/ss:sheets/ss:sheet");
+ for (int i = 0; i < nl.getLength(); i++) {
+ if (Objects.equals(nl.item(i).getAttributes().getNamedItem("name").getTextContent(), sheetName)) {
+ index = i;
+ }
+ }
+ if (index < 0) {
+ return null;
+ }
+ }
+ Iterator iter = reader.getSheetsData();
+ InputStream sheet = null;
+
+ int i = 0;
+ while (iter.hasNext()) {
+ InputStream is = iter.next();
+ if (i++ == index) {
+ sheet = is;
+ log.debug("Found sheet at index [" + sheetIndex + "]");
+ break;
+ }
+ }
+ return sheet;
}
- }
- return sheet;
}
- }
}
diff --git a/src/main/java/com/monitorjbl/xlsx/impl/StreamingSheet.java b/src/main/java/com/monitorjbl/xlsx/impl/StreamingSheet.java
index e89073e0..9be727a0 100644
--- a/src/main/java/com/monitorjbl/xlsx/impl/StreamingSheet.java
+++ b/src/main/java/com/monitorjbl/xlsx/impl/StreamingSheet.java
@@ -24,6 +24,8 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import org.apache.poi.ss.usermodel.PageMargin;
+import org.apache.poi.ss.usermodel.PaneType;
public class StreamingSheet implements Sheet {
@@ -1000,4 +1002,19 @@ public CellAddress getActiveCell() {
public void setActiveCell(CellAddress cellAddress) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public double getMargin(PageMargin pm) {
+ throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
+ }
+
+ @Override
+ public void setMargin(PageMargin pm, double d) {
+ throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
+ }
+
+ @Override
+ public void createSplitPane(int i, int i1, int i2, int i3, PaneType pt) {
+ throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
+ }
}
diff --git a/src/main/java/com/monitorjbl/xlsx/impl/StreamingSheetReader.java b/src/main/java/com/monitorjbl/xlsx/impl/StreamingSheetReader.java
index ee5aaf0b..d82aa2b4 100644
--- a/src/main/java/com/monitorjbl/xlsx/impl/StreamingSheetReader.java
+++ b/src/main/java/com/monitorjbl/xlsx/impl/StreamingSheetReader.java
@@ -7,7 +7,6 @@
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellReference;
-import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
@@ -28,11 +27,12 @@
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import org.apache.poi.xssf.model.SharedStrings;
public class StreamingSheetReader implements Iterable {
private static final Logger log = LoggerFactory.getLogger(StreamingSheetReader.class);
- private final SharedStringsTable sst;
+ private final SharedStrings sst;
private final StylesTable stylesTable;
private final XMLEventReader parser;
private final DataFormatter dataFormatter = new DataFormatter();
@@ -52,7 +52,7 @@ public class StreamingSheetReader implements Iterable {
private StreamingCell currentCell;
private boolean use1904Dates;
- public StreamingSheetReader(SharedStringsTable sst, StylesTable stylesTable, XMLEventReader parser,
+ public StreamingSheetReader(SharedStrings sst, StylesTable stylesTable, XMLEventReader parser,
final boolean use1904Dates, int rowCacheSize) {
this.sst = sst;
this.stylesTable = stylesTable;
diff --git a/src/main/java/com/monitorjbl/xlsx/impl/StreamingWorkbook.java b/src/main/java/com/monitorjbl/xlsx/impl/StreamingWorkbook.java
index 47d1346a..2e4b7c16 100644
--- a/src/main/java/com/monitorjbl/xlsx/impl/StreamingWorkbook.java
+++ b/src/main/java/com/monitorjbl/xlsx/impl/StreamingWorkbook.java
@@ -19,6 +19,7 @@
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
+import org.apache.poi.ss.usermodel.CellReferenceType;
public class StreamingWorkbook implements Workbook, AutoCloseable {
private final StreamingWorkbookReader reader;
@@ -509,4 +510,14 @@ public int addOlePackage(byte[] bytes, String s, String s1, String s2) throws IO
public EvaluationWorkbook createEvaluationWorkbook() {
return null;
}
+
+ @Override
+ public CellReferenceType getCellReferenceType() {
+ throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
+ }
+
+ @Override
+ public void setCellReferenceType(CellReferenceType crt) {
+ throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
+ }
}
diff --git a/src/main/java/com/monitorjbl/xlsx/impl/StreamingWorkbookReader.java b/src/main/java/com/monitorjbl/xlsx/impl/StreamingWorkbookReader.java
index 282f4bc9..fcf1efaa 100644
--- a/src/main/java/com/monitorjbl/xlsx/impl/StreamingWorkbookReader.java
+++ b/src/main/java/com/monitorjbl/xlsx/impl/StreamingWorkbookReader.java
@@ -14,7 +14,6 @@
import org.apache.poi.util.StaxHelper;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFReader.SheetIterator;
-import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,199 +39,203 @@
import static com.monitorjbl.xlsx.XmlUtils.searchForNodeList;
import static com.monitorjbl.xlsx.impl.TempFileUtil.writeInputStreamToFile;
import static java.util.Arrays.asList;
+import org.apache.poi.xssf.model.SharedStrings;
public class StreamingWorkbookReader implements Iterable, AutoCloseable {
- private static final Logger log = LoggerFactory.getLogger(StreamingWorkbookReader.class);
-
- private final List sheets;
- private final List